From 88e077e6dfa303ba38ee5aeff905747649f49383 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 10:39:27 +0100 Subject: [PATCH 01/95] Adding code --- src/vs/editor/contrib/hover/browser/contentHover.ts | 7 +++++++ src/vs/editor/contrib/hover/browser/hover.ts | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 8d1e69b3abb31..045f83f25b2dc 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -24,6 +24,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/suggest'; import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; +import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; const $ = dom.$; @@ -428,6 +429,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hover: HoverWidget = this._register(new HoverWidget()); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + // Adding a resizable element directly to the content hover widget + private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); + private _visibleData: ContentHoverVisibleData | null = null; /** @@ -472,6 +476,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._focusTracker.onDidBlur(() => { this._hoverFocusedKey.set(false); })); + + // Resizable Elemenent contains as a child the hover container dom node + this._element.domNode.appendChild(this._hover.containerDomNode); } public override dispose(): void { diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 9d4b0ae0ef70a..290d1f9b7261c 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -205,7 +205,7 @@ export class ModesHoverController implements IEditorContribution { const resolvedKeyboardEvent = this._keybindingService.softDispatch(e, this._editor.getDomNode()); // If the beginning of a multi-chord keybinding is pressed, or the command aims to focus the hover, set the variable to true, otherwise false - const mightTriggerFocus = (resolvedKeyboardEvent?.enterMultiChord || (resolvedKeyboardEvent?.commandId === 'editor.action.showOrFocusHover' && this._contentWidget?.isVisible())); + const mightTriggerFocus = (resolvedKeyboardEvent?.enterMultiChord || (resolvedKeyboardEvent?.commandId === 'editor.action.showHover' && this._contentWidget?.isVisible())); if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift && !mightTriggerFocus) { From 46446a0d4b90323e0620dfe071a10443c8535a80 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 10:45:19 +0100 Subject: [PATCH 02/95] Working code, work from here --- src/vs/editor/contrib/hover/browser/contentHover.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 045f83f25b2dc..c505558624572 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -427,11 +427,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); - private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); + // Placing the getDomNode() call after instantiating the element + private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + private _visibleData: ContentHoverVisibleData | null = null; /** @@ -478,6 +481,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { })); // Resizable Elemenent contains as a child the hover container dom node + // TODO: Adding the line below makes the content hover disappear this._element.domNode.appendChild(this._hover.containerDomNode); } @@ -494,7 +498,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getDomNode(): HTMLElement { - return this._hover.containerDomNode; + // return this._hover.containerDomNode; + return this._element.domNode; } public getPosition(): IContentWidgetPosition | null { From 492ecb61e3d02680c25792b1d2bf9dad8c7bd3cd Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 10:53:44 +0100 Subject: [PATCH 03/95] Made the sashes appear, need to write the code so that the sashes can be correctly resized --- .../editor/contrib/hover/browser/contentHover.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index c505558624572..889068e0a8528 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -431,6 +431,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); + private readonly _disposables = new DisposableStore(); // Placing the getDomNode() call after instantiating the element private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); @@ -483,6 +484,21 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Resizable Elemenent contains as a child the hover container dom node // TODO: Adding the line below makes the content hover disappear this._element.domNode.appendChild(this._hover.containerDomNode); + + this._disposables.add(this._element.onDidWillResize(() => { + console.log('Inside of onDidWillResize of ContentHoverWidget'); + // TODO + })); + this._disposables.add(this._element.onDidResize(e => { + console.log('Inside of onDidResize of ContentHoverWidget'); + // TODO + })); + + // TODO: place in other function once figured out the code + this._element.enableSashes(true, true, false, false); + const height = 200; + const width = 200; + this._element.layout(height, width); } public override dispose(): void { From d01bccbf3542a19e2b3b4a780863817a53cb2b8e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 11:46:21 +0100 Subject: [PATCH 04/95] Added the possibility to persist the height of the hover content widget --- src/vs/base/browser/ui/hover/hoverWidget.ts | 3 + .../contrib/hover/browser/contentHover.ts | 197 +++++++++++++++++- .../contrib/suggest/browser/suggestWidget.ts | 20 +- 3 files changed, 204 insertions(+), 16 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index 96e99cbec4a2f..afa44bf0aec3f 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -18,6 +18,9 @@ export const enum HoverPosition { export class HoverWidget extends Disposable { + public maxHeight = 0; + public maxWidth = 0; + public readonly containerDomNode: HTMLElement; public readonly contentsDomNode: HTMLElement; public readonly scrollbar: DomScrollableElement; diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 889068e0a8528..9cb89854f5f42 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -25,6 +25,9 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/sug import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; +import { clamp } from 'vs/base/common/numbers'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { PersistedWidgetSize, ResizeState } from 'vs/editor/contrib/suggest/browser/suggestWidget'; const $ = dom.$; @@ -431,6 +434,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); + private _cappedHeight?: { wanted: number; capped: number }; + private readonly _persistedSize: PersistedWidgetSize; private readonly _disposables = new DisposableStore(); // Placing the getDomNode() call after instantiating the element @@ -460,6 +465,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IStorageService private readonly _storageService: IStorageService ) { super(); @@ -481,26 +487,193 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); + this._persistedSize = new PersistedWidgetSize(_storageService, _editor); + let state: ResizeState | undefined; + // Resizable Elemenent contains as a child the hover container dom node // TODO: Adding the line below makes the content hover disappear this._element.domNode.appendChild(this._hover.containerDomNode); this._disposables.add(this._element.onDidWillResize(() => { - console.log('Inside of onDidWillResize of ContentHoverWidget'); - // TODO + console.log('* Inside of onDidWillResize of ContentHoverWidget'); + const persistedSize = this._persistedSize.restore(); + state = new ResizeState(persistedSize, this._element.size); })); this._disposables.add(this._element.onDidResize(e => { - console.log('Inside of onDidResize of ContentHoverWidget'); - // TODO + console.log('* Inside of onDidResize of ContentHoverWidget'); + console.log('e : ', e); + + this._resize(e.dimension.width, e.dimension.height); + if (state) { + state.persistHeight = state.persistHeight || !!e.north || !!e.south; + state.persistWidth = state.persistWidth || !!e.east || !!e.west; + } + + if (!e.done) { + return; + } + + if (state) { + const { itemHeight, defaultSize } = this._getLayoutInfo(); + const threshold = Math.round(itemHeight / 2); + let { width, height } = this._element.size; + + if (!state.persistHeight || Math.abs(state.currentSize.height - height) <= threshold) { + height = state.persistedSize?.height ?? defaultSize.height; + } + if (!state.persistWidth || Math.abs(state.currentSize.width - width) <= threshold) { + width = state.persistedSize?.width ?? defaultSize.width; + } + // Store the new persisted sizes + this._persistedSize.store(new dom.Dimension(width, height)); + } + state = undefined; })); // TODO: place in other function once figured out the code + // this._element.enableSashes(true, true, false, false); + // const height = 200; + // const width = 200; + // Actually makes the sashes appear on that given size + // this._element.layout(height, width); + } + + private _resizableLayout(size: dom.Dimension | undefined): void { + + /* + console.log('* Entered into _resizableLayout of ContentHoverWidget'); + + if (!this._editor.hasModel()) { + return; + } + if (!this._editor.getDomNode()) { + return; + } + + const bodyBox = dom.getClientArea(document.body); + // Should return the default size of the suggest widget too + const info = this._getLayoutInfo(); + + if (!size) { + size = info.defaultSize; + } + + let height = size.height; + let width = size.width; + + // When there is no suggest content, or the content is still loading, specify some height and width parameters + // if (this._state === State.Empty || this._state === State.Loading) { + // console.log('Inside of the first if loop'); + // showing a message only + // height = info.itemHeight + info.borderHeight; + // width = info.defaultSize.width / 2; + // The sahes are nowhere enabled + // this.element.enableSashes(false, false, false, false); + // this.element.minSize = this.element.maxSize = new dom.Dimension(width, height); + // Setting the preference of where the content widget should be located + // this._contentWidget.setPreference(ContentWidgetPositionPreference.BELOW); + // } else { + // In this case the suggest items are presumably showing + // Presumably the suggest widget width should never be bigger than some padded version fo the body box + + const maxWidth = bodyBox.width - info.borderHeight - 2 * info.horizontalPadding; + if (width > maxWidth) { + width = maxWidth; + } + const preferredWidth = width; + + // The actual heigh is the sum of the status bar height, the content height (where the items are shown), and the border height + const fullHeight = this._hover.maxHeight + info.borderHeight; + // Min height requires only one suggest, hence why we have item height below, there is no border heigh however + const minHeight = info.itemHeight; + // The box of the editor + const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); + // The possible places where the cursor can be + const cursorBox = this._editor.getScrolledVisiblePosition(this._editor.getPosition()); + const cursorBottom = editorBox.top + cursorBox.top + cursorBox.height; + const maxHeightBelow = Math.min(bodyBox.height - cursorBottom - info.verticalPadding, fullHeight); + const availableSpaceAbove = editorBox.top + cursorBox.top - info.verticalPadding; + const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); + let maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow) + info.borderHeight, fullHeight); + + if (height === this._cappedHeight?.capped) { + // Restore the old (wanted) height when the current + // height is capped to fit + height = this._cappedHeight.wanted; + } + + if (height < minHeight) { + height = minHeight; + } + if (height > maxHeight) { + height = maxHeight; + } + + // Suppose that the height of the suggest widget is bigger than some maximum height, or the rendering should be above, and there is enough space above the cursor + if (height > maxHeightBelow) { + // Set the suggest content widget so that it renders above + // this._contentWidget.setPreference(ContentWidgetPositionPreference.ABOVE); + // Enable the sashes on the north and the east + this._element.enableSashes(true, true, false, false); + // The max height that can be attained is determined by the max height above the line + maxHeight = maxHeightAbove; + } else { + // Otherwise the suggest content widget is rendered below the line + // this._contentWidget.setPreference(ContentWidgetPositionPreference.BELOW); + // The sashes are enabled on the south and the east + this._element.enableSashes(false, true, true, false); + // The max height that can be attained is determined by the max height below the line + maxHeight = maxHeightBelow; + } + this._element.preferredSize = new dom.Dimension(preferredWidth, info.defaultSize.height); + this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); + // Hard-coding the minimum width of the resizeable element + this._element.minSize = new dom.Dimension(220, minHeight); + + // Know when the height was capped to fit and remember + // the wanted height for later. This is required when going + // left to widen suggestions. + this._cappedHeight = height === fullHeight + ? { wanted: this._cappedHeight?.wanted ?? size.height, capped: height } + : undefined; + + // The _layout function also does the resizing + this._resize(width, height); + */ + + console.log('* Entered into _resizableLayout of ContentHoverWidget'); this._element.enableSashes(true, true, false, false); - const height = 200; - const width = 200; + const height = size ? size.height : 200; + const width = size ? size.width : 200; + this._resize(width, height); + + } + + private _resize(width: number, height: number): void { + console.log(' * Entered into the _resize function of ContentHoverWidget'); + const { width: maxWidth, height: maxHeight } = this._element.maxSize; + width = Math.min(maxWidth, width); + height = Math.min(maxHeight, height); this._element.layout(height, width); } + private _getLayoutInfo() { + const fontInfo = this._editor.getOption(EditorOption.fontInfo); + const itemHeight = clamp(fontInfo.lineHeight, 8, 1000); + const borderWidth = 1; // this._details.widget.borderWidth; + const borderHeight = 2 * borderWidth; + + return { + itemHeight, + borderWidth, + borderHeight, + typicalHalfwidthCharacterWidth: fontInfo.typicalHalfwidthCharacterWidth, + verticalPadding: 22, + horizontalPadding: 14, + defaultSize: new dom.Dimension(430, 12 * itemHeight + borderHeight) + }; + } + public override dispose(): void { this._editor.removeContentWidget(this); if (this._visibleData) { @@ -583,6 +756,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; this._hover.contentsDomNode.style.maxHeight = `${height}px`; this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; + + this._hover.maxHeight = height; + this._hover.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); } private _updateFont(): void { @@ -591,6 +767,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { + console.log(' * Entered into showAt of ContentHoverWidget'); this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -612,6 +789,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.focus(); } visibleData.colorPicker?.layout(); + + // TODO: added but may cause errors + + // Either restore the persisted size or take the current element size + console.log('this._persistedSize.restore() : ', this._persistedSize.restore()); + console.log('this._element.size : ', this._element.size); + const size = this._persistedSize.restore() ?? this._element.size; + this._resizableLayout(size); } public hide(): void { diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index d2e86783c8a0f..ab06705d407d1 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -63,7 +63,7 @@ export interface ISelectedSuggestion { model: CompletionModel; } -class PersistedWidgetSize { +export class PersistedWidgetSize { private readonly _key: string; @@ -96,6 +96,15 @@ class PersistedWidgetSize { } } +export class ResizeState { + constructor( + readonly persistedSize: dom.Dimension | undefined, + readonly currentSize: dom.Dimension, + public persistHeight = false, + public persistWidth = false, + ) { } +} + export class SuggestWidget implements IDisposable { private static LOADING_MESSAGE: string = nls.localize('suggestWidget.loading', "Loading..."); @@ -158,15 +167,6 @@ export class SuggestWidget implements IDisposable { this._contentWidget = new SuggestContentWidget(this, editor); this._persistedSize = new PersistedWidgetSize(_storageService, editor); - class ResizeState { - constructor( - readonly persistedSize: dom.Dimension | undefined, - readonly currentSize: dom.Dimension, - public persistHeight = false, - public persistWidth = false, - ) { } - } - let state: ResizeState | undefined; this._disposables.add(this.element.onDidWillResize(() => { this._contentWidget.lockPreference(); From c9933154a1bdc718b2b6d2d52adf99ed355686e7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 13:46:13 +0100 Subject: [PATCH 05/95] Removing the persisting of the size because the hovers are of different size --- src/vs/base/browser/ui/resizable/resizable.ts | 3 + .../contrib/hover/browser/contentHover.ts | 62 +++++-------------- 2 files changed, 17 insertions(+), 48 deletions(-) diff --git a/src/vs/base/browser/ui/resizable/resizable.ts b/src/vs/base/browser/ui/resizable/resizable.ts index 95dfb06b8d007..4e14a2698fd39 100644 --- a/src/vs/base/browser/ui/resizable/resizable.ts +++ b/src/vs/base/browser/ui/resizable/resizable.ts @@ -142,7 +142,10 @@ export class ResizableHTMLElement { width = Math.max(minWidth, Math.min(maxWidth, width)); const newSize = new Dimension(width, height); + + // We layout of the resize element is changed only when it is different to the size before if (!Dimension.equals(newSize, this._size)) { + console.log('Inside of the if statement of the layout function of ResizableHTMLElement'); this.domNode.style.height = height + 'px'; this.domNode.style.width = width + 'px'; this._size = newSize; diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 9cb89854f5f42..22e8ff271d4ff 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -435,7 +435,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); private _cappedHeight?: { wanted: number; capped: number }; - private readonly _persistedSize: PersistedWidgetSize; private readonly _disposables = new DisposableStore(); // Placing the getDomNode() call after instantiating the element @@ -487,55 +486,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); - this._persistedSize = new PersistedWidgetSize(_storageService, _editor); - let state: ResizeState | undefined; - - // Resizable Elemenent contains as a child the hover container dom node - // TODO: Adding the line below makes the content hover disappear this._element.domNode.appendChild(this._hover.containerDomNode); - this._disposables.add(this._element.onDidWillResize(() => { console.log('* Inside of onDidWillResize of ContentHoverWidget'); - const persistedSize = this._persistedSize.restore(); - state = new ResizeState(persistedSize, this._element.size); })); this._disposables.add(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); - this._resize(e.dimension.width, e.dimension.height); - if (state) { - state.persistHeight = state.persistHeight || !!e.north || !!e.south; - state.persistWidth = state.persistWidth || !!e.east || !!e.west; - } - - if (!e.done) { - return; - } - - if (state) { - const { itemHeight, defaultSize } = this._getLayoutInfo(); - const threshold = Math.round(itemHeight / 2); - let { width, height } = this._element.size; - - if (!state.persistHeight || Math.abs(state.currentSize.height - height) <= threshold) { - height = state.persistedSize?.height ?? defaultSize.height; - } - if (!state.persistWidth || Math.abs(state.currentSize.width - width) <= threshold) { - width = state.persistedSize?.width ?? defaultSize.width; - } - // Store the new persisted sizes - this._persistedSize.store(new dom.Dimension(width, height)); - } - state = undefined; })); - - // TODO: place in other function once figured out the code - // this._element.enableSashes(true, true, false, false); - // const height = 200; - // const width = 200; - // Actually makes the sashes appear on that given size - // this._element.layout(height, width); } private _resizableLayout(size: dom.Dimension | undefined): void { @@ -642,9 +601,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { */ console.log('* Entered into _resizableLayout of ContentHoverWidget'); + // TODO: The content hover is not placed correctly, it is placed in the center but should be at the same position as before + // TODO: Enable sashes on different places depending on if hover shown on the top or on the bottom + // TODO: When the hover is extended too much, so that part of it disappears, it disappears completely + // TODO: Eastern sash disappears when the hover is too small? or after extending too much? this._element.enableSashes(true, true, false, false); const height = size ? size.height : 200; const width = size ? size.width : 200; + // let height = 200; + // let width = 200; this._resize(width, height); } @@ -655,6 +620,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { width = Math.min(maxWidth, width); height = Math.min(maxHeight, height); this._element.layout(height, width); + console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); + console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); } private _getLayoutInfo() { @@ -692,6 +659,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getPosition(): IContentWidgetPosition | null { + console.log('Inside of getPosition of the ContentHoverWidget'); if (!this._visibleData) { return null; } @@ -768,6 +736,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { console.log(' * Entered into showAt of ContentHoverWidget'); + console.log('visibleData : ', visibleData); + this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -790,13 +760,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } visibleData.colorPicker?.layout(); - // TODO: added but may cause errors - - // Either restore the persisted size or take the current element size - console.log('this._persistedSize.restore() : ', this._persistedSize.restore()); - console.log('this._element.size : ', this._element.size); - const size = this._persistedSize.restore() ?? this._element.size; - this._resizableLayout(size); + // Resizable + const newSize = new dom.Dimension(this._hover.maxWidth, this._hover.maxHeight); + this._resizableLayout(newSize); } public hide(): void { From d34afc3dedd5a9161a4db7c5892b65adf3071943 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 16:10:12 +0100 Subject: [PATCH 06/95] container dom node size now depends on the resizable element size too, needs polishing --- .../contrib/hover/browser/contentHover.ts | 198 ++++++++---------- 1 file changed, 91 insertions(+), 107 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 22e8ff271d4ff..946a7e4c7312b 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -11,7 +11,7 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IContentWidgetPosition, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions'; -import { Position } from 'vs/editor/common/core/position'; +import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IModelDecoration, PositionAffinity } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; @@ -25,9 +25,6 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/sug import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; -import { clamp } from 'vs/base/common/numbers'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { PersistedWidgetSize, ResizeState } from 'vs/editor/contrib/suggest/browser/suggestWidget'; const $ = dom.$; @@ -431,15 +428,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); - // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); - private _cappedHeight?: { wanted: number; capped: number }; - private readonly _disposables = new DisposableStore(); - - // Placing the getDomNode() call after instantiating the element + private _mousePosition: IPosition | null = null; private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - private _visibleData: ContentHoverVisibleData | null = null; /** @@ -464,7 +456,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService, - @IStorageService private readonly _storageService: IStorageService ) { super(); @@ -486,21 +477,30 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); + // Savin tha approximate position of the mouse + this._register(this._editor.onMouseMove(e => { + this._mousePosition = e.target.position; + })); this._element.domNode.appendChild(this._hover.containerDomNode); - this._disposables.add(this._element.onDidWillResize(() => { + this._register(this._element.onDidWillResize(() => { console.log('* Inside of onDidWillResize of ContentHoverWidget'); })); - this._disposables.add(this._element.onDidResize(e => { + this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); this._resize(e.dimension.width, e.dimension.height); })); } - private _resizableLayout(size: dom.Dimension | undefined): void { + private _setLayoutOfResizableElement(size: dom.Dimension): void { + + // Setting the initial layout of the resizable element, before calling the resize function - /* console.log('* Entered into _resizableLayout of ContentHoverWidget'); + console.log('this._mousePosition : ', this._mousePosition); + console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); + console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); + // Mistake in the height calculations it appears if (!this._editor.hasModel()) { return; @@ -508,137 +508,119 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (!this._editor.getDomNode()) { return; } + if (!this._mousePosition) { + return; + } + // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); - // Should return the default size of the suggest widget too - const info = this._getLayoutInfo(); - if (!size) { - size = info.defaultSize; - } + // Should return the default size of the suggest widget too + // Hard-coded in the hover.css file as 1.5em or 24px + const minHeight = 24; + console.log('size : ', size); let height = size.height; let width = size.width; - // When there is no suggest content, or the content is still loading, specify some height and width parameters - // if (this._state === State.Empty || this._state === State.Loading) { - // console.log('Inside of the first if loop'); - // showing a message only - // height = info.itemHeight + info.borderHeight; - // width = info.defaultSize.width / 2; - // The sahes are nowhere enabled - // this.element.enableSashes(false, false, false, false); - // this.element.minSize = this.element.maxSize = new dom.Dimension(width, height); - // Setting the preference of where the content widget should be located - // this._contentWidget.setPreference(ContentWidgetPositionPreference.BELOW); - // } else { - // In this case the suggest items are presumably showing - // Presumably the suggest widget width should never be bigger than some padded version fo the body box - - const maxWidth = bodyBox.width - info.borderHeight - 2 * info.horizontalPadding; + // Hard-code the values for now! + // TODO: Where to find the border and padding values? + const maxWidth = bodyBox.width; if (width > maxWidth) { + console.log('width capped at the maxWidth'); width = maxWidth; } - const preferredWidth = width; - // The actual heigh is the sum of the status bar height, the content height (where the items are shown), and the border height - const fullHeight = this._hover.maxHeight + info.borderHeight; - // Min height requires only one suggest, hence why we have item height below, there is no border heigh however - const minHeight = info.itemHeight; - // The box of the editor + // The full height is already passed in as a parameter + const fullHeight = size.height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - // The possible places where the cursor can be - const cursorBox = this._editor.getScrolledVisiblePosition(this._editor.getPosition()); - const cursorBottom = editorBox.top + cursorBox.top + cursorBox.height; - const maxHeightBelow = Math.min(bodyBox.height - cursorBottom - info.verticalPadding, fullHeight); - const availableSpaceAbove = editorBox.top + cursorBox.top - info.verticalPadding; + // We want not the cursor box but the mouse box + const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); + console.log('mouseBox : ', mouseBox); + const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; + const maxHeightBelow = Math.min(bodyBox.height - mouseBottom, fullHeight); + console.log('maxHeightBelow : ', maxHeightBelow); + const availableSpaceAbove = editorBox.top + mouseBox.top; const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); - let maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow) + info.borderHeight, fullHeight); - - if (height === this._cappedHeight?.capped) { - // Restore the old (wanted) height when the current - // height is capped to fit - height = this._cappedHeight.wanted; - } + console.log('maxHeightAbove : ', maxHeightAbove); + let maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); if (height < minHeight) { + console.log('height capped at the min height'); height = minHeight; } if (height > maxHeight) { + console.log('height capped at the maximum height'); height = maxHeight; } + const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; + console.log('preferRenderingAbove : ', preferRenderingAbove); + // Suppose that the height of the suggest widget is bigger than some maximum height, or the rendering should be above, and there is enough space above the cursor - if (height > maxHeightBelow) { - // Set the suggest content widget so that it renders above - // this._contentWidget.setPreference(ContentWidgetPositionPreference.ABOVE); - // Enable the sashes on the north and the east - this._element.enableSashes(true, true, false, false); - // The max height that can be attained is determined by the max height above the line - maxHeight = maxHeightAbove; + console.log('Before enabling sashes'); + if (preferRenderingAbove) { + console.log('first if condition'); + + const westSash = false; + const eastSash = true; + const northSash = height < maxHeightAbove; + const southSash = height >= maxHeightAbove; + + maxHeight = height < maxHeightAbove ? maxHeightAbove : maxHeightBelow; + this._element.enableSashes(northSash, eastSash, southSash, westSash); + } else { - // Otherwise the suggest content widget is rendered below the line - // this._contentWidget.setPreference(ContentWidgetPositionPreference.BELOW); - // The sashes are enabled on the south and the east - this._element.enableSashes(false, true, true, false); - // The max height that can be attained is determined by the max height below the line - maxHeight = maxHeightBelow; - } - this._element.preferredSize = new dom.Dimension(preferredWidth, info.defaultSize.height); - this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); - // Hard-coding the minimum width of the resizeable element - this._element.minSize = new dom.Dimension(220, minHeight); - - // Know when the height was capped to fit and remember - // the wanted height for later. This is required when going - // left to widen suggestions. - this._cappedHeight = height === fullHeight - ? { wanted: this._cappedHeight?.wanted ?? size.height, capped: height } - : undefined; - - // The _layout function also does the resizing + console.log('Second if condition'); + const westSash = false; + const eastSash = true; + const northSash = height >= maxHeightBelow; + const southSash = height < maxHeightBelow; + + maxHeight = height < maxHeightBelow ? maxHeightBelow : maxHeightAbove; + this._element.enableSashes(northSash, eastSash, southSash, westSash); + } + + // TODO: Place the folloding line in order to use the calculated max width and max height + // TODO: this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); + // TODO: When the following is used, there are less issues with the correct positioning + this._element.maxSize = new dom.Dimension(1000, 1000); + // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 + // TODO: this._element.minSize = new dom.Dimension(10, minHeight); + this._resize(width, height); - */ - console.log('* Entered into _resizableLayout of ContentHoverWidget'); - // TODO: The content hover is not placed correctly, it is placed in the center but should be at the same position as before // TODO: Enable sashes on different places depending on if hover shown on the top or on the bottom // TODO: When the hover is extended too much, so that part of it disappears, it disappears completely // TODO: Eastern sash disappears when the hover is too small? or after extending too much? - this._element.enableSashes(true, true, false, false); - const height = size ? size.height : 200; - const width = size ? size.width : 200; - // let height = 200; - // let width = 200; - this._resize(width, height); + + // The below works!! + // this._element.enableSashes(true, true, false, false); + // const height = size ? size.height : 200; + // const width = size ? size.width : 200; + // this._resize(width, height); } private _resize(width: number, height: number): void { console.log(' * Entered into the _resize function of ContentHoverWidget'); + // Performs the actual resizing const { width: maxWidth, height: maxHeight } = this._element.maxSize; + console.log('maxWidth : ', maxWidth, ' width : ', width); width = Math.min(maxWidth, width); + console.log('maxHeight : ', maxHeight, ' height : ', height); height = Math.min(maxHeight, height); this._element.layout(height, width); console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); - } - private _getLayoutInfo() { - const fontInfo = this._editor.getOption(EditorOption.fontInfo); - const itemHeight = clamp(fontInfo.lineHeight, 8, 1000); - const borderWidth = 1; // this._details.widget.borderWidth; - const borderHeight = 2 * borderWidth; + // Make the inner container also have that size? + // If you do the following, the sashes disappear, we do not want that + // Sashes are 4 px wide, do not hardcode later - return { - itemHeight, - borderWidth, - borderHeight, - typicalHalfwidthCharacterWidth: fontInfo.typicalHalfwidthCharacterWidth, - verticalPadding: 22, - horizontalPadding: 14, - defaultSize: new dom.Dimension(430, 12 * itemHeight + borderHeight) - }; + // Forcing the container do node to have another size, but what we should do is make the resizable element have same dimension as container dom node + this._hover.containerDomNode.style.height = `${height - 4}px`; + this._hover.containerDomNode.style.width = `${width - 4}px`; } public override dispose(): void { @@ -761,8 +743,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { visibleData.colorPicker?.layout(); // Resizable - const newSize = new dom.Dimension(this._hover.maxWidth, this._hover.maxHeight); - this._resizableLayout(newSize); + // Only called once, when the widget is first shown + const newSize = new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); + console.log('newSize : ', newSize); + this._setLayoutOfResizableElement(newSize); } public hide(): void { From 182f444675d232d65833777237b26b42efe78291 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 19:53:37 +0100 Subject: [PATCH 07/95] Added code in order to stop the hover from jumping on vertical resize --- .../contrib/hover/browser/contentHover.ts | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 946a7e4c7312b..ccec8ee020841 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -432,6 +432,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); private _mousePosition: IPosition | null = null; private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + private _initialTop: number = -1; + private _initialHeight: number = -1; private _visibleData: ContentHoverVisibleData | null = null; /** @@ -494,6 +496,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _setLayoutOfResizableElement(size: dom.Dimension): void { + // TODO: 1) Make resizing correct generally between the resizable element and the container dom node + // TODO: 2) Do correct calculations of maximum height above and below in order to decide which sashes to enable + // Setting the initial layout of the resizable element, before calling the resize function console.log('* Entered into _resizableLayout of ContentHoverWidget'); @@ -538,13 +543,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); console.log('mouseBox : ', mouseBox); const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; - const maxHeightBelow = Math.min(bodyBox.height - mouseBottom, fullHeight); + let maxHeightBelow = Math.min(bodyBox.height - mouseBottom, fullHeight); console.log('maxHeightBelow : ', maxHeightBelow); const availableSpaceAbove = editorBox.top + mouseBox.top; - const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); + let maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); console.log('maxHeightAbove : ', maxHeightAbove); let maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); + // TODO: CHANGE ONCE FIGURED OUT THE CORRECT MATH FOR MAXWIDTH AND MAXHEIGHT + maxHeightAbove = 1000; + maxHeightBelow = 1000; + // Change the above in order to correctly show the widget + if (height < minHeight) { console.log('height capped at the min height'); height = minHeight; @@ -582,11 +592,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // TODO: Place the folloding line in order to use the calculated max width and max height - // TODO: this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); - // TODO: When the following is used, there are less issues with the correct positioning - this._element.maxSize = new dom.Dimension(1000, 1000); + this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 - // TODO: this._element.minSize = new dom.Dimension(10, minHeight); + this._element.minSize = new dom.Dimension(10, minHeight); this._resize(width, height); @@ -603,6 +611,16 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } private _resize(width: number, height: number): void { + + console.log('this._initialHeight : ', this._initialHeight); + console.log('this._initialTop : ', this._initialTop); + + if (this._initialHeight !== -1) { + const diff = height - this._initialHeight; + // When difference positive, means that the widget grew, place it higher up + this._element.domNode.style.top = this._initialTop - diff + 'px'; + } + console.log(' * Entered into the _resize function of ContentHoverWidget'); // Performs the actual resizing const { width: maxWidth, height: maxHeight } = this._element.maxSize; @@ -621,6 +639,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Forcing the container do node to have another size, but what we should do is make the resizable element have same dimension as container dom node this._hover.containerDomNode.style.height = `${height - 4}px`; this._hover.containerDomNode.style.width = `${width - 4}px`; + + if (this._initialTop === -1 || this._initialTop === 0) { + console.log('Entered into update of initial top'); + console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); + console.log('this._element.domNode.style : ', this._element.domNode.style); + console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); + console.log('this._element.domNode.style[0] : ', this._element.domNode.style[0]); + console.log('this._element.domNode.clientHeight : ', this._element.domNode.clientHeight); + console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); + console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); + this._initialTop = this._element.domNode.offsetTop + 4; + this._initialHeight = this._element.domNode.clientHeight; + } + console.log('this._element.domNode : ', this._element.domNode); } public override dispose(): void { @@ -758,6 +790,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.focus(); } } + + // resetting the distance to the top from the hover + this._initialTop = -1; + this._initialHeight = -1; } public onContentsChanged(): void { From 8f35179fca988fa0e225f330b54a53a1b6b4d78d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 21:11:50 +0100 Subject: [PATCH 08/95] code in for resizing, need to polish the code --- src/vs/base/browser/ui/hover/hover.css | 1 - .../contrib/hover/browser/contentHover.ts | 64 ++++++++++++++----- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 5cd824a3d7669..20c73b8332707 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -28,7 +28,6 @@ } .monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) { - max-width: 500px; word-wrap: break-word; } diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index ccec8ee020841..67387d0b18189 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -434,6 +434,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _initialTop: number = -1; private _initialHeight: number = -1; + private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; /** @@ -490,11 +491,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); - this._resize(e.dimension.width, e.dimension.height); + this._resize(e.dimension.width, e.dimension.height, this._renderingAbove); })); } - private _setLayoutOfResizableElement(size: dom.Dimension): void { + // Only called once, define here a default size + private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { // TODO: 1) Make resizing correct generally between the resizable element and the container dom node // TODO: 2) Do correct calculations of maximum height above and below in order to decide which sashes to enable @@ -502,6 +504,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Setting the initial layout of the resizable element, before calling the resize function console.log('* Entered into _resizableLayout of ContentHoverWidget'); + console.log('defaultSize : ', defaultSize); console.log('this._mousePosition : ', this._mousePosition); console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); @@ -524,9 +527,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Hard-coded in the hover.css file as 1.5em or 24px const minHeight = 24; - console.log('size : ', size); - let height = size.height; - let width = size.width; + console.log('size : ', defaultSize); + let height = defaultSize.height; + let width = defaultSize.width; // Hard-code the values for now! // TODO: Where to find the border and padding values? @@ -537,7 +540,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // The full height is already passed in as a parameter - const fullHeight = size.height; + const fullHeight = defaultSize.height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); // We want not the cursor box but the mouse box const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); @@ -569,6 +572,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Suppose that the height of the suggest widget is bigger than some maximum height, or the rendering should be above, and there is enough space above the cursor console.log('Before enabling sashes'); + if (preferRenderingAbove) { console.log('first if condition'); @@ -578,6 +582,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const southSash = height >= maxHeightAbove; maxHeight = height < maxHeightAbove ? maxHeightAbove : maxHeightBelow; + this._renderingAbove = height < maxHeightAbove; this._element.enableSashes(northSash, eastSash, southSash, westSash); } else { @@ -588,6 +593,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const southSash = height < maxHeightBelow; maxHeight = height < maxHeightBelow ? maxHeightBelow : maxHeightAbove; + this._renderingAbove = height >= maxHeightBelow; this._element.enableSashes(northSash, eastSash, southSash, westSash); } @@ -596,7 +602,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 this._element.minSize = new dom.Dimension(10, minHeight); - this._resize(width, height); + this._resize(width, height, this._renderingAbove); // TODO: Enable sashes on different places depending on if hover shown on the top or on the bottom // TODO: When the hover is extended too much, so that part of it disappears, it disappears completely @@ -610,12 +616,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } - private _resize(width: number, height: number): void { + private _resize(width: number, height: number, renderingAbove: boolean): void { console.log('this._initialHeight : ', this._initialHeight); console.log('this._initialTop : ', this._initialTop); - if (this._initialHeight !== -1) { + if (this._initialHeight !== -1 && renderingAbove) { + // If it's not the initial rendering and rendering above const diff = height - this._initialHeight; // When difference positive, means that the widget grew, place it higher up this._element.domNode.style.top = this._initialTop - diff + 'px'; @@ -637,10 +644,26 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Sashes are 4 px wide, do not hardcode later // Forcing the container do node to have another size, but what we should do is make the resizable element have same dimension as container dom node + // TODO: Maybe have to add this back this._hover.containerDomNode.style.height = `${height - 4}px`; this._hover.containerDomNode.style.width = `${width - 4}px`; - if (this._initialTop === -1 || this._initialTop === 0) { + console.log('this._hover.containerDomNode.offsetWidth : ', this._hover.containerDomNode.offsetWidth); + console.log('this._hover.containerDomNode.offsetHeight : ', this._hover.containerDomNode.offsetHeight); + console.log('this._hover.contentsDomNode.offsetWidth : ', this._hover.contentsDomNode.offsetWidth); + console.log('this._hover.contentsDomNode.offsetHeight : ', this._hover.contentsDomNode.offsetHeight); + + const maxResizableWidth = this._hover.contentsDomNode.offsetWidth; + const maxResizableHeight = this._hover.contentsDomNode.offsetHeight; + + const currentMaxSize = new dom.Dimension(maxResizableWidth, maxResizableHeight); + console.log('currentMaxSize : ', currentMaxSize); + // this._element.maxSize = currentMaxSize; + + console.log('this._element.domNode.style.maxWidth : ', this._element.domNode.style.maxWidth); + console.log('this._element.domNode.style.maxHeight : ', this._element.domNode.style.maxHeight); + + if (this._initialTop === -1) { console.log('Entered into update of initial top'); console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); console.log('this._element.domNode.style : ', this._element.domNode.style); @@ -736,8 +759,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.fontSize = `${fontSize}px`; this._hover.contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; - this._hover.contentsDomNode.style.maxHeight = `${height}px`; - this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; + // Removing the max width and the max height on the content + // this._hover.contentsDomNode.style.maxHeight = `${height}px`; + // this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; this._hover.maxHeight = height; this._hover.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); @@ -749,6 +773,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { + + // Setting maximum so that the hover initially made to respect these conditions + // this._hover.containerDomNode.style.maxHeight = '150px'; + // this._hover.containerDomNode.style.maxWidth = '300px'; + console.log(' * Entered into showAt of ContentHoverWidget'); console.log('visibleData : ', visibleData); @@ -776,9 +805,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Resizable // Only called once, when the widget is first shown - const newSize = new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); - console.log('newSize : ', newSize); - this._setLayoutOfResizableElement(newSize); + // Set a default size which can then be changed + // TODO: Set a better default, this is causing small initial sizes + console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); + console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); + const defaultMaxHeight = Math.min(150, this._hover.contentsDomNode.offsetHeight); + const defaultMaxWidth = Math.min(300, this._hover.contentsDomNode.offsetWidth); + const defaultSize = new dom.Dimension(defaultMaxWidth, defaultMaxHeight); + this._setLayoutOfResizableElement(defaultSize); } public hide(): void { From 3234bce6c02414af0eafc3681e468ab1abeb8624 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 21:13:44 +0100 Subject: [PATCH 09/95] added todo list for steps to take --- src/vs/editor/contrib/hover/browser/contentHover.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 67387d0b18189..8813cc4cdff23 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -498,8 +498,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Only called once, define here a default size private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { - // TODO: 1) Make resizing correct generally between the resizable element and the container dom node + // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed // TODO: 2) Do correct calculations of maximum height above and below in order to decide which sashes to enable + // TODO: 3) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show // Setting the initial layout of the resizable element, before calling the resize function From 36fc4ab53274d0b46908263458c09fd64ce14b9d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 10 Mar 2023 21:36:32 +0100 Subject: [PATCH 10/95] adding some more comments --- .../contrib/hover/browser/contentHover.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 8813cc4cdff23..37c33fd0868f2 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -499,8 +499,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: 2) Do correct calculations of maximum height above and below in order to decide which sashes to enable - // TODO: 3) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show + // TODO: 2) Find out why the scrollbars disappeared, make them appear again, so can be used to scroll the resized element, look at the scroll bar from the suggest widget + // TODO: 3) Do correct calculations of maximum height above and below in order to decide which sashes to enable + // TODO: 4) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show + // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown // Setting the initial layout of the resizable element, before calling the resize function @@ -649,10 +651,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.style.height = `${height - 4}px`; this._hover.containerDomNode.style.width = `${width - 4}px`; + const containerOffsetHeight = this._hover.containerDomNode.offsetHeight; + const contentsOffsetHeight = this._hover.contentsDomNode.offsetHeight; console.log('this._hover.containerDomNode.offsetWidth : ', this._hover.containerDomNode.offsetWidth); - console.log('this._hover.containerDomNode.offsetHeight : ', this._hover.containerDomNode.offsetHeight); + console.log('this._hover.containerDomNode.offsetHeight : ', containerOffsetHeight); console.log('this._hover.contentsDomNode.offsetWidth : ', this._hover.contentsDomNode.offsetWidth); - console.log('this._hover.contentsDomNode.offsetHeight : ', this._hover.contentsDomNode.offsetHeight); + console.log('this._hover.contentsDomNode.offsetHeight : ', contentsOffsetHeight); const maxResizableWidth = this._hover.contentsDomNode.offsetWidth; const maxResizableHeight = this._hover.contentsDomNode.offsetHeight; @@ -661,6 +665,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('currentMaxSize : ', currentMaxSize); // this._element.maxSize = currentMaxSize; + if (containerOffsetHeight < contentsOffsetHeight) { + // make scrollbar visible? + console.log('container height offset smaller than contents height offset'); + } + console.log('this._element.domNode.style.maxWidth : ', this._element.domNode.style.maxWidth); console.log('this._element.domNode.style.maxHeight : ', this._element.domNode.style.maxHeight); From 7ce0334daa7b64cc0196b7c1dea24a189f1e0767 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 12 Mar 2023 21:36:28 +0100 Subject: [PATCH 11/95] Adding comments, current solution works but scroll does not --- src/vs/base/browser/ui/hover/hoverWidget.ts | 1 + .../contrib/hover/browser/contentHover.ts | 50 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index afa44bf0aec3f..5c1cf095c0a12 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -18,6 +18,7 @@ export const enum HoverPosition { export class HoverWidget extends Disposable { + // Do we need the maximum height and the maximum width public maxHeight = 0; public maxWidth = 0; diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 37c33fd0868f2..fa41d5fbdb96f 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -430,10 +430,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); + // The mouse position in the editor is needed in order to calculate the space above and below it private _mousePosition: IPosition | null = null; private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + // When the content hover is rendered, the following two variables store the initial position from the top and the initial height private _initialTop: number = -1; private _initialHeight: number = -1; + // Storing the preference of whether we want to render above or below private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; @@ -480,7 +483,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); - // Savin tha approximate position of the mouse + // Saving the approximate position of the mouse this._register(this._editor.onMouseMove(e => { this._mousePosition = e.target.position; })); @@ -488,6 +491,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._element.onDidWillResize(() => { console.log('* Inside of onDidWillResize of ContentHoverWidget'); })); + // The below is called when the resizable element is reized this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); @@ -502,16 +506,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: 2) Find out why the scrollbars disappeared, make them appear again, so can be used to scroll the resized element, look at the scroll bar from the suggest widget // TODO: 3) Do correct calculations of maximum height above and below in order to decide which sashes to enable // TODO: 4) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show - // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown - - // Setting the initial layout of the resizable element, before calling the resize function + // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size console.log('* Entered into _resizableLayout of ContentHoverWidget'); console.log('defaultSize : ', defaultSize); console.log('this._mousePosition : ', this._mousePosition); console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); - // Mistake in the height calculations it appears if (!this._editor.hasModel()) { return; @@ -624,33 +625,30 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('this._initialHeight : ', this._initialHeight); console.log('this._initialTop : ', this._initialTop); + // Suppose that this is not the first time the resize is called after the initial rendering and we are rendering above + // Then update the top position of the widget if (this._initialHeight !== -1 && renderingAbove) { - // If it's not the initial rendering and rendering above const diff = height - this._initialHeight; // When difference positive, means that the widget grew, place it higher up this._element.domNode.style.top = this._initialTop - diff + 'px'; } console.log(' * Entered into the _resize function of ContentHoverWidget'); - // Performs the actual resizing const { width: maxWidth, height: maxHeight } = this._element.maxSize; console.log('maxWidth : ', maxWidth, ' width : ', width); width = Math.min(maxWidth, width); console.log('maxHeight : ', maxHeight, ' height : ', height); height = Math.min(maxHeight, height); + // Setting the size of the resizable element with the height and width given this._element.layout(height, width); console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); - // Make the inner container also have that size? - // If you do the following, the sashes disappear, we do not want that - // Sashes are 4 px wide, do not hardcode later - - // Forcing the container do node to have another size, but what we should do is make the resizable element have same dimension as container dom node - // TODO: Maybe have to add this back + // Making the hover container dom node have height and width of the resizable element minus the pixels needed in order to show the sashes this._hover.containerDomNode.style.height = `${height - 4}px`; this._hover.containerDomNode.style.width = `${width - 4}px`; + // TODO Experimentation done for finding the maximum current size to give to the resizable element const containerOffsetHeight = this._hover.containerDomNode.offsetHeight; const contentsOffsetHeight = this._hover.contentsDomNode.offsetHeight; console.log('this._hover.containerDomNode.offsetWidth : ', this._hover.containerDomNode.offsetWidth); @@ -660,11 +658,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const maxResizableWidth = this._hover.contentsDomNode.offsetWidth; const maxResizableHeight = this._hover.contentsDomNode.offsetHeight; - const currentMaxSize = new dom.Dimension(maxResizableWidth, maxResizableHeight); console.log('currentMaxSize : ', currentMaxSize); // this._element.maxSize = currentMaxSize; + // Find when to make the scroll-bar visible if (containerOffsetHeight < contentsOffsetHeight) { // make scrollbar visible? console.log('container height offset smaller than contents height offset'); @@ -673,19 +671,23 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('this._element.domNode.style.maxWidth : ', this._element.domNode.style.maxWidth); console.log('this._element.domNode.style.maxHeight : ', this._element.domNode.style.maxHeight); + // If the initial top and height values have not been updated yet, update them the first time the content is rendered if (this._initialTop === -1) { - console.log('Entered into update of initial top'); - console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); - console.log('this._element.domNode.style : ', this._element.domNode.style); - console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); - console.log('this._element.domNode.style[0] : ', this._element.domNode.style[0]); - console.log('this._element.domNode.clientHeight : ', this._element.domNode.clientHeight); - console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); - console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); + // console.log('Entered into update of initial top'); + // console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); + // console.log('this._element.domNode.style : ', this._element.domNode.style); + // console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); + // console.log('this._element.domNode.style[0] : ', this._element.domNode.style[0]); + // console.log('this._element.domNode.clientHeight : ', this._element.domNode.clientHeight); + // console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); + // console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); this._initialTop = this._element.domNode.offsetTop + 4; this._initialHeight = this._element.domNode.clientHeight; } + + this._hover.scrollbar.scanDomNode(); console.log('this._element.domNode : ', this._element.domNode); + console.log('this._hover.scrollbar : ', this._hover.scrollbar); } public override dispose(): void { @@ -702,6 +704,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public getDomNode(): HTMLElement { // return this._hover.containerDomNode; + // Returning instead the resizable element return this._element.domNode; } @@ -773,6 +776,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._hover.contentsDomNode.style.maxHeight = `${height}px`; // this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; + // TODO: Do we need this? this._hover.maxHeight = height; this._hover.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); } @@ -813,9 +817,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } visibleData.colorPicker?.layout(); - // Resizable // Only called once, when the widget is first shown - // Set a default size which can then be changed // TODO: Set a better default, this is causing small initial sizes console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); From 2639aae6063083b8a6c2e1b43a1b930357eae9b5 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 13 Mar 2023 11:37:14 +0100 Subject: [PATCH 12/95] Added code in order to have the scroll bar on the contents dom node too --- src/vs/base/browser/fastDomNode.ts | 4 ++ src/vs/base/browser/ui/hover/hoverWidget.ts | 1 + .../browser/ui/scrollbar/abstractScrollbar.ts | 7 +++ .../ui/scrollbar/horizontalScrollbar.ts | 1 + .../browser/ui/scrollbar/scrollableElement.ts | 42 ++++++++++++- .../browser/ui/scrollbar/scrollbarState.ts | 7 +++ .../scrollbarVisibilityController.ts | 61 +++++++++++++++++-- .../browser/ui/scrollbar/verticalScrollbar.ts | 2 + src/vs/base/common/scrollable.ts | 2 + .../contrib/hover/browser/contentHover.ts | 29 ++++++++- 10 files changed, 148 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/fastDomNode.ts b/src/vs/base/browser/fastDomNode.ts index 1ef17e48cd5d4..9fdd934e5ae1b 100644 --- a/src/vs/base/browser/fastDomNode.ts +++ b/src/vs/base/browser/fastDomNode.ts @@ -214,7 +214,11 @@ export class FastDomNode { } public setClassName(className: string): void { + console.log('Inside of setClassName'); + console.log('this._className : ', this._className); + console.log('className : ', className); if (this._className === className) { + console.log('Early return'); return; } this._className = className; diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index 5c1cf095c0a12..e0a78aa3033c2 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -37,6 +37,7 @@ export class HoverWidget extends Disposable { this.contentsDomNode = document.createElement('div'); this.contentsDomNode.className = 'monaco-hover-content'; + // TODO: set the client height and scroll height appropriately this.scrollbar = this._register(new DomScrollableElement(this.contentsDomNode, { consumeMouseWheelIfScrollbarIsNeeded: true })); diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index 5ab75393d9e64..5febf8e976144 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -64,6 +64,7 @@ export abstract class AbstractScrollbar extends Widget { this._scrollByPage = opts.scrollByPage; this._scrollbarState = opts.scrollbarState; this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName)); + console.log('In the constructor of AbstractScrollbar'); this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); this._shouldRender = true; @@ -78,6 +79,9 @@ export abstract class AbstractScrollbar extends Widget { } // ----------------- creation + get visibilityController() { + return this._visibilityController; + } /** * Creates the dom node for an arrow & adds it to the container @@ -129,6 +133,7 @@ export abstract class AbstractScrollbar extends Widget { // ----------------- Update state protected _onElementSize(visibleSize: number): boolean { + console.log('Inside of _onElementSize'); if (this._scrollbarState.setVisibleSize(visibleSize)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; @@ -140,6 +145,7 @@ export abstract class AbstractScrollbar extends Widget { } protected _onElementScrollSize(elementScrollSize: number): boolean { + console.log('Inside of _onElementScrollSize'); if (this._scrollbarState.setScrollSize(elementScrollSize)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; @@ -151,6 +157,7 @@ export abstract class AbstractScrollbar extends Widget { } protected _onElementScrollPosition(elementScrollPosition: number): boolean { + console.log('Inside of _onElementScrollPosition'); if (this._scrollbarState.setScrollPosition(elementScrollPosition)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; diff --git a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts index 9672118552d07..f56883d8d4e6f 100644 --- a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts @@ -108,6 +108,7 @@ export class HorizontalScrollbar extends AbstractScrollbar { } public updateOptions(options: ScrollableElementResolvedOptions): void { + console.log('Inside of updateOptions of HorizontalScrollbar'); this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.Hidden ? 0 : options.horizontalScrollbarSize); this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); this._visibilityController.setVisibility(options.horizontal); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 87d4ed4d9fa38..3cf7004073557 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -337,6 +337,7 @@ export abstract class AbstractScrollableElement extends Widget { this._verticalScrollbar.updateOptions(this._options); if (!this._options.lazyRender) { + console.log('Inside of updateOptions of AbstractScrollableElement'); this._render(); } } @@ -465,8 +466,11 @@ export abstract class AbstractScrollableElement extends Widget { } private _onDidScroll(e: ScrollEvent): void { + console.log('Inside of _onDidScroll'); + this._shouldRender = this._horizontalScrollbar.onDidScroll(e) || this._shouldRender; this._shouldRender = this._verticalScrollbar.onDidScroll(e) || this._shouldRender; + console.log('this._shouldRender: ', this._shouldRender); if (this._options.useShadows) { this._shouldRender = true; @@ -489,18 +493,21 @@ export abstract class AbstractScrollableElement extends Widget { if (!this._options.lazyRender) { throw new Error('Please use `lazyRender` together with `renderNow`!'); } - + console.log('Inside of renderNow of AbstractScrollableElement'); this._render(); } private _render(): void { + console.log('** Inside of _render of AbstractScrollableElement'); if (!this._shouldRender) { return; } this._shouldRender = false; + console.log('Before rendering of horizontal scroll bar'); this._horizontalScrollbar.render(); + console.log('Before rendering of the vertical scroll bar'); this._verticalScrollbar.render(); if (this._options.useShadows) { @@ -525,27 +532,48 @@ export abstract class AbstractScrollableElement extends Widget { } private _onDragEnd(): void { + console.log('Inside of _onDragEnd of AbstractScrollableElement'); this._isDragging = false; this._hide(); } private _onMouseLeave(e: IMouseEvent): void { + console.log('** _onMouseLeave inside of AbstractScrollableElement'); this._mouseIsOver = false; this._hide(); } private _onMouseOver(e: IMouseEvent): void { + console.log(' ** _onMouseOver inside of AbstractScrollableElement'); this._mouseIsOver = true; this._reveal(); } private _reveal(): void { + console.log('** Inside of _reveal of AbstractScrollableElement'); + console.log('Begin reveal for vertical scroll-bar'); this._verticalScrollbar.beginReveal(); + console.log('this._verticalScrollBar.visibilityController.shouldBeVisible : ', this._verticalScrollbar.visibilityController.shouldBeVisible); + console.log('this._verticalScrollBar.visibilityController.isVisible ', this._verticalScrollbar.visibilityController.isVisible); + console.log('this._verticalScrollBar.visibilityController.visibility ', this._verticalScrollbar.visibilityController.visibility); + console.log('this._verticalScrollBar.visibilityController.visibileClassName ', this._verticalScrollbar.visibilityController.visibileClassName); + console.log('this._verticalScrollBar.visibilityController.invisibileClassName ', this._verticalScrollbar.visibilityController.invisibleClassName); + console.log('this._verticalScrollbar.domNode.domNode.className : ', this._verticalScrollbar.domNode.domNode.className); + + console.log('Begin reveal for horizontal scroll-bar'); this._horizontalScrollbar.beginReveal(); + console.log('this._horizontalScrollBar : ', this._horizontalScrollbar); + console.log('this._horizontalScrollbar.visibilityController.shouldBeVisible : ', this._horizontalScrollbar.visibilityController.shouldBeVisible); + console.log('this._horizontalScrollbar.visibilityController.isVisible ', this._horizontalScrollbar.visibilityController.isVisible); + console.log('this._horizontalScrollbar.visibilityController.visibility ', this._horizontalScrollbar.visibilityController.visibility); + console.log('this._horizontalScrollbar.visibilityController.visibileClassName ', this._horizontalScrollbar.visibilityController.visibileClassName); + console.log('this._horizontalScrollbar.visibilityController.invisibileClassName ', this._horizontalScrollbar.visibilityController.invisibleClassName); + console.log('this._verticalScrollbar.domNode.domNode.className ', this._verticalScrollbar.domNode.domNode.className); this._scheduleHide(); } private _hide(): void { + console.log(' ** Inside of _hide of AbstractScrollableElement'); if (!this._mouseIsOver && !this._isDragging) { this._verticalScrollbar.beginHide(); this._horizontalScrollbar.beginHide(); @@ -553,8 +581,14 @@ export abstract class AbstractScrollableElement extends Widget { } private _scheduleHide(): void { + console.log('Inside of _scheduleHide'); + console.log('this._mouseIsOver : ', this._mouseIsOver); + console.log('this._isDragging : ', this._isDragging); if (!this._mouseIsOver && !this._isDragging) { - this._hideTimeout.cancelAndSet(() => this._hide(), HIDE_TIMEOUT); + this._hideTimeout.cancelAndSet(() => { + console.log('Hiding because of the timeout'); + this._hide(); + }, HIDE_TIMEOUT); } } } @@ -616,6 +650,7 @@ export class DomScrollableElement extends AbstractScrollableElement { }); super(element, options, scrollable); this._register(scrollable); + // Element is set once this._element = element; this.onScroll((e) => { if (e.scrollTopChanged) { @@ -638,6 +673,9 @@ export class DomScrollableElement extends AbstractScrollableElement { public scanDomNode(): void { // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight + console.log('Inside of scanDomNode'); + console.log('this._element.clientHeight : ', this._element.clientHeight); + console.log('this._element.scrollHeight : ', this._element.scrollHeight); this.setScrollDimensions({ width: this._element.clientWidth, scrollWidth: this._element.scrollWidth, diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts index 9a4f4e2cbbdcc..70379b705a5e0 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts @@ -84,6 +84,7 @@ export class ScrollbarState { return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition); } + // Here you can set the visible size of the scroll bar public setVisibleSize(visibleSize: number): boolean { const iVisibleSize = Math.round(visibleSize); if (this._visibleSize !== iVisibleSize) { @@ -94,6 +95,7 @@ export class ScrollbarState { return false; } + // You can also set the scroll size, or the possible height of the scrolling public setScrollSize(scrollSize: number): boolean { const iScrollSize = Math.round(scrollSize); if (this._scrollSize !== iScrollSize) { @@ -123,8 +125,11 @@ export class ScrollbarState { } private static _computeValues(oppositeScrollbarSize: number, arrowSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) { + console.log('Inside of _computeValues of ScrollbarState'); const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize); const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize); + console.log('visibleSize : ', visibleSize); + console.log('scrollSize : ', scrollSize); const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize); if (!computedIsNeeded) { @@ -156,6 +161,7 @@ export class ScrollbarState { } private _refreshComputedValues(): void { + // Updating the fact whether we need the scroll bar ot not const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition); this._computedAvailableSize = r.computedAvailableSize; this._computedIsNeeded = r.computedIsNeeded; @@ -181,6 +187,7 @@ export class ScrollbarState { } public isNeeded(): boolean { + console.log('Inside of isNeeded of the ScrollbarState'); return this._computedIsNeeded; } diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts index 791c7332ffb16..cf89649a6289f 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts @@ -32,7 +32,29 @@ export class ScrollbarVisibilityController extends Disposable { this._revealTimer = this._register(new TimeoutTimer()); } + get shouldBeVisible(): boolean { + return this._shouldBeVisible; + } + + get isVisible(): boolean { + return this._isVisible; + } + + get visibility() { + return this._visibility; + } + + get visibileClassName(): string { + return this._visibleClassName; + } + + get invisibleClassName(): string { + return this._invisibleClassName; + } + public setVisibility(visibility: ScrollbarVisibility): void { + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('Inside of setVisibility'); if (this._visibility !== visibility) { this._visibility = visibility; this._updateShouldBeVisible(); @@ -42,6 +64,9 @@ export class ScrollbarVisibilityController extends Disposable { // ----------------- Hide / Reveal public setShouldBeVisible(rawShouldBeVisible: boolean): void { + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('Inside of setShouldBeVisible of ScrollbarVisibilityController'); + console.log('rawShouldBeVisible: ', rawShouldBeVisible); this._rawShouldBeVisible = rawShouldBeVisible; this._updateShouldBeVisible(); } @@ -58,11 +83,20 @@ export class ScrollbarVisibilityController extends Disposable { private _updateShouldBeVisible(): void { const shouldBeVisible = this._applyVisibilitySetting(); - + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('Inside of _updateShouldBeVisible of ScrollbarVisibilityController'); + console.log('this._shouldBeVisible: ', this._shouldBeVisible); + console.log('shouldBeVisible: ', shouldBeVisible); + /* if (this._shouldBeVisible !== shouldBeVisible) { this._shouldBeVisible = shouldBeVisible; this.ensureVisibility(); + } else { + console.log('Not entering into ensureVisibility, end of call'); } + */ + this._shouldBeVisible = shouldBeVisible; + this.ensureVisibility(); } public setIsNeeded(isNeeded: boolean): void { @@ -74,6 +108,7 @@ export class ScrollbarVisibilityController extends Disposable { public setDomNode(domNode: FastDomNode): void { this._domNode = domNode; + console.log('Inside of setDomNode of ScrollbarVisibilityController'); this._domNode.setClassName(this._invisibleClassName); // Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration @@ -81,38 +116,54 @@ export class ScrollbarVisibilityController extends Disposable { } public ensureVisibility(): void { - + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('Inside of ensureVisibility of ScrollbarVisibilityController'); if (!this._isNeeded) { // Nothing to be rendered + console.log('is not neeeded'); this._hide(false); return; } if (this._shouldBeVisible) { + console.log('revealing'); this._reveal(); } else { + console.log('hiding'); this._hide(true); } } private _reveal(): void { + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('Inside of _reveal of ScrollbarVisibilityController'); if (this._isVisible) { + console.log('Early return because visible'); return; } this._isVisible = true; // The CSS animation doesn't play otherwise - this._revealTimer.setIfNotSet(() => { - this._domNode?.setClassName(this._visibleClassName); - }, 0); + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('set the visible class name'); + console.log('this._visibleClassName : ', this._visibleClassName); + // this._revealTimer.setIfNotSet(() => { + // this._domNode?.setClassName(this._visibleClassName); + // }, 0); + this._domNode?.setClassName(this._visibleClassName); + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); } private _hide(withFadeAway: boolean): void { + console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + console.log('Inside of _hide of ScrollbarVisibilityController'); this._revealTimer.cancel(); if (!this._isVisible) { + console.log('Early return because not visible'); return; } this._isVisible = false; + console.log('set the invisible class name'); this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : '')); } } diff --git a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts index 672bde8e01777..848f7ca8484db 100644 --- a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts @@ -18,6 +18,7 @@ export class VerticalScrollbar extends AbstractScrollbar { constructor(scrollable: Scrollable, options: ScrollableElementResolvedOptions, host: ScrollbarHost) { const scrollDimensions = scrollable.getScrollDimensions(); const scrollPosition = scrollable.getCurrentScrollPosition(); + // TODO; It would appear that the scroll dimensions height and scroll height are the same while they should not be the same super({ lazyRender: options.lazyRender, host: host, @@ -108,6 +109,7 @@ export class VerticalScrollbar extends AbstractScrollbar { } public updateOptions(options: ScrollableElementResolvedOptions): void { + console.log('Inside of update options of VerticalScrollBar'); this.updateScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom this._scrollbarState.setOppositeScrollbarSize(0); diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 1be0752c3fd40..9151afda75cf1 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -239,6 +239,7 @@ export class Scrollable extends Disposable { this._smoothScrollDuration = options.smoothScrollDuration; this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame; + // Initially the scroll state height and scroll height are zero this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0); this._smoothScrolling = null; } @@ -263,6 +264,7 @@ export class Scrollable extends Disposable { return this._state; } + // Can set the scroll dimensions or the height and the scroll height public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void { const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions); this._setState(newState, Boolean(this._smoothScrolling)); diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index fa41d5fbdb96f..dd8b9f3a1b54c 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -427,6 +427,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); + // private readonly _hoverCopy: HoverWidget = this._register(new HoverWidget()); // Adding a resizable element directly to the content hover widget private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); @@ -487,7 +488,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._editor.onMouseMove(e => { this._mousePosition = e.target.position; })); + this._element.domNode.appendChild(this._hover.containerDomNode); + + // Place also the hover container dom node on top of the resizable element + // const boundingBox = this._hover.containerDomNode.getBoundingClientRect(); + // this._hoverCopy.containerDomNode.style.top = boundingBox.top + 'px'; + // this._hoverCopy.containerDomNode.style.left = boundingBox.left + 'px'; + // this._hoverCopy.containerDomNode.style.width = boundingBox.width + 'px'; + // this._hoverCopy.containerDomNode.style.height = boundingBox.height + 'px'; + // this._hoverCopy.containerDomNode.style.zIndex = '1000'; + // console.log('this_hoverCopy.containerDomNode : ', this._hoverCopy.containerDomNode); + this._register(this._element.onDidWillResize(() => { console.log('* Inside of onDidWillResize of ContentHoverWidget'); })); @@ -685,9 +697,24 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._initialHeight = this._element.domNode.clientHeight; } + // Client height and scroll height should not be the same so that the scroll bar is needed + this._hover.contentsDomNode.style.height = `${height - 4}px`; + this._hover.contentsDomNode.style.width = `${width - 4}px`; + console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + this._hover.scrollbar.scanDomNode(); console.log('this._element.domNode : ', this._element.domNode); - console.log('this._hover.scrollbar : ', this._hover.scrollbar); + + // this._hoverCopy.scrollbar.scanDomNode(); + // console.log('this._hover.scrollbar : ', this._hover.scrollbar); + // Adding code for hover copy!! + // const boundingBox = this._hover.containerDomNode.getBoundingClientRect(); + // this._hoverCopy.containerDomNode.style.top = boundingBox.top + 'px'; + // this._hoverCopy.containerDomNode.style.left = boundingBox.left + 'px'; + // this._hoverCopy.containerDomNode.style.width = boundingBox.width + 'px'; + // this._hoverCopy.containerDomNode.style.height = boundingBox.height + 'px'; + // console.log('this_hoverCopy.containerDomNode : ', this._hoverCopy.containerDomNode); } public override dispose(): void { From 62e5490add1cab1d7bc8d8256fd8ef534e19a240 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 13 Mar 2023 13:36:01 +0100 Subject: [PATCH 13/95] Changing the available space above to the mouse box top along with the tabs height and the breadcrumbs height --- src/vs/base/browser/fastDomNode.ts | 8 +- src/vs/base/browser/ui/hover/hoverWidget.ts | 1 - src/vs/base/browser/ui/resizable/resizable.ts | 2 +- .../browser/ui/scrollbar/abstractScrollbar.ts | 8 +- .../ui/scrollbar/horizontalScrollbar.ts | 2 +- .../browser/ui/scrollbar/scrollableElement.ts | 46 +++++----- .../browser/ui/scrollbar/scrollbarState.ts | 8 +- .../scrollbarVisibilityController.ts | 66 +++++++-------- .../browser/ui/scrollbar/verticalScrollbar.ts | 2 +- .../contrib/hover/browser/contentHover.ts | 84 +++++++++++-------- 10 files changed, 120 insertions(+), 107 deletions(-) diff --git a/src/vs/base/browser/fastDomNode.ts b/src/vs/base/browser/fastDomNode.ts index 9fdd934e5ae1b..3e304729defe7 100644 --- a/src/vs/base/browser/fastDomNode.ts +++ b/src/vs/base/browser/fastDomNode.ts @@ -214,11 +214,11 @@ export class FastDomNode { } public setClassName(className: string): void { - console.log('Inside of setClassName'); - console.log('this._className : ', this._className); - console.log('className : ', className); + // console.log('Inside of setClassName'); + // console.log('this._className : ', this._className); + // console.log('className : ', className); if (this._className === className) { - console.log('Early return'); + // console.log('Early return'); return; } this._className = className; diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index e0a78aa3033c2..5c1cf095c0a12 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -37,7 +37,6 @@ export class HoverWidget extends Disposable { this.contentsDomNode = document.createElement('div'); this.contentsDomNode.className = 'monaco-hover-content'; - // TODO: set the client height and scroll height appropriately this.scrollbar = this._register(new DomScrollableElement(this.contentsDomNode, { consumeMouseWheelIfScrollbarIsNeeded: true })); diff --git a/src/vs/base/browser/ui/resizable/resizable.ts b/src/vs/base/browser/ui/resizable/resizable.ts index 4e14a2698fd39..5c2d4a0c434c5 100644 --- a/src/vs/base/browser/ui/resizable/resizable.ts +++ b/src/vs/base/browser/ui/resizable/resizable.ts @@ -145,7 +145,7 @@ export class ResizableHTMLElement { // We layout of the resize element is changed only when it is different to the size before if (!Dimension.equals(newSize, this._size)) { - console.log('Inside of the if statement of the layout function of ResizableHTMLElement'); + // console.log('Inside of the if statement of the layout function of ResizableHTMLElement'); this.domNode.style.height = height + 'px'; this.domNode.style.width = width + 'px'; this._size = newSize; diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index 5febf8e976144..88ef2bcc9adc9 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -64,7 +64,7 @@ export abstract class AbstractScrollbar extends Widget { this._scrollByPage = opts.scrollByPage; this._scrollbarState = opts.scrollbarState; this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName)); - console.log('In the constructor of AbstractScrollbar'); + // console.log('In the constructor of AbstractScrollbar'); this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); this._shouldRender = true; @@ -133,7 +133,7 @@ export abstract class AbstractScrollbar extends Widget { // ----------------- Update state protected _onElementSize(visibleSize: number): boolean { - console.log('Inside of _onElementSize'); + // console.log('Inside of _onElementSize'); if (this._scrollbarState.setVisibleSize(visibleSize)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; @@ -145,7 +145,7 @@ export abstract class AbstractScrollbar extends Widget { } protected _onElementScrollSize(elementScrollSize: number): boolean { - console.log('Inside of _onElementScrollSize'); + // console.log('Inside of _onElementScrollSize'); if (this._scrollbarState.setScrollSize(elementScrollSize)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; @@ -157,7 +157,7 @@ export abstract class AbstractScrollbar extends Widget { } protected _onElementScrollPosition(elementScrollPosition: number): boolean { - console.log('Inside of _onElementScrollPosition'); + // console.log('Inside of _onElementScrollPosition'); if (this._scrollbarState.setScrollPosition(elementScrollPosition)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; diff --git a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts index f56883d8d4e6f..4c8cdd697454e 100644 --- a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts @@ -108,7 +108,7 @@ export class HorizontalScrollbar extends AbstractScrollbar { } public updateOptions(options: ScrollableElementResolvedOptions): void { - console.log('Inside of updateOptions of HorizontalScrollbar'); + // console.log('Inside of updateOptions of HorizontalScrollbar'); this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.Hidden ? 0 : options.horizontalScrollbarSize); this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); this._visibilityController.setVisibility(options.horizontal); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 3cf7004073557..003cfbd867f08 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -337,7 +337,7 @@ export abstract class AbstractScrollableElement extends Widget { this._verticalScrollbar.updateOptions(this._options); if (!this._options.lazyRender) { - console.log('Inside of updateOptions of AbstractScrollableElement'); + // console.log('Inside of updateOptions of AbstractScrollableElement'); this._render(); } } @@ -466,11 +466,10 @@ export abstract class AbstractScrollableElement extends Widget { } private _onDidScroll(e: ScrollEvent): void { - console.log('Inside of _onDidScroll'); - + // console.log('Inside of _onDidScroll'); this._shouldRender = this._horizontalScrollbar.onDidScroll(e) || this._shouldRender; this._shouldRender = this._verticalScrollbar.onDidScroll(e) || this._shouldRender; - console.log('this._shouldRender: ', this._shouldRender); + // console.log('this._shouldRender: ', this._shouldRender); if (this._options.useShadows) { this._shouldRender = true; @@ -493,21 +492,21 @@ export abstract class AbstractScrollableElement extends Widget { if (!this._options.lazyRender) { throw new Error('Please use `lazyRender` together with `renderNow`!'); } - console.log('Inside of renderNow of AbstractScrollableElement'); + // console.log('Inside of renderNow of AbstractScrollableElement'); this._render(); } private _render(): void { - console.log('** Inside of _render of AbstractScrollableElement'); + // console.log('** Inside of _render of AbstractScrollableElement'); if (!this._shouldRender) { return; } this._shouldRender = false; - console.log('Before rendering of horizontal scroll bar'); + // console.log('Before rendering of horizontal scroll bar'); this._horizontalScrollbar.render(); - console.log('Before rendering of the vertical scroll bar'); + // console.log('Before rendering of the vertical scroll bar'); this._verticalScrollbar.render(); if (this._options.useShadows) { @@ -532,36 +531,38 @@ export abstract class AbstractScrollableElement extends Widget { } private _onDragEnd(): void { - console.log('Inside of _onDragEnd of AbstractScrollableElement'); + // console.log('Inside of _onDragEnd of AbstractScrollableElement'); this._isDragging = false; this._hide(); } private _onMouseLeave(e: IMouseEvent): void { - console.log('** _onMouseLeave inside of AbstractScrollableElement'); + // console.log('** _onMouseLeave inside of AbstractScrollableElement'); this._mouseIsOver = false; this._hide(); } private _onMouseOver(e: IMouseEvent): void { - console.log(' ** _onMouseOver inside of AbstractScrollableElement'); + // console.log(' ** _onMouseOver inside of AbstractScrollableElement'); this._mouseIsOver = true; this._reveal(); } private _reveal(): void { - console.log('** Inside of _reveal of AbstractScrollableElement'); - console.log('Begin reveal for vertical scroll-bar'); + // console.log('** Inside of _reveal of AbstractScrollableElement'); + // console.log('Begin reveal for vertical scroll-bar'); this._verticalScrollbar.beginReveal(); + /* console.log('this._verticalScrollBar.visibilityController.shouldBeVisible : ', this._verticalScrollbar.visibilityController.shouldBeVisible); console.log('this._verticalScrollBar.visibilityController.isVisible ', this._verticalScrollbar.visibilityController.isVisible); console.log('this._verticalScrollBar.visibilityController.visibility ', this._verticalScrollbar.visibilityController.visibility); console.log('this._verticalScrollBar.visibilityController.visibileClassName ', this._verticalScrollbar.visibilityController.visibileClassName); console.log('this._verticalScrollBar.visibilityController.invisibileClassName ', this._verticalScrollbar.visibilityController.invisibleClassName); console.log('this._verticalScrollbar.domNode.domNode.className : ', this._verticalScrollbar.domNode.domNode.className); - console.log('Begin reveal for horizontal scroll-bar'); + */ this._horizontalScrollbar.beginReveal(); + /* console.log('this._horizontalScrollBar : ', this._horizontalScrollbar); console.log('this._horizontalScrollbar.visibilityController.shouldBeVisible : ', this._horizontalScrollbar.visibilityController.shouldBeVisible); console.log('this._horizontalScrollbar.visibilityController.isVisible ', this._horizontalScrollbar.visibilityController.isVisible); @@ -569,11 +570,12 @@ export abstract class AbstractScrollableElement extends Widget { console.log('this._horizontalScrollbar.visibilityController.visibileClassName ', this._horizontalScrollbar.visibilityController.visibileClassName); console.log('this._horizontalScrollbar.visibilityController.invisibileClassName ', this._horizontalScrollbar.visibilityController.invisibleClassName); console.log('this._verticalScrollbar.domNode.domNode.className ', this._verticalScrollbar.domNode.domNode.className); + */ this._scheduleHide(); } private _hide(): void { - console.log(' ** Inside of _hide of AbstractScrollableElement'); + // console.log(' ** Inside of _hide of AbstractScrollableElement'); if (!this._mouseIsOver && !this._isDragging) { this._verticalScrollbar.beginHide(); this._horizontalScrollbar.beginHide(); @@ -581,12 +583,12 @@ export abstract class AbstractScrollableElement extends Widget { } private _scheduleHide(): void { - console.log('Inside of _scheduleHide'); - console.log('this._mouseIsOver : ', this._mouseIsOver); - console.log('this._isDragging : ', this._isDragging); + // console.log('Inside of _scheduleHide'); + // console.log('this._mouseIsOver : ', this._mouseIsOver); + // console.log('this._isDragging : ', this._isDragging); if (!this._mouseIsOver && !this._isDragging) { this._hideTimeout.cancelAndSet(() => { - console.log('Hiding because of the timeout'); + // console.log('Hiding because of the timeout'); this._hide(); }, HIDE_TIMEOUT); } @@ -673,9 +675,9 @@ export class DomScrollableElement extends AbstractScrollableElement { public scanDomNode(): void { // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight - console.log('Inside of scanDomNode'); - console.log('this._element.clientHeight : ', this._element.clientHeight); - console.log('this._element.scrollHeight : ', this._element.scrollHeight); + // console.log('Inside of scanDomNode'); + // console.log('this._element.clientHeight : ', this._element.clientHeight); + // console.log('this._element.scrollHeight : ', this._element.scrollHeight); this.setScrollDimensions({ width: this._element.clientWidth, scrollWidth: this._element.scrollWidth, diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts index 70379b705a5e0..4277ecf412ea2 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts @@ -125,11 +125,11 @@ export class ScrollbarState { } private static _computeValues(oppositeScrollbarSize: number, arrowSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) { - console.log('Inside of _computeValues of ScrollbarState'); + // console.log('Inside of _computeValues of ScrollbarState'); const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize); const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize); - console.log('visibleSize : ', visibleSize); - console.log('scrollSize : ', scrollSize); + // console.log('visibleSize : ', visibleSize); + // console.log('scrollSize : ', scrollSize); const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize); if (!computedIsNeeded) { @@ -187,7 +187,7 @@ export class ScrollbarState { } public isNeeded(): boolean { - console.log('Inside of isNeeded of the ScrollbarState'); + // console.log('Inside of isNeeded of the ScrollbarState'); return this._computedIsNeeded; } diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts index cf89649a6289f..cd247093e0cfa 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts @@ -53,8 +53,8 @@ export class ScrollbarVisibilityController extends Disposable { } public setVisibility(visibility: ScrollbarVisibility): void { - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('Inside of setVisibility'); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('Inside of setVisibility'); if (this._visibility !== visibility) { this._visibility = visibility; this._updateShouldBeVisible(); @@ -64,9 +64,9 @@ export class ScrollbarVisibilityController extends Disposable { // ----------------- Hide / Reveal public setShouldBeVisible(rawShouldBeVisible: boolean): void { - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('Inside of setShouldBeVisible of ScrollbarVisibilityController'); - console.log('rawShouldBeVisible: ', rawShouldBeVisible); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('Inside of setShouldBeVisible of ScrollbarVisibilityController'); + // console.log('rawShouldBeVisible: ', rawShouldBeVisible); this._rawShouldBeVisible = rawShouldBeVisible; this._updateShouldBeVisible(); } @@ -83,20 +83,14 @@ export class ScrollbarVisibilityController extends Disposable { private _updateShouldBeVisible(): void { const shouldBeVisible = this._applyVisibilitySetting(); - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('Inside of _updateShouldBeVisible of ScrollbarVisibilityController'); - console.log('this._shouldBeVisible: ', this._shouldBeVisible); - console.log('shouldBeVisible: ', shouldBeVisible); - /* + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('Inside of _updateShouldBeVisible of ScrollbarVisibilityController'); + // console.log('this._shouldBeVisible: ', this._shouldBeVisible); + // console.log('shouldBeVisible: ', shouldBeVisible); if (this._shouldBeVisible !== shouldBeVisible) { this._shouldBeVisible = shouldBeVisible; this.ensureVisibility(); - } else { - console.log('Not entering into ensureVisibility, end of call'); } - */ - this._shouldBeVisible = shouldBeVisible; - this.ensureVisibility(); } public setIsNeeded(isNeeded: boolean): void { @@ -108,7 +102,7 @@ export class ScrollbarVisibilityController extends Disposable { public setDomNode(domNode: FastDomNode): void { this._domNode = domNode; - console.log('Inside of setDomNode of ScrollbarVisibilityController'); + // console.log('Inside of setDomNode of ScrollbarVisibilityController'); this._domNode.setClassName(this._invisibleClassName); // Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration @@ -116,54 +110,54 @@ export class ScrollbarVisibilityController extends Disposable { } public ensureVisibility(): void { - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('Inside of ensureVisibility of ScrollbarVisibilityController'); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('Inside of ensureVisibility of ScrollbarVisibilityController'); if (!this._isNeeded) { // Nothing to be rendered - console.log('is not neeeded'); + // console.log('is not neeeded'); this._hide(false); return; } if (this._shouldBeVisible) { - console.log('revealing'); + // console.log('revealing'); this._reveal(); } else { - console.log('hiding'); + // console.log('hiding'); this._hide(true); } } private _reveal(): void { - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('Inside of _reveal of ScrollbarVisibilityController'); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('Inside of _reveal of ScrollbarVisibilityController'); if (this._isVisible) { - console.log('Early return because visible'); + // console.log('Early return because visible'); return; } this._isVisible = true; // The CSS animation doesn't play otherwise - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('set the visible class name'); - console.log('this._visibleClassName : ', this._visibleClassName); - // this._revealTimer.setIfNotSet(() => { - // this._domNode?.setClassName(this._visibleClassName); - // }, 0); - this._domNode?.setClassName(this._visibleClassName); - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('set the visible class name'); + // console.log('this._visibleClassName : ', this._visibleClassName); + this._revealTimer.setIfNotSet(() => { + this._domNode?.setClassName(this._visibleClassName); + }, 0); + // this._domNode?.setClassName(this._visibleClassName); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); } private _hide(withFadeAway: boolean): void { - console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - console.log('Inside of _hide of ScrollbarVisibilityController'); + // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); + // console.log('Inside of _hide of ScrollbarVisibilityController'); this._revealTimer.cancel(); if (!this._isVisible) { - console.log('Early return because not visible'); + // console.log('Early return because not visible'); return; } this._isVisible = false; - console.log('set the invisible class name'); + // console.log('set the invisible class name'); this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : '')); } } diff --git a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts index 848f7ca8484db..9b0414de5d75b 100644 --- a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts @@ -109,7 +109,7 @@ export class VerticalScrollbar extends AbstractScrollbar { } public updateOptions(options: ScrollableElementResolvedOptions): void { - console.log('Inside of update options of VerticalScrollBar'); + // console.log('Inside of update options of VerticalScrollBar'); this.updateScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom this._scrollbarState.setOppositeScrollbarSize(0); diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index dd8b9f3a1b54c..70df190efaaaa 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -515,7 +515,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: 2) Find out why the scrollbars disappeared, make them appear again, so can be used to scroll the resized element, look at the scroll bar from the suggest widget // TODO: 3) Do correct calculations of maximum height above and below in order to decide which sashes to enable // TODO: 4) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size @@ -538,17 +537,16 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); + console.log('bodyBox : ', bodyBox); - // Should return the default size of the suggest widget too // Hard-coded in the hover.css file as 1.5em or 24px const minHeight = 24; - console.log('size : ', defaultSize); + console.log('defaultSize : ', defaultSize); let height = defaultSize.height; let width = defaultSize.width; // Hard-code the values for now! - // TODO: Where to find the border and padding values? const maxWidth = bodyBox.width; if (width > maxWidth) { console.log('width capped at the maxWidth'); @@ -558,21 +556,27 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // The full height is already passed in as a parameter const fullHeight = defaultSize.height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - // We want not the cursor box but the mouse box + console.log('editorBox : ', editorBox); const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); console.log('mouseBox : ', mouseBox); + // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; - let maxHeightBelow = Math.min(bodyBox.height - mouseBottom, fullHeight); + console.log('mouseBottom : ', mouseBottom); + // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position + const availableSpaceBelow = bodyBox.height - mouseBottom; + console.log('availableSpaceBelow : ', availableSpaceBelow); + // Max height below is the minimum of the available space below and the full height of the widget + const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); console.log('maxHeightBelow : ', maxHeightBelow); - const availableSpaceAbove = editorBox.top + mouseBox.top; - let maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); + // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor + const availableSpaceAbove = mouseBox.top + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs + console.log('availableSpaceAbove : ', availableSpaceAbove); + // Max height above is the minimum of the available space above and the full height of the widget + const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); console.log('maxHeightAbove : ', maxHeightAbove); + // We find the maximum height of the widget possible on the top or on the bottom let maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); - - // TODO: CHANGE ONCE FIGURED OUT THE CORRECT MATH FOR MAXWIDTH AND MAXHEIGHT - maxHeightAbove = 1000; - maxHeightBelow = 1000; - // Change the above in order to correctly show the widget + console.log('maxHeight : ', maxHeight); if (height < minHeight) { console.log('height capped at the min height'); @@ -580,40 +584,41 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } if (height > maxHeight) { console.log('height capped at the maximum height'); + // The maximum height has been limited due to not enough height = maxHeight; } const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; console.log('preferRenderingAbove : ', preferRenderingAbove); - // Suppose that the height of the suggest widget is bigger than some maximum height, or the rendering should be above, and there is enough space above the cursor console.log('Before enabling sashes'); - if (preferRenderingAbove) { console.log('first if condition'); const westSash = false; const eastSash = true; - const northSash = height < maxHeightAbove; - const southSash = height >= maxHeightAbove; + const northSash = height <= maxHeightAbove; + const southSash = height > maxHeightAbove; - maxHeight = height < maxHeightAbove ? maxHeightAbove : maxHeightBelow; - this._renderingAbove = height < maxHeightAbove; + maxHeight = height <= maxHeightAbove ? maxHeightAbove : maxHeightBelow; + this._renderingAbove = height <= maxHeightAbove; + console.log('this._renderingAbove : ', this._renderingAbove); this._element.enableSashes(northSash, eastSash, southSash, westSash); } else { console.log('Second if condition'); const westSash = false; const eastSash = true; - const northSash = height >= maxHeightBelow; - const southSash = height < maxHeightBelow; + const northSash = height > maxHeightBelow; + const southSash = height <= maxHeightBelow; - maxHeight = height < maxHeightBelow ? maxHeightBelow : maxHeightAbove; - this._renderingAbove = height >= maxHeightBelow; + maxHeight = height <= maxHeightBelow ? maxHeightBelow : maxHeightAbove; + this._renderingAbove = height > maxHeightBelow; + console.log('this._renderingAbove : ', this._renderingAbove); this._element.enableSashes(northSash, eastSash, southSash, westSash); } - // TODO: Place the folloding line in order to use the calculated max width and max height + // TODO: Place the following line in order to use the calculated max width and max height this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 this._element.minSize = new dom.Dimension(10, minHeight); @@ -634,6 +639,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _resize(width: number, height: number, renderingAbove: boolean): void { + console.log(' * Entered into the _resize function of ContentHoverWidget'); + console.log('this._initialHeight : ', this._initialHeight); console.log('this._initialTop : ', this._initialTop); @@ -645,12 +652,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._element.domNode.style.top = this._initialTop - diff + 'px'; } - console.log(' * Entered into the _resize function of ContentHoverWidget'); const { width: maxWidth, height: maxHeight } = this._element.maxSize; console.log('maxWidth : ', maxWidth, ' width : ', width); width = Math.min(maxWidth, width); console.log('maxHeight : ', maxHeight, ' height : ', height); height = Math.min(maxHeight, height); + // Setting the size of the resizable element with the height and width given this._element.layout(height, width); console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); @@ -659,6 +666,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Making the hover container dom node have height and width of the resizable element minus the pixels needed in order to show the sashes this._hover.containerDomNode.style.height = `${height - 4}px`; this._hover.containerDomNode.style.width = `${width - 4}px`; + // Client height and scroll height should not be the same so that the scroll bar is needed + this._hover.contentsDomNode.style.height = `${height - 4}px`; + this._hover.contentsDomNode.style.width = `${width - 4}px`; + console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + // TODO Experimentation done for finding the maximum current size to give to the resizable element const containerOffsetHeight = this._hover.containerDomNode.offsetHeight; @@ -697,12 +710,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._initialHeight = this._element.domNode.clientHeight; } - // Client height and scroll height should not be the same so that the scroll bar is needed - this._hover.contentsDomNode.style.height = `${height - 4}px`; - this._hover.contentsDomNode.style.width = `${width - 4}px`; - console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); - this._hover.scrollbar.scanDomNode(); console.log('this._element.domNode : ', this._element.domNode); @@ -848,8 +855,19 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: Set a better default, this is causing small initial sizes console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); - const defaultMaxHeight = Math.min(150, this._hover.contentsDomNode.offsetHeight); - const defaultMaxWidth = Math.min(300, this._hover.contentsDomNode.offsetWidth); + console.log('this._hover.containerDomNode.clientHeight : ', this._hover.containerDomNode.clientHeight); + console.log('this._hover.containerDomNode.clientWidth : ', this._hover.containerDomNode.clientWidth); + let height; + let width; + if (this._initialTop === -1) { + height = this._hover.containerDomNode.offsetHeight; + width = this._hover.containerDomNode.offsetWidth; + } else { + height = this._hover.containerDomNode.offsetHeight + 4; + width = this._hover.containerDomNode.offsetWidth + 2; // not sure why adding only 2 + } + const defaultMaxHeight = Math.min(150, height); + const defaultMaxWidth = Math.min(300, width); const defaultSize = new dom.Dimension(defaultMaxWidth, defaultMaxHeight); this._setLayoutOfResizableElement(defaultSize); } From 1ef04a3223480a5a5f733f3fed10bd7a72532b96 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 13 Mar 2023 16:29:35 +0100 Subject: [PATCH 14/95] work in progress --- src/vs/base/browser/ui/resizable/resizable.ts | 4 +- .../contrib/hover/browser/contentHover.ts | 99 ++++++++++++++----- 2 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/vs/base/browser/ui/resizable/resizable.ts b/src/vs/base/browser/ui/resizable/resizable.ts index 5c2d4a0c434c5..c9178f48679f1 100644 --- a/src/vs/base/browser/ui/resizable/resizable.ts +++ b/src/vs/base/browser/ui/resizable/resizable.ts @@ -137,7 +137,9 @@ export class ResizableHTMLElement { const { height: minHeight, width: minWidth } = this._minSize; const { height: maxHeight, width: maxWidth } = this._maxSize; - + console.log('Inside of the layout function of ResizableHTMLElement'); + console.log('minHeight: ' + minHeight + ' minWidth: ' + minWidth + ' maxHeight: ' + maxHeight + ' maxWidth: ' + maxWidth); + console.log('height: ' + height + ' width: ' + width); height = Math.max(minHeight, Math.min(maxHeight, height)); width = Math.max(minWidth, Math.min(maxWidth, width)); diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 70df190efaaaa..052fb4e5e5b22 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -430,7 +430,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // private readonly _hoverCopy: HoverWidget = this._register(new HoverWidget()); // Adding a resizable element directly to the content hover widget - private readonly _element: ResizableHTMLElement = new ResizableHTMLElement(); + private readonly _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); // The mouse position in the editor is needed in order to calculate the space above and below it private _mousePosition: IPosition | null = null; private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); @@ -515,9 +515,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: 3) Do correct calculations of maximum height above and below in order to decide which sashes to enable + // TODO: 3) Find out why sometimes when resizing the element now jumps, should not jump! + // TODO: - What happens when the resizing is so large it disappears? ADD MAXIMUM SIZE ON THE CONTENT HOVER // TODO: 4) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size + // TODO: 6) Find why the content hover widget changes as hover mouse is moved, ever so slight movement + // TODO: 7) find why sashes go over board with somewhat longer sashes than should be console.log('* Entered into _resizableLayout of ContentHoverWidget'); console.log('defaultSize : ', defaultSize); @@ -575,7 +578,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); console.log('maxHeightAbove : ', maxHeightAbove); // We find the maximum height of the widget possible on the top or on the bottom - let maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); + const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); console.log('maxHeight : ', maxHeight); if (height < minHeight) { @@ -599,8 +602,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const eastSash = true; const northSash = height <= maxHeightAbove; const southSash = height > maxHeightAbove; - - maxHeight = height <= maxHeightAbove ? maxHeightAbove : maxHeightBelow; this._renderingAbove = height <= maxHeightAbove; console.log('this._renderingAbove : ', this._renderingAbove); this._element.enableSashes(northSash, eastSash, southSash, westSash); @@ -612,16 +613,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const northSash = height > maxHeightBelow; const southSash = height <= maxHeightBelow; - maxHeight = height <= maxHeightBelow ? maxHeightBelow : maxHeightAbove; this._renderingAbove = height > maxHeightBelow; console.log('this._renderingAbove : ', this._renderingAbove); this._element.enableSashes(northSash, eastSash, southSash, westSash); } // TODO: Place the following line in order to use the calculated max width and max height - this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); + // this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 this._element.minSize = new dom.Dimension(10, minHeight); + const maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + if (!maxRenderingHeight) { + return; + } + this._element.maxSize = new dom.Dimension(maxWidth, maxRenderingHeight); this._resize(width, height, this._renderingAbove); @@ -637,6 +642,34 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } + private _findMaxRenderingHeight(renderingAbove: boolean): number | undefined { + if (!this._mousePosition || !this._editor || !this._editor.hasModel()) { + return; + } + const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; + const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); + const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); + const bodyBox = dom.getClientArea(document.body); + // Different to availableSpaceAbove because we want to remove the tabs and breadcrumbs, since the content hover disappears as soon as below the tabs or breadcrumbs + const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top; + const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; + const availableSpaceBelow = bodyBox.height - mouseBottom; + + let maxRenderingHeight; + if (preferRenderingAbove) { + maxRenderingHeight = renderingAbove ? availableSpaceAboveMinusTabsAndBreadcrumbs : availableSpaceBelow; + } else { + maxRenderingHeight = renderingAbove ? availableSpaceBelow : availableSpaceAboveMinusTabsAndBreadcrumbs; + } + + let actualMaxHeight = 0; + for (const childHtmlElement of this._hover.contentsDomNode.children) { + actualMaxHeight += childHtmlElement.clientHeight; + } + maxRenderingHeight = Math.min(maxRenderingHeight, actualMaxHeight); + return maxRenderingHeight; + } + private _resize(width: number, height: number, renderingAbove: boolean): void { console.log(' * Entered into the _resize function of ContentHoverWidget'); @@ -647,21 +680,24 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Suppose that this is not the first time the resize is called after the initial rendering and we are rendering above // Then update the top position of the widget if (this._initialHeight !== -1 && renderingAbove) { + console.log('Entered into case when initial height !== -1'); const diff = height - this._initialHeight; + console.log('diff : ', diff); // When difference positive, means that the widget grew, place it higher up + console.log('this._initialTop - diff : ', this._initialTop - diff); this._element.domNode.style.top = this._initialTop - diff + 'px'; } const { width: maxWidth, height: maxHeight } = this._element.maxSize; - console.log('maxWidth : ', maxWidth, ' width : ', width); + // console.log('maxWidth : ', maxWidth, ' width : ', width); width = Math.min(maxWidth, width); - console.log('maxHeight : ', maxHeight, ' height : ', height); + // console.log('maxHeight : ', maxHeight, ' height : ', height); height = Math.min(maxHeight, height); // Setting the size of the resizable element with the height and width given this._element.layout(height, width); - console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); - console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); + // console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); + // console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); // Making the hover container dom node have height and width of the resizable element minus the pixels needed in order to show the sashes this._hover.containerDomNode.style.height = `${height - 4}px`; @@ -669,32 +705,32 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Client height and scroll height should not be the same so that the scroll bar is needed this._hover.contentsDomNode.style.height = `${height - 4}px`; this._hover.contentsDomNode.style.width = `${width - 4}px`; - console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + // console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + // console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); // TODO Experimentation done for finding the maximum current size to give to the resizable element const containerOffsetHeight = this._hover.containerDomNode.offsetHeight; const contentsOffsetHeight = this._hover.contentsDomNode.offsetHeight; - console.log('this._hover.containerDomNode.offsetWidth : ', this._hover.containerDomNode.offsetWidth); - console.log('this._hover.containerDomNode.offsetHeight : ', containerOffsetHeight); - console.log('this._hover.contentsDomNode.offsetWidth : ', this._hover.contentsDomNode.offsetWidth); - console.log('this._hover.contentsDomNode.offsetHeight : ', contentsOffsetHeight); + // console.log('this._hover.containerDomNode.offsetWidth : ', this._hover.containerDomNode.offsetWidth); + // console.log('this._hover.containerDomNode.offsetHeight : ', containerOffsetHeight); + // console.log('this._hover.contentsDomNode.offsetWidth : ', this._hover.contentsDomNode.offsetWidth); + // console.log('this._hover.contentsDomNode.offsetHeight : ', contentsOffsetHeight); const maxResizableWidth = this._hover.contentsDomNode.offsetWidth; const maxResizableHeight = this._hover.contentsDomNode.offsetHeight; const currentMaxSize = new dom.Dimension(maxResizableWidth, maxResizableHeight); - console.log('currentMaxSize : ', currentMaxSize); + // console.log('currentMaxSize : ', currentMaxSize); // this._element.maxSize = currentMaxSize; // Find when to make the scroll-bar visible if (containerOffsetHeight < contentsOffsetHeight) { // make scrollbar visible? - console.log('container height offset smaller than contents height offset'); + // console.log('container height offset smaller than contents height offset'); } - console.log('this._element.domNode.style.maxWidth : ', this._element.domNode.style.maxWidth); - console.log('this._element.domNode.style.maxHeight : ', this._element.domNode.style.maxHeight); + // console.log('this._element.domNode.style.maxWidth : ', this._element.domNode.style.maxWidth); + // console.log('this._element.domNode.style.maxHeight : ', this._element.domNode.style.maxHeight); // If the initial top and height values have not been updated yet, update them the first time the content is rendered if (this._initialTop === -1) { @@ -708,10 +744,25 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); this._initialTop = this._element.domNode.offsetTop + 4; this._initialHeight = this._element.domNode.clientHeight; + // TODO: The problem is that the offset top is not correctly set! Hence the jumping of the dom node + // console.log('this._element.domNode.getClientRects() : ', this._element.domNode.getClientRects()[0].top); + console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); + console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); + console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); + console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); + console.log('this._hover.containerDomNode.style.top : ', this._hover.containerDomNode.style.top); + console.log('this._initialTop : ', this._initialTop); + console.log('this._initialHeight ; ', this._initialHeight); } this._hover.scrollbar.scanDomNode(); - console.log('this._element.domNode : ', this._element.domNode); + + const maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + if (!maxRenderingHeight) { + return; + } + this._element.maxSize = new dom.Dimension(maxWidth, maxRenderingHeight); + // console.log('this._element.domNode : ', this._element.domNode); // this._hoverCopy.scrollbar.scanDomNode(); // console.log('this._hover.scrollbar : ', this._hover.scrollbar); @@ -798,6 +849,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._visibleData = visibleData; this._hoverVisibleKey.set(!!this._visibleData); this._hover.containerDomNode.classList.toggle('hidden', !this._visibleData); + // Also need to set the element dom node to hidden when hidden + this._element.domNode.classList.toggle('hidden', !this._visibleData); } private _layout(): void { @@ -873,6 +926,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public hide(): void { + console.log('calling hide'); + this._element.enableSashes(false, false, false, false); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); From a3173d5dbd80cd1310731df9b05ec465755f695e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 13 Mar 2023 17:55:06 +0100 Subject: [PATCH 15/95] changed the code so that the maximu size is rspected for a given width --- .../contrib/hover/browser/contentHover.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 052fb4e5e5b22..c93617aaba846 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -433,6 +433,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); // The mouse position in the editor is needed in order to calculate the space above and below it private _mousePosition: IPosition | null = null; + private _initialMousePosition: IPosition | null = null; private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); // When the content hover is rendered, the following two variables store the initial position from the top and the initial height private _initialTop: number = -1; @@ -623,6 +624,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 this._element.minSize = new dom.Dimension(10, minHeight); const maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + console.log('maxRenderingHeight : ', maxRenderingHeight); if (!maxRenderingHeight) { return; } @@ -643,12 +645,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } private _findMaxRenderingHeight(renderingAbove: boolean): number | undefined { - if (!this._mousePosition || !this._editor || !this._editor.hasModel()) { + if (!this._initialMousePosition || !this._editor || !this._editor.hasModel()) { return; } const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); + console.log('this._mousePosition : ', this._mousePosition); + const mouseBox = this._editor.getScrolledVisiblePosition(this._initialMousePosition); const bodyBox = dom.getClientArea(document.body); // Different to availableSpaceAbove because we want to remove the tabs and breadcrumbs, since the content hover disappears as soon as below the tabs or breadcrumbs const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top; @@ -661,11 +664,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } else { maxRenderingHeight = renderingAbove ? availableSpaceBelow : availableSpaceAboveMinusTabsAndBreadcrumbs; } - + console.log('maxRenderingHeight : ', maxRenderingHeight); let actualMaxHeight = 0; for (const childHtmlElement of this._hover.contentsDomNode.children) { actualMaxHeight += childHtmlElement.clientHeight; } + console.log('actualMaxHeight : ', actualMaxHeight); maxRenderingHeight = Math.min(maxRenderingHeight, actualMaxHeight); return maxRenderingHeight; } @@ -758,6 +762,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.scrollbar.scanDomNode(); const maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + console.log('maxRenderingHeight : ', maxRenderingHeight); if (!maxRenderingHeight) { return; } @@ -879,6 +884,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._hover.containerDomNode.style.maxHeight = '150px'; // this._hover.containerDomNode.style.maxWidth = '300px'; + // Setting the initial mouse position + if (!this._initialMousePosition) { + this._initialMousePosition = this._mousePosition; + } + console.log(' * Entered into showAt of ContentHoverWidget'); console.log('visibleData : ', visibleData); @@ -940,6 +950,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // resetting the distance to the top from the hover this._initialTop = -1; this._initialHeight = -1; + this._initialMousePosition = null; } public onContentsChanged(): void { From be2790e4d160a8ee1701df91a12328540f2d3337 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 13 Mar 2023 18:05:09 +0100 Subject: [PATCH 16/95] Removing 4 instead of 2 make the sashes not overflow --- src/vs/editor/contrib/hover/browser/contentHover.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index c93617aaba846..e4dbe61d6a4b2 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -517,8 +517,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed // TODO: 3) Find out why sometimes when resizing the element now jumps, should not jump! - // TODO: - What happens when the resizing is so large it disappears? ADD MAXIMUM SIZE ON THE CONTENT HOVER - // TODO: 4) Do not let infinite resizing, set a maximum resize size which depends on the current maximum size you can show // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size // TODO: 6) Find why the content hover widget changes as hover mouse is moved, ever so slight movement // TODO: 7) find why sashes go over board with somewhat longer sashes than should be @@ -670,7 +668,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { actualMaxHeight += childHtmlElement.clientHeight; } console.log('actualMaxHeight : ', actualMaxHeight); - maxRenderingHeight = Math.min(maxRenderingHeight, actualMaxHeight); + maxRenderingHeight = Math.min(maxRenderingHeight, actualMaxHeight + 2); return maxRenderingHeight; } @@ -704,11 +702,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); // Making the hover container dom node have height and width of the resizable element minus the pixels needed in order to show the sashes - this._hover.containerDomNode.style.height = `${height - 4}px`; - this._hover.containerDomNode.style.width = `${width - 4}px`; + this._hover.containerDomNode.style.height = `${height - 2}px`; + this._hover.containerDomNode.style.width = `${width - 2}px`; // Client height and scroll height should not be the same so that the scroll bar is needed - this._hover.contentsDomNode.style.height = `${height - 4}px`; - this._hover.contentsDomNode.style.width = `${width - 4}px`; + this._hover.contentsDomNode.style.height = `${height - 2}px`; + this._hover.contentsDomNode.style.width = `${width - 2}px`; // console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); // console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); From 1e79b872e31df1b1d07382dd032d1fce0df74152 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 09:40:55 +0100 Subject: [PATCH 17/95] Added code in order to reposition the content hover widget without explicitly calculating the height --- .../editor/browser/widget/codeEditorWidget.ts | 1 + .../contrib/hover/browser/contentHover.ts | 82 +++++++++++++++---- .../contrib/hover/browser/hoverOperation.ts | 4 + 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 93c7923c14be5..50dc5e676e561 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1431,6 +1431,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } public addContentWidget(widget: editorBrowser.IContentWidget): void { + // Data correspoding to the widget which is added const widgetData: IContentWidgetData = { widget: widget, position: widget.getPosition() diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e4dbe61d6a4b2..81e24ec3a83e0 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -154,6 +154,7 @@ export class ContentHoverController extends Disposable { if (!anchor.canAdoptVisibleHover(this._currentResult.anchor, this._widget.position)) { // The new anchor is not compatible with the previous anchor this._setCurrentResult(null); + // TODO: Save the height and top after the hover operation has completed this._startHoverOperationIfNecessary(anchor, mode, source, focus, false); return true; } @@ -161,6 +162,7 @@ export class ContentHoverController extends Disposable { // We aren't getting any closer to the hover, so we will filter existing results // and keep those which also apply to the new anchor. this._setCurrentResult(this._currentResult.filter(anchor)); + // TODO: Save the height and top after the hover operation has completed this._startHoverOperationIfNecessary(anchor, mode, source, focus, false); return true; } @@ -179,7 +181,7 @@ export class ContentHoverController extends Disposable { this._hoverOperation.start(mode); } - private _setCurrentResult(hoverResult: HoverResult | null): void { + private _setCurrentResult(hoverResult: HoverResult | null, initialRender: boolean = false): void { if (this._currentResult === hoverResult) { // avoid updating the DOM to avoid resetting the user selection return; @@ -189,7 +191,7 @@ export class ContentHoverController extends Disposable { } this._currentResult = hoverResult; if (this._currentResult) { - this._renderMessages(this._currentResult.anchor, this._currentResult.messages); + this._renderMessages(this._currentResult.anchor, this._currentResult.messages, initialRender); } else { this._widget.hide(); } @@ -245,11 +247,12 @@ export class ContentHoverController extends Disposable { return; } } - - this._setCurrentResult(hoverResult); + const initialRender = true; + this._setCurrentResult(hoverResult, initialRender); } - private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { + // Everything which is rendered + private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[], initialRender: boolean = false): void { const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); @@ -289,8 +292,7 @@ export class ContentHoverController extends Disposable { highlightDecoration.clear(); })); } - - this._widget.showAt(fragment, new ContentHoverVisibleData( + const visibleData = new ContentHoverVisibleData( colorPicker, showAtPosition, showAtSecondaryPosition, @@ -301,7 +303,29 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosX, anchor.initialMousePosY, disposables - )); + ); + this._widget.showAt(fragment, visibleData); + + console.log('After showAt, this._widget.element.domNode : ', this._widget.element.domNode); + console.log('visibleData : ', visibleData); + if (initialRender) { + // Need to change the code so that we know when the hover has finished rendering + console.log('When initialRender is true inside of _renderMessage'); + const offsetTop = this._widget.element.domNode.offsetTop + 2; + const clientTop = this._widget.element.domNode.clientTop + 2; + const styleTop = this._widget.element.domNode.style.top; + const scrollTop = this._widget.element.domNode.scrollTop; + const height = this._widget.element.domNode.clientHeight; + console.log('offsetTop : ', offsetTop); + console.log('clientTop : ', clientTop); + console.log('styleTop : ', styleTop); + console.log('scrollTop : ', scrollTop); + console.log('height : ', height); + // TODO: Removed this._initialTop = this._element.domNode.offsetTop + 2; + // TODO: Removed this._initialHeight = this._element.domNode.clientHeight; + this._widget.initialTop = offsetTop; + this._widget.initialHeight = height; + } } else { disposables.dispose(); } @@ -442,6 +466,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; + public get element(): ResizableHTMLElement { + return this._element; + } + + public set initialTop(top: number) { + this._initialTop = top; + } + + public set initialHeight(height: number) { + this._initialHeight = height; + } + /** * Returns `null` if the hover is not visible. */ @@ -516,10 +552,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: 3) Find out why sometimes when resizing the element now jumps, should not jump! + // TODO: 3) Find out why sometimes when resizing the element now jumps, should not jump! The top offset should be correctly saved // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size // TODO: 6) Find why the content hover widget changes as hover mouse is moved, ever so slight movement - // TODO: 7) find why sashes go over board with somewhat longer sashes than should be console.log('* Entered into _resizableLayout of ContentHoverWidget'); console.log('defaultSize : ', defaultSize); @@ -676,6 +711,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log(' * Entered into the _resize function of ContentHoverWidget'); + console.log('width : ', width); + console.log('height : ', height); console.log('this._initialHeight : ', this._initialHeight); console.log('this._initialTop : ', this._initialTop); @@ -683,11 +720,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Then update the top position of the widget if (this._initialHeight !== -1 && renderingAbove) { console.log('Entered into case when initial height !== -1'); + console.log('this._initialTop : ', this._initialTop); const diff = height - this._initialHeight; console.log('diff : ', diff); // When difference positive, means that the widget grew, place it higher up console.log('this._initialTop - diff : ', this._initialTop - diff); - this._element.domNode.style.top = this._initialTop - diff + 'px'; + // this._element.domNode.style.top = this._initialTop - diff + 'px'; } const { width: maxWidth, height: maxHeight } = this._element.maxSize; @@ -710,6 +748,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); // console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + // Also setting the size of the resizable element to that size? // TODO Experimentation done for finding the maximum current size to give to the resizable element const containerOffsetHeight = this._hover.containerDomNode.offsetHeight; @@ -744,15 +783,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // console.log('this._element.domNode.clientHeight : ', this._element.domNode.clientHeight); // console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); // console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); - this._initialTop = this._element.domNode.offsetTop + 4; - this._initialHeight = this._element.domNode.clientHeight; + // TODO: This height initially found is NOT correct! + + // TODO: Removed this._initialTop = this._element.domNode.offsetTop + 2; + // TODO: Removed this._initialHeight = this._element.domNode.clientHeight; + // TODO: The problem is that the offset top is not correctly set! Hence the jumping of the dom node // console.log('this._element.domNode.getClientRects() : ', this._element.domNode.getClientRects()[0].top); + console.log('Entered into the case when this._initialTop === -1'); console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); console.log('this._hover.containerDomNode.style.top : ', this._hover.containerDomNode.style.top); + console.log('this._hover.contentsDomNode.style.top : ', this._hover.contentsDomNode.style.top); console.log('this._initialTop : ', this._initialTop); console.log('this._initialHeight ; ', this._initialHeight); } @@ -765,6 +809,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return; } this._element.maxSize = new dom.Dimension(maxWidth, maxRenderingHeight); + this._editor.layoutContentWidget(this); // console.log('this._element.domNode : ', this._element.domNode); // this._hoverCopy.scrollbar.scanDomNode(); @@ -878,6 +923,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { + // TODO: Maybe should not be here, should the content widget be added? + this._editor.addContentWidget(this); + // Setting maximum so that the hover initially made to respect these conditions // this._hover.containerDomNode.style.maxHeight = '150px'; // this._hover.containerDomNode.style.maxWidth = '300px'; @@ -924,7 +972,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = this._hover.containerDomNode.offsetHeight; width = this._hover.containerDomNode.offsetWidth; } else { - height = this._hover.containerDomNode.offsetHeight + 4; + height = this._hover.containerDomNode.offsetHeight + 2; width = this._hover.containerDomNode.offsetWidth + 2; // not sure why adding only 2 } const defaultMaxHeight = Math.min(150, height); @@ -936,6 +984,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public hide(): void { console.log('calling hide'); this._element.enableSashes(false, false, false, false); + this._element.clearSashHoverState(); + this._editor.removeContentWidget(this); + if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); @@ -1106,7 +1157,8 @@ class ContentHoverComputer implements IHoverComputer { if (!participant.computeAsync) { return AsyncIterableObject.EMPTY; } - return participant.computeAsync(anchor, lineDecorations, token); + const computeAsync = participant.computeAsync(anchor, lineDecorations, token); + return computeAsync; }) ); } diff --git a/src/vs/editor/contrib/hover/browser/hoverOperation.ts b/src/vs/editor/contrib/hover/browser/hoverOperation.ts index 79c56ade663e3..c70908a621392 100644 --- a/src/vs/editor/contrib/hover/browser/hoverOperation.ts +++ b/src/vs/editor/contrib/hover/browser/hoverOperation.ts @@ -111,6 +111,7 @@ export class HoverOperation extends Disposable { } private _triggerAsyncComputation(): void { + console.log('Inside of _triggerAsyncComputation()'); this._setState(HoverOperationState.SecondWait); this._secondWaitScheduler.schedule(this._secondWaitTime); @@ -127,6 +128,7 @@ export class HoverOperation extends Disposable { } } this._asyncIterableDone = true; + // Once everything is finished if (this._state === HoverOperationState.WaitingForAsync || this._state === HoverOperationState.WaitingForAsyncShowingLoading) { this._setState(HoverOperationState.Idle); @@ -143,6 +145,7 @@ export class HoverOperation extends Disposable { } private _triggerSyncComputation(): void { + console.log('Inside of _triggerSyncComputation()'); if (this._computer.computeSync) { this._result = this._result.concat(this._computer.computeSync()); } @@ -165,6 +168,7 @@ export class HoverOperation extends Disposable { this._onResult.fire(new HoverResult(this._result.slice(0), isComplete, hasLoadingMessage)); } + // Starting the hover operation public start(mode: HoverStartMode): void { if (mode === HoverStartMode.Delayed) { if (this._state === HoverOperationState.Idle) { From 8aff3b9666ea7306fc467d76fb60dd05d25ddb4a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 10:02:14 +0100 Subject: [PATCH 18/95] Changed the z-index of the hover --- .../contrib/hover/browser/contentHover.ts | 20 ++++++++++++++----- src/vs/editor/contrib/hover/browser/hover.css | 4 +++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 81e24ec3a83e0..7d4db9142d69b 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -465,6 +465,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Storing the preference of whether we want to render above or below private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; + private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; public get element(): ResizableHTMLElement { return this._element; @@ -527,6 +528,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { })); this._element.domNode.appendChild(this._hover.containerDomNode); + this._element.domNode.className = 'resizable-hover'; // Place also the hover container dom node on top of the resizable element // const boundingBox = this._hover.containerDomNode.getBoundingClientRect(); @@ -638,6 +640,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const southSash = height > maxHeightAbove; this._renderingAbove = height <= maxHeightAbove; console.log('this._renderingAbove : ', this._renderingAbove); + + this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('this._renderingType : ', this._renderingType); this._element.enableSashes(northSash, eastSash, southSash, westSash); } else { @@ -649,6 +654,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._renderingAbove = height > maxHeightBelow; console.log('this._renderingAbove : ', this._renderingAbove); + + this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('this._renderingType : ', this._renderingType); this._element.enableSashes(northSash, eastSash, southSash, westSash); } @@ -843,6 +851,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public getPosition(): IContentWidgetPosition | null { console.log('Inside of getPosition of the ContentHoverWidget'); + console.log('this._renderingType : ', this._renderingType); if (!this._visibleData) { return null; } @@ -858,11 +867,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, - preference: ( - preferAbove - ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] - : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] - ), + preference: [this._renderingType], + // ( + // preferAbove + // ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] + // : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] + // ), positionAffinity: affinity }; } diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 6a82748a59fff..d64c4887a287f 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -29,4 +29,6 @@ background-color: var(--vscode-textCodeBlock-background); } - +.monaco-editor .resizable-hover { + z-index: 10; +} From 57ad53051617a8ba6c2327ac8c7db061e10db970 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 11:36:55 +0100 Subject: [PATCH 19/95] Removing some code in order to remove the blinking --- src/vs/editor/contrib/hover/browser/contentHover.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 7d4db9142d69b..a650def3dd84d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -554,9 +554,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: 3) Find out why sometimes when resizing the element now jumps, should not jump! The top offset should be correctly saved // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size // TODO: 6) Find why the content hover widget changes as hover mouse is moved, ever so slight movement + // TODO: Render the correct initial size + // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size + // TODO: Find out why the content hover widget blinks once in the beginning when hovering above it console.log('* Entered into _resizableLayout of ContentHoverWidget'); console.log('defaultSize : ', defaultSize); @@ -695,7 +697,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const mouseBox = this._editor.getScrolledVisiblePosition(this._initialMousePosition); const bodyBox = dom.getClientArea(document.body); // Different to availableSpaceAbove because we want to remove the tabs and breadcrumbs, since the content hover disappears as soon as below the tabs or breadcrumbs - const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top; + const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top - 4; const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; const availableSpaceBelow = bodyBox.height - mouseBottom; @@ -934,7 +936,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { // TODO: Maybe should not be here, should the content widget be added? - this._editor.addContentWidget(this); + // this._editor.addContentWidget(this); // Setting maximum so that the hover initially made to respect these conditions // this._hover.containerDomNode.style.maxHeight = '150px'; @@ -995,7 +997,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('calling hide'); this._element.enableSashes(false, false, false, false); this._element.clearSashHoverState(); - this._editor.removeContentWidget(this); + // this._editor.removeContentWidget(this); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; From 92f4f4db28d4026af78e95144fcddfa8ee72eb43 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 12:06:24 +0100 Subject: [PATCH 20/95] Disabling the vertical sashes when the hover can not be resized anyway, it is not useful in that case --- .../contrib/hover/browser/contentHover.ts | 154 +++++++----------- 1 file changed, 56 insertions(+), 98 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a650def3dd84d..b130a3d6e5f25 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -466,6 +466,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; + private _maxRenderingHeight: number | undefined = -1; public get element(): ResizableHTMLElement { return this._element; @@ -551,17 +552,16 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // Only called once, define here a default size - private _setLayoutOfResizableElement(defaultSize: dom.Dimension): void { + private _setLayoutOfResizableElement(maxSize: dom.Dimension): void { // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size - // TODO: 6) Find why the content hover widget changes as hover mouse is moved, ever so slight movement // TODO: Render the correct initial size // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size - // TODO: Find out why the content hover widget blinks once in the beginning when hovering above it + // TODO: Do not enable the sashes when the hover should not be resizable anymore console.log('* Entered into _resizableLayout of ContentHoverWidget'); - console.log('defaultSize : ', defaultSize); + console.log('maxSize : ', maxSize); console.log('this._mousePosition : ', this._mousePosition); console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); @@ -583,9 +583,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Hard-coded in the hover.css file as 1.5em or 24px const minHeight = 24; - console.log('defaultSize : ', defaultSize); - let height = defaultSize.height; - let width = defaultSize.width; + console.log('defaultSize : ', maxSize); + let height = maxSize.height; + let width = maxSize.width; // Hard-code the values for now! const maxWidth = bodyBox.width; @@ -595,7 +595,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // The full height is already passed in as a parameter - const fullHeight = defaultSize.height; + const fullHeight = maxSize.height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); console.log('editorBox : ', editorBox); const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); @@ -666,14 +666,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 this._element.minSize = new dom.Dimension(10, minHeight); - const maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); - console.log('maxRenderingHeight : ', maxRenderingHeight); - if (!maxRenderingHeight) { + this._maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + console.log('maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { return; } - this._element.maxSize = new dom.Dimension(maxWidth, maxRenderingHeight); + this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - this._resize(width, height, this._renderingAbove); + // The last variable is true because it is the initial rendering + this._resize(width, height, true); // TODO: Enable sashes on different places depending on if hover shown on the top or on the bottom // TODO: When the hover is extended too much, so that part of it disappears, it disappears completely @@ -717,7 +718,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return maxRenderingHeight; } - private _resize(width: number, height: number, renderingAbove: boolean): void { + // Initiall height and width are the maximmum dimensions to give to the hover + private _resize(width: number, height: number, initialRedering: boolean = false): void { console.log(' * Entered into the _resize function of ContentHoverWidget'); @@ -726,99 +728,49 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('this._initialHeight : ', this._initialHeight); console.log('this._initialTop : ', this._initialTop); - // Suppose that this is not the first time the resize is called after the initial rendering and we are rendering above - // Then update the top position of the widget - if (this._initialHeight !== -1 && renderingAbove) { - console.log('Entered into case when initial height !== -1'); - console.log('this._initialTop : ', this._initialTop); - const diff = height - this._initialHeight; - console.log('diff : ', diff); - // When difference positive, means that the widget grew, place it higher up - console.log('this._initialTop - diff : ', this._initialTop - diff); - // this._element.domNode.style.top = this._initialTop - diff + 'px'; - } - const { width: maxWidth, height: maxHeight } = this._element.maxSize; - // console.log('maxWidth : ', maxWidth, ' width : ', width); + + // TODO: When the following is added, it causes errors yet we want the initial hover widget to not inherit the size from before + /* + let maxWidth: number; + let maxHeight: number; + if (initialRedering) { + console.log('Entered into the initial rendering inside of the resize function'); + this._hover.contentsDomNode.style.maxHeight = height + 'px'; + this._hover.containerDomNode.style.maxWidth = width + 'px'; + this._hover.contentsDomNode.style.maxHeight = height + 'px'; + this._hover.contentsDomNode.style.maxWidth = width + 'px'; + const bodyBox = dom.getClientArea(document.body); + maxWidth = bodyBox.width; + } else { + */ + const maxWidth = this._element.maxSize.width; + const maxHeight = this._element.maxSize.height; width = Math.min(maxWidth, width); - // console.log('maxHeight : ', maxHeight, ' height : ', height); height = Math.min(maxHeight, height); - - // Setting the size of the resizable element with the height and width given + console.log('height : ', height); + console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { + return; + } + if (height >= this._maxRenderingHeight) { + this._element.enableSashes(false, true, false, false); + } this._element.layout(height, width); - // console.log('this._element.domNode.style.height : ', this._element.domNode.style.height); - // console.log('this._element.domNode.style.width : ', this._element.domNode.style.width); - - // Making the hover container dom node have height and width of the resizable element minus the pixels needed in order to show the sashes this._hover.containerDomNode.style.height = `${height - 2}px`; this._hover.containerDomNode.style.width = `${width - 2}px`; - // Client height and scroll height should not be the same so that the scroll bar is needed this._hover.contentsDomNode.style.height = `${height - 2}px`; this._hover.contentsDomNode.style.width = `${width - 2}px`; - // console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - // console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); - - // Also setting the size of the resizable element to that size? - - // TODO Experimentation done for finding the maximum current size to give to the resizable element - const containerOffsetHeight = this._hover.containerDomNode.offsetHeight; - const contentsOffsetHeight = this._hover.contentsDomNode.offsetHeight; - // console.log('this._hover.containerDomNode.offsetWidth : ', this._hover.containerDomNode.offsetWidth); - // console.log('this._hover.containerDomNode.offsetHeight : ', containerOffsetHeight); - // console.log('this._hover.contentsDomNode.offsetWidth : ', this._hover.contentsDomNode.offsetWidth); - // console.log('this._hover.contentsDomNode.offsetHeight : ', contentsOffsetHeight); - - const maxResizableWidth = this._hover.contentsDomNode.offsetWidth; - const maxResizableHeight = this._hover.contentsDomNode.offsetHeight; - const currentMaxSize = new dom.Dimension(maxResizableWidth, maxResizableHeight); - // console.log('currentMaxSize : ', currentMaxSize); - // this._element.maxSize = currentMaxSize; - - // Find when to make the scroll-bar visible - if (containerOffsetHeight < contentsOffsetHeight) { - // make scrollbar visible? - // console.log('container height offset smaller than contents height offset'); - } - - // console.log('this._element.domNode.style.maxWidth : ', this._element.domNode.style.maxWidth); - // console.log('this._element.domNode.style.maxHeight : ', this._element.domNode.style.maxHeight); - - // If the initial top and height values have not been updated yet, update them the first time the content is rendered - if (this._initialTop === -1) { - // console.log('Entered into update of initial top'); - // console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); - // console.log('this._element.domNode.style : ', this._element.domNode.style); - // console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); - // console.log('this._element.domNode.style[0] : ', this._element.domNode.style[0]); - // console.log('this._element.domNode.clientHeight : ', this._element.domNode.clientHeight); - // console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); - // console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); - // TODO: This height initially found is NOT correct! - - // TODO: Removed this._initialTop = this._element.domNode.offsetTop + 2; - // TODO: Removed this._initialHeight = this._element.domNode.clientHeight; - - // TODO: The problem is that the offset top is not correctly set! Hence the jumping of the dom node - // console.log('this._element.domNode.getClientRects() : ', this._element.domNode.getClientRects()[0].top); - console.log('Entered into the case when this._initialTop === -1'); - console.log('this._element.domNode.style.top : ', this._element.domNode.style.top); - console.log('this._element.domNode.offsetTop : ', this._element.domNode.offsetTop); - console.log('this._element.domNode.clientTop : ', this._element.domNode.clientTop); - console.log('this._element.domNode.scrollTop : ', this._element.domNode.scrollTop); - console.log('this._hover.containerDomNode.style.top : ', this._hover.containerDomNode.style.top); - console.log('this._hover.contentsDomNode.style.top : ', this._hover.contentsDomNode.style.top); - console.log('this._initialTop : ', this._initialTop); - console.log('this._initialHeight ; ', this._initialHeight); - } + // } this._hover.scrollbar.scanDomNode(); - const maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); - console.log('maxRenderingHeight : ', maxRenderingHeight); - if (!maxRenderingHeight) { + this._maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + console.log('maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { return; } - this._element.maxSize = new dom.Dimension(maxWidth, maxRenderingHeight); + this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); this._editor.layoutContentWidget(this); // console.log('this._element.domNode : ', this._element.domNode); @@ -987,10 +939,16 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = this._hover.containerDomNode.offsetHeight + 2; width = this._hover.containerDomNode.offsetWidth + 2; // not sure why adding only 2 } - const defaultMaxHeight = Math.min(150, height); - const defaultMaxWidth = Math.min(300, width); - const defaultSize = new dom.Dimension(defaultMaxWidth, defaultMaxHeight); - this._setLayoutOfResizableElement(defaultSize); + console.log('height : ', height); + console.log('width : ', width); + + // const defaultMaxHeight = Math.min(150, height); + const maxHeight = 150; + // const defaultMaxWidth = Math.min(300, width); + const maxWidth = 300; + // const defaultSize = new dom.Dimension(defaultMaxWidth, defaultMaxHeight); + const maxSize = new dom.Dimension(maxWidth, maxHeight); + this._setLayoutOfResizableElement(maxSize); } public hide(): void { From 277f85392d5100ad52f6b474c98c499c0c3cd752 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 13:57:20 +0100 Subject: [PATCH 21/95] Adding code in order to initially render the layout when first shown in order to adapt the height and width to that --- .../contrib/hover/browser/contentHover.ts | 77 +++++++++++++------ 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index b130a3d6e5f25..e2e01ccafd8ac 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -731,37 +731,70 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: When the following is added, it causes errors yet we want the initial hover widget to not inherit the size from before - /* + let maxWidth: number; let maxHeight: number; if (initialRedering) { - console.log('Entered into the initial rendering inside of the resize function'); - this._hover.contentsDomNode.style.maxHeight = height + 'px'; + console.log('* Entered into the initial rendering inside of the resize function'); + + this._hover.containerDomNode.style.height = 'auto'; + this._hover.containerDomNode.style.width = 'auto'; + this._hover.contentsDomNode.style.height = 'auto'; + this._hover.contentsDomNode.style.width = 'auto'; + + this._hover.containerDomNode.style.maxHeight = height + 'px'; this._hover.containerDomNode.style.maxWidth = width + 'px'; this._hover.contentsDomNode.style.maxHeight = height + 'px'; this._hover.contentsDomNode.style.maxWidth = width + 'px'; const bodyBox = dom.getClientArea(document.body); + // Do the layout once + this._editor.layoutContentWidget(this); + + const heightAfterRender = this._hover.containerDomNode.offsetHeight; + const widthAfterRender = this._hover.containerDomNode.offsetWidth; + console.log('heightAfterRender : ', heightAfterRender); + console.log('widthAfterRender : ', widthAfterRender); + + this._hover.containerDomNode.style.height = heightAfterRender + 'px'; + this._hover.containerDomNode.style.width = widthAfterRender + 'px'; + this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; + this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; + + this._hover.containerDomNode.style.maxHeight = 'none'; + this._hover.containerDomNode.style.maxWidth = 'none'; + this._hover.contentsDomNode.style.maxHeight = 'none'; + this._hover.contentsDomNode.style.maxWidth = 'none'; + + this._element.layout(heightAfterRender + 2, widthAfterRender + 2); + maxWidth = bodyBox.width; + + console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); } else { - */ - const maxWidth = this._element.maxSize.width; - const maxHeight = this._element.maxSize.height; - width = Math.min(maxWidth, width); - height = Math.min(maxHeight, height); - console.log('height : ', height); - console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { - return; - } - if (height >= this._maxRenderingHeight) { - this._element.enableSashes(false, true, false, false); + this._hover.containerDomNode.style.maxHeight = 'none'; + this._hover.containerDomNode.style.maxWidth = 'none'; + this._hover.contentsDomNode.style.maxHeight = 'none'; + this._hover.contentsDomNode.style.maxWidth = 'none'; + + maxWidth = this._element.maxSize.width; + maxHeight = this._element.maxSize.height; + width = Math.min(maxWidth, width); + height = Math.min(maxHeight, height); + console.log('height : ', height); + console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { + return; + } + // TODO: the following should be tweaked so that the sashes are still there for making it smaller but, it should not be possible to resize when the maxRenderingHeight is the minimal value of 18 cm + if (height >= this._maxRenderingHeight) { + this._element.enableSashes(false, true, false, false); + } + this._element.layout(height, width); + this._hover.containerDomNode.style.height = `${height - 2}px`; + this._hover.containerDomNode.style.width = `${width - 2}px`; + this._hover.contentsDomNode.style.height = `${height - 2}px`; + this._hover.contentsDomNode.style.width = `${width - 2}px`; } - this._element.layout(height, width); - this._hover.containerDomNode.style.height = `${height - 2}px`; - this._hover.containerDomNode.style.width = `${width - 2}px`; - this._hover.contentsDomNode.style.height = `${height - 2}px`; - this._hover.contentsDomNode.style.width = `${width - 2}px`; - // } this._hover.scrollbar.scanDomNode(); @@ -772,8 +805,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); this._editor.layoutContentWidget(this); - // console.log('this._element.domNode : ', this._element.domNode); + // console.log('this._element.domNode : ', this._element.domNode); // this._hoverCopy.scrollbar.scanDomNode(); // console.log('this._hover.scrollbar : ', this._hover.scrollbar); // Adding code for hover copy!! From 66f9d1628ac5ee9994f19eba54fc0fff5467c768 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 14:44:19 +0100 Subject: [PATCH 22/95] Adding code in order to assign different heights and widths to the hover widgets --- .../contrib/hover/browser/contentHover.ts | 184 ++++++++++-------- 1 file changed, 105 insertions(+), 79 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e2e01ccafd8ac..0204714889e45 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -547,24 +547,24 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); - this._resize(e.dimension.width, e.dimension.height, this._renderingAbove); + this._resize(e.dimension.width, e.dimension.height); })); } - // Only called once, define here a default size - private _setLayoutOfResizableElement(maxSize: dom.Dimension): void { + // TODO: Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed + // TODO: Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size + // TODO: Render the correct initial size + // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size + // TODO: Do not enable the sashes when the hover should not be resizable anymore - // TODO: 1) Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: 5) Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size - // TODO: Render the correct initial size - // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size - // TODO: Do not enable the sashes when the hover should not be resizable anymore + // Only called once, define here a default size + private _setLayoutOfResizableElement(): void { // maxSize: dom.Dimension - console.log('* Entered into _resizableLayout of ContentHoverWidget'); - console.log('maxSize : ', maxSize); - console.log('this._mousePosition : ', this._mousePosition); - console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); - console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); + console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); + // console.log('maxSize : ', maxSize); + // console.log('this._mousePosition : ', this._mousePosition); + // console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); + // console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); if (!this._editor.hasModel()) { return; @@ -576,6 +576,36 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return; } + // The hover container dom node height and width are initial automatically determined by the browser before being changed + this._hover.containerDomNode.style.height = 'auto'; + this._hover.containerDomNode.style.width = 'auto'; + this._hover.contentsDomNode.style.height = 'auto'; + this._hover.contentsDomNode.style.width = 'auto'; + + // this._hover.containerDomNode.style.maxHeight = height + 'px'; + // this._hover.containerDomNode.style.maxWidth = width + 'px'; + // this._hover.contentsDomNode.style.maxHeight = height + 'px'; + // this._hover.contentsDomNode.style.maxWidth = width + 'px'; + this._editor.layoutContentWidget(this); + + let height = this._hover.containerDomNode.offsetHeight; + let width = this._hover.containerDomNode.offsetWidth; + console.log('height : ', height); + console.log('width : ', width); + + // this._hover.containerDomNode.style.height = heightAfterRender + 'px'; + // this._hover.containerDomNode.style.width = widthAfterRender + 'px'; + // this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; + // this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; + + // this._hover.containerDomNode.style.maxHeight = 'none'; + // this._hover.containerDomNode.style.maxWidth = 'none'; + // this._hover.contentsDomNode.style.maxHeight = 'none'; + // this._hover.contentsDomNode.style.maxWidth = 'none'; + // this._element.layout(heightAfterRender + 2, widthAfterRender + 2); + + console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); + // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); console.log('bodyBox : ', bodyBox); @@ -583,9 +613,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Hard-coded in the hover.css file as 1.5em or 24px const minHeight = 24; - console.log('defaultSize : ', maxSize); - let height = maxSize.height; - let width = maxSize.width; + // console.log('defaultSize : ', maxSize); + // let height = maxSize.height; + // let width = maxSize.width; // Hard-code the values for now! const maxWidth = bodyBox.width; @@ -595,7 +625,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // The full height is already passed in as a parameter - const fullHeight = maxSize.height; + const fullHeight = height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); console.log('editorBox : ', editorBox); const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); @@ -610,7 +640,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); console.log('maxHeightBelow : ', maxHeightBelow); // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor - const availableSpaceAbove = mouseBox.top + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs + const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs console.log('availableSpaceAbove : ', availableSpaceAbove); // Max height above is the minimum of the available space above and the full height of the widget const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); @@ -666,7 +696,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 this._element.minSize = new dom.Dimension(10, minHeight); - this._maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + this._maxRenderingHeight = this._findMaxRenderingHeight(); console.log('maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight) { return; @@ -674,21 +704,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); // The last variable is true because it is the initial rendering - this._resize(width, height, true); - - // TODO: Enable sashes on different places depending on if hover shown on the top or on the bottom - // TODO: When the hover is extended too much, so that part of it disappears, it disappears completely - // TODO: Eastern sash disappears when the hover is too small? or after extending too much? - - // The below works!! - // this._element.enableSashes(true, true, false, false); - // const height = size ? size.height : 200; - // const width = size ? size.width : 200; - // this._resize(width, height); - + // this._resize(width, height, true); + console.log('height : ', height); + console.log('width : ', width); + this._element.layout(height, width); + this._hover.containerDomNode.style.height = `${height - 2}px`; + this._hover.containerDomNode.style.width = `${width - 2}px`; + this._hover.contentsDomNode.style.height = `${height - 2}px`; + this._hover.contentsDomNode.style.width = `${width - 2}px`; + this._hover.scrollbar.scanDomNode(); + console.log('Before layoutContentWidget'); + this._editor.layoutContentWidget(this); } - private _findMaxRenderingHeight(renderingAbove: boolean): number | undefined { + private _findMaxRenderingHeight(): number | undefined { if (!this._initialMousePosition || !this._editor || !this._editor.hasModel()) { return; } @@ -704,9 +733,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let maxRenderingHeight; if (preferRenderingAbove) { - maxRenderingHeight = renderingAbove ? availableSpaceAboveMinusTabsAndBreadcrumbs : availableSpaceBelow; + maxRenderingHeight = this._renderingAbove ? availableSpaceAboveMinusTabsAndBreadcrumbs : availableSpaceBelow; } else { - maxRenderingHeight = renderingAbove ? availableSpaceBelow : availableSpaceAboveMinusTabsAndBreadcrumbs; + maxRenderingHeight = this._renderingAbove ? availableSpaceBelow : availableSpaceAboveMinusTabsAndBreadcrumbs; } console.log('maxRenderingHeight : ', maxRenderingHeight); let actualMaxHeight = 0; @@ -719,21 +748,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // Initiall height and width are the maximmum dimensions to give to the hover - private _resize(width: number, height: number, initialRedering: boolean = false): void { + private _resize(width: number, height: number): void { console.log(' * Entered into the _resize function of ContentHoverWidget'); console.log('width : ', width); console.log('height : ', height); - console.log('this._initialHeight : ', this._initialHeight); - console.log('this._initialTop : ', this._initialTop); - - - // TODO: When the following is added, it causes errors yet we want the initial hover widget to not inherit the size from before - - let maxWidth: number; - let maxHeight: number; + /* if (initialRedering) { console.log('* Entered into the initial rendering inside of the resize function'); @@ -771,34 +793,36 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); } else { - this._hover.containerDomNode.style.maxHeight = 'none'; - this._hover.containerDomNode.style.maxWidth = 'none'; - this._hover.contentsDomNode.style.maxHeight = 'none'; - this._hover.contentsDomNode.style.maxWidth = 'none'; + */ - maxWidth = this._element.maxSize.width; - maxHeight = this._element.maxSize.height; - width = Math.min(maxWidth, width); - height = Math.min(maxHeight, height); - console.log('height : ', height); - console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { - return; - } - // TODO: the following should be tweaked so that the sashes are still there for making it smaller but, it should not be possible to resize when the maxRenderingHeight is the minimal value of 18 cm - if (height >= this._maxRenderingHeight) { - this._element.enableSashes(false, true, false, false); - } - this._element.layout(height, width); - this._hover.containerDomNode.style.height = `${height - 2}px`; - this._hover.containerDomNode.style.width = `${width - 2}px`; - this._hover.contentsDomNode.style.height = `${height - 2}px`; - this._hover.contentsDomNode.style.width = `${width - 2}px`; + this._hover.containerDomNode.style.maxHeight = 'none'; + this._hover.containerDomNode.style.maxWidth = 'none'; + this._hover.contentsDomNode.style.maxHeight = 'none'; + this._hover.contentsDomNode.style.maxWidth = 'none'; + + const maxWidth = this._element.maxSize.width; + const maxHeight = this._element.maxSize.height; + width = Math.min(maxWidth, width); + height = Math.min(maxHeight, height); + console.log('height : ', height); + console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { + return; } + // TODO: the following should be tweaked so that the sashes are still there for making it smaller but, it should not be possible to resize when the maxRenderingHeight is the minimal value of 18 cm + // if (height >= this._maxRenderingHeight) { + // this._element.enableSashes(false, true, false, false); + // } + this._element.layout(height, width); + this._hover.containerDomNode.style.height = `${height - 2}px`; + this._hover.containerDomNode.style.width = `${width - 2}px`; + this._hover.contentsDomNode.style.height = `${height - 2}px`; + this._hover.contentsDomNode.style.width = `${width - 2}px`; + this._hover.scrollbar.scanDomNode(); - this._maxRenderingHeight = this._findMaxRenderingHeight(this._renderingAbove); + this._maxRenderingHeight = this._findMaxRenderingHeight(); console.log('maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight) { return; @@ -957,12 +981,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } visibleData.colorPicker?.layout(); - // Only called once, when the widget is first shown - // TODO: Set a better default, this is causing small initial sizes - console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); - console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); - console.log('this._hover.containerDomNode.clientHeight : ', this._hover.containerDomNode.clientHeight); - console.log('this._hover.containerDomNode.clientWidth : ', this._hover.containerDomNode.clientWidth); + // console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); + // console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); + // console.log('this._hover.containerDomNode.clientHeight : ', this._hover.containerDomNode.clientHeight); + // console.log('this._hover.containerDomNode.clientWidth : ', this._hover.containerDomNode.clientWidth); + /* let height; let width; if (this._initialTop === -1) { @@ -972,16 +995,19 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = this._hover.containerDomNode.offsetHeight + 2; width = this._hover.containerDomNode.offsetWidth + 2; // not sure why adding only 2 } - console.log('height : ', height); - console.log('width : ', width); - + */ + // console.log('height : ', height); + // console.log('width : ', width); // const defaultMaxHeight = Math.min(150, height); - const maxHeight = 150; // const defaultMaxWidth = Math.min(300, width); - const maxWidth = 300; // const defaultSize = new dom.Dimension(defaultMaxWidth, defaultMaxHeight); - const maxSize = new dom.Dimension(maxWidth, maxHeight); - this._setLayoutOfResizableElement(maxSize); + + // We specify the maximum size to which to cap the hover. But do we need to do that? If not capped it will achieve some default size + // const maxHeight = 150; + // const maxWidth = 300; + // const maxSize = new dom.Dimension(maxWidth, maxHeight); + // this._setLayoutOfResizableElement(maxSize); + this._setLayoutOfResizableElement(); } public hide(): void { From 535e3b4d5a225af9d5d6d092cff17f9faf6cdb3a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 15:01:34 +0100 Subject: [PATCH 23/95] Cleaning the code --- src/vs/base/browser/fastDomNode.ts | 4 - src/vs/base/browser/ui/hover/hover.css | 2 +- src/vs/base/browser/ui/hover/hoverWidget.ts | 4 - src/vs/base/browser/ui/resizable/resizable.ts | 7 +- .../browser/ui/scrollbar/abstractScrollbar.ts | 7 - .../ui/scrollbar/horizontalScrollbar.ts | 1 - .../browser/ui/scrollbar/scrollableElement.ts | 44 +--- .../browser/ui/scrollbar/scrollbarState.ts | 7 - .../scrollbarVisibilityController.ts | 49 +--- .../browser/ui/scrollbar/verticalScrollbar.ts | 1 - src/vs/base/common/scrollable.ts | 2 - .../editor/browser/widget/codeEditorWidget.ts | 1 - .../contrib/hover/browser/contentHover.ts | 233 ++---------------- .../contrib/hover/browser/hoverOperation.ts | 4 - 14 files changed, 27 insertions(+), 339 deletions(-) diff --git a/src/vs/base/browser/fastDomNode.ts b/src/vs/base/browser/fastDomNode.ts index 3e304729defe7..1ef17e48cd5d4 100644 --- a/src/vs/base/browser/fastDomNode.ts +++ b/src/vs/base/browser/fastDomNode.ts @@ -214,11 +214,7 @@ export class FastDomNode { } public setClassName(className: string): void { - // console.log('Inside of setClassName'); - // console.log('this._className : ', this._className); - // console.log('className : ', className); if (this._className === className) { - // console.log('Early return'); return; } this._className = className; diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 20c73b8332707..57a366d59e840 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -8,8 +8,8 @@ position: absolute; overflow: hidden; z-index: 50; - user-select: text; -webkit-user-select: text; + user-select: text; box-sizing: initial; animation: fadein 100ms linear; line-height: 1.5em; diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index 5c1cf095c0a12..96e99cbec4a2f 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -18,10 +18,6 @@ export const enum HoverPosition { export class HoverWidget extends Disposable { - // Do we need the maximum height and the maximum width - public maxHeight = 0; - public maxWidth = 0; - public readonly containerDomNode: HTMLElement; public readonly contentsDomNode: HTMLElement; public readonly scrollbar: DomScrollableElement; diff --git a/src/vs/base/browser/ui/resizable/resizable.ts b/src/vs/base/browser/ui/resizable/resizable.ts index c9178f48679f1..95dfb06b8d007 100644 --- a/src/vs/base/browser/ui/resizable/resizable.ts +++ b/src/vs/base/browser/ui/resizable/resizable.ts @@ -137,17 +137,12 @@ export class ResizableHTMLElement { const { height: minHeight, width: minWidth } = this._minSize; const { height: maxHeight, width: maxWidth } = this._maxSize; - console.log('Inside of the layout function of ResizableHTMLElement'); - console.log('minHeight: ' + minHeight + ' minWidth: ' + minWidth + ' maxHeight: ' + maxHeight + ' maxWidth: ' + maxWidth); - console.log('height: ' + height + ' width: ' + width); + height = Math.max(minHeight, Math.min(maxHeight, height)); width = Math.max(minWidth, Math.min(maxWidth, width)); const newSize = new Dimension(width, height); - - // We layout of the resize element is changed only when it is different to the size before if (!Dimension.equals(newSize, this._size)) { - // console.log('Inside of the if statement of the layout function of ResizableHTMLElement'); this.domNode.style.height = height + 'px'; this.domNode.style.width = width + 'px'; this._size = newSize; diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index 88ef2bcc9adc9..5ab75393d9e64 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -64,7 +64,6 @@ export abstract class AbstractScrollbar extends Widget { this._scrollByPage = opts.scrollByPage; this._scrollbarState = opts.scrollbarState; this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName)); - // console.log('In the constructor of AbstractScrollbar'); this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); this._shouldRender = true; @@ -79,9 +78,6 @@ export abstract class AbstractScrollbar extends Widget { } // ----------------- creation - get visibilityController() { - return this._visibilityController; - } /** * Creates the dom node for an arrow & adds it to the container @@ -133,7 +129,6 @@ export abstract class AbstractScrollbar extends Widget { // ----------------- Update state protected _onElementSize(visibleSize: number): boolean { - // console.log('Inside of _onElementSize'); if (this._scrollbarState.setVisibleSize(visibleSize)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; @@ -145,7 +140,6 @@ export abstract class AbstractScrollbar extends Widget { } protected _onElementScrollSize(elementScrollSize: number): boolean { - // console.log('Inside of _onElementScrollSize'); if (this._scrollbarState.setScrollSize(elementScrollSize)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; @@ -157,7 +151,6 @@ export abstract class AbstractScrollbar extends Widget { } protected _onElementScrollPosition(elementScrollPosition: number): boolean { - // console.log('Inside of _onElementScrollPosition'); if (this._scrollbarState.setScrollPosition(elementScrollPosition)) { this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded()); this._shouldRender = true; diff --git a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts index 4c8cdd697454e..9672118552d07 100644 --- a/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts @@ -108,7 +108,6 @@ export class HorizontalScrollbar extends AbstractScrollbar { } public updateOptions(options: ScrollableElementResolvedOptions): void { - // console.log('Inside of updateOptions of HorizontalScrollbar'); this.updateScrollbarSize(options.horizontal === ScrollbarVisibility.Hidden ? 0 : options.horizontalScrollbarSize); this._scrollbarState.setOppositeScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); this._visibilityController.setVisibility(options.horizontal); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 003cfbd867f08..87d4ed4d9fa38 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -337,7 +337,6 @@ export abstract class AbstractScrollableElement extends Widget { this._verticalScrollbar.updateOptions(this._options); if (!this._options.lazyRender) { - // console.log('Inside of updateOptions of AbstractScrollableElement'); this._render(); } } @@ -466,10 +465,8 @@ export abstract class AbstractScrollableElement extends Widget { } private _onDidScroll(e: ScrollEvent): void { - // console.log('Inside of _onDidScroll'); this._shouldRender = this._horizontalScrollbar.onDidScroll(e) || this._shouldRender; this._shouldRender = this._verticalScrollbar.onDidScroll(e) || this._shouldRender; - // console.log('this._shouldRender: ', this._shouldRender); if (this._options.useShadows) { this._shouldRender = true; @@ -492,21 +489,18 @@ export abstract class AbstractScrollableElement extends Widget { if (!this._options.lazyRender) { throw new Error('Please use `lazyRender` together with `renderNow`!'); } - // console.log('Inside of renderNow of AbstractScrollableElement'); + this._render(); } private _render(): void { - // console.log('** Inside of _render of AbstractScrollableElement'); if (!this._shouldRender) { return; } this._shouldRender = false; - // console.log('Before rendering of horizontal scroll bar'); this._horizontalScrollbar.render(); - // console.log('Before rendering of the vertical scroll bar'); this._verticalScrollbar.render(); if (this._options.useShadows) { @@ -531,51 +525,27 @@ export abstract class AbstractScrollableElement extends Widget { } private _onDragEnd(): void { - // console.log('Inside of _onDragEnd of AbstractScrollableElement'); this._isDragging = false; this._hide(); } private _onMouseLeave(e: IMouseEvent): void { - // console.log('** _onMouseLeave inside of AbstractScrollableElement'); this._mouseIsOver = false; this._hide(); } private _onMouseOver(e: IMouseEvent): void { - // console.log(' ** _onMouseOver inside of AbstractScrollableElement'); this._mouseIsOver = true; this._reveal(); } private _reveal(): void { - // console.log('** Inside of _reveal of AbstractScrollableElement'); - // console.log('Begin reveal for vertical scroll-bar'); this._verticalScrollbar.beginReveal(); - /* - console.log('this._verticalScrollBar.visibilityController.shouldBeVisible : ', this._verticalScrollbar.visibilityController.shouldBeVisible); - console.log('this._verticalScrollBar.visibilityController.isVisible ', this._verticalScrollbar.visibilityController.isVisible); - console.log('this._verticalScrollBar.visibilityController.visibility ', this._verticalScrollbar.visibilityController.visibility); - console.log('this._verticalScrollBar.visibilityController.visibileClassName ', this._verticalScrollbar.visibilityController.visibileClassName); - console.log('this._verticalScrollBar.visibilityController.invisibileClassName ', this._verticalScrollbar.visibilityController.invisibleClassName); - console.log('this._verticalScrollbar.domNode.domNode.className : ', this._verticalScrollbar.domNode.domNode.className); - console.log('Begin reveal for horizontal scroll-bar'); - */ this._horizontalScrollbar.beginReveal(); - /* - console.log('this._horizontalScrollBar : ', this._horizontalScrollbar); - console.log('this._horizontalScrollbar.visibilityController.shouldBeVisible : ', this._horizontalScrollbar.visibilityController.shouldBeVisible); - console.log('this._horizontalScrollbar.visibilityController.isVisible ', this._horizontalScrollbar.visibilityController.isVisible); - console.log('this._horizontalScrollbar.visibilityController.visibility ', this._horizontalScrollbar.visibilityController.visibility); - console.log('this._horizontalScrollbar.visibilityController.visibileClassName ', this._horizontalScrollbar.visibilityController.visibileClassName); - console.log('this._horizontalScrollbar.visibilityController.invisibileClassName ', this._horizontalScrollbar.visibilityController.invisibleClassName); - console.log('this._verticalScrollbar.domNode.domNode.className ', this._verticalScrollbar.domNode.domNode.className); - */ this._scheduleHide(); } private _hide(): void { - // console.log(' ** Inside of _hide of AbstractScrollableElement'); if (!this._mouseIsOver && !this._isDragging) { this._verticalScrollbar.beginHide(); this._horizontalScrollbar.beginHide(); @@ -583,14 +553,8 @@ export abstract class AbstractScrollableElement extends Widget { } private _scheduleHide(): void { - // console.log('Inside of _scheduleHide'); - // console.log('this._mouseIsOver : ', this._mouseIsOver); - // console.log('this._isDragging : ', this._isDragging); if (!this._mouseIsOver && !this._isDragging) { - this._hideTimeout.cancelAndSet(() => { - // console.log('Hiding because of the timeout'); - this._hide(); - }, HIDE_TIMEOUT); + this._hideTimeout.cancelAndSet(() => this._hide(), HIDE_TIMEOUT); } } } @@ -652,7 +616,6 @@ export class DomScrollableElement extends AbstractScrollableElement { }); super(element, options, scrollable); this._register(scrollable); - // Element is set once this._element = element; this.onScroll((e) => { if (e.scrollTopChanged) { @@ -675,9 +638,6 @@ export class DomScrollableElement extends AbstractScrollableElement { public scanDomNode(): void { // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight - // console.log('Inside of scanDomNode'); - // console.log('this._element.clientHeight : ', this._element.clientHeight); - // console.log('this._element.scrollHeight : ', this._element.scrollHeight); this.setScrollDimensions({ width: this._element.clientWidth, scrollWidth: this._element.scrollWidth, diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts index 4277ecf412ea2..9a4f4e2cbbdcc 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarState.ts @@ -84,7 +84,6 @@ export class ScrollbarState { return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition); } - // Here you can set the visible size of the scroll bar public setVisibleSize(visibleSize: number): boolean { const iVisibleSize = Math.round(visibleSize); if (this._visibleSize !== iVisibleSize) { @@ -95,7 +94,6 @@ export class ScrollbarState { return false; } - // You can also set the scroll size, or the possible height of the scrolling public setScrollSize(scrollSize: number): boolean { const iScrollSize = Math.round(scrollSize); if (this._scrollSize !== iScrollSize) { @@ -125,11 +123,8 @@ export class ScrollbarState { } private static _computeValues(oppositeScrollbarSize: number, arrowSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) { - // console.log('Inside of _computeValues of ScrollbarState'); const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize); const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize); - // console.log('visibleSize : ', visibleSize); - // console.log('scrollSize : ', scrollSize); const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize); if (!computedIsNeeded) { @@ -161,7 +156,6 @@ export class ScrollbarState { } private _refreshComputedValues(): void { - // Updating the fact whether we need the scroll bar ot not const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition); this._computedAvailableSize = r.computedAvailableSize; this._computedIsNeeded = r.computedIsNeeded; @@ -187,7 +181,6 @@ export class ScrollbarState { } public isNeeded(): boolean { - // console.log('Inside of isNeeded of the ScrollbarState'); return this._computedIsNeeded; } diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts index cd247093e0cfa..791c7332ffb16 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts @@ -32,29 +32,7 @@ export class ScrollbarVisibilityController extends Disposable { this._revealTimer = this._register(new TimeoutTimer()); } - get shouldBeVisible(): boolean { - return this._shouldBeVisible; - } - - get isVisible(): boolean { - return this._isVisible; - } - - get visibility() { - return this._visibility; - } - - get visibileClassName(): string { - return this._visibleClassName; - } - - get invisibleClassName(): string { - return this._invisibleClassName; - } - public setVisibility(visibility: ScrollbarVisibility): void { - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('Inside of setVisibility'); if (this._visibility !== visibility) { this._visibility = visibility; this._updateShouldBeVisible(); @@ -64,9 +42,6 @@ export class ScrollbarVisibilityController extends Disposable { // ----------------- Hide / Reveal public setShouldBeVisible(rawShouldBeVisible: boolean): void { - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('Inside of setShouldBeVisible of ScrollbarVisibilityController'); - // console.log('rawShouldBeVisible: ', rawShouldBeVisible); this._rawShouldBeVisible = rawShouldBeVisible; this._updateShouldBeVisible(); } @@ -83,10 +58,7 @@ export class ScrollbarVisibilityController extends Disposable { private _updateShouldBeVisible(): void { const shouldBeVisible = this._applyVisibilitySetting(); - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('Inside of _updateShouldBeVisible of ScrollbarVisibilityController'); - // console.log('this._shouldBeVisible: ', this._shouldBeVisible); - // console.log('shouldBeVisible: ', shouldBeVisible); + if (this._shouldBeVisible !== shouldBeVisible) { this._shouldBeVisible = shouldBeVisible; this.ensureVisibility(); @@ -102,7 +74,6 @@ export class ScrollbarVisibilityController extends Disposable { public setDomNode(domNode: FastDomNode): void { this._domNode = domNode; - // console.log('Inside of setDomNode of ScrollbarVisibilityController'); this._domNode.setClassName(this._invisibleClassName); // Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration @@ -110,54 +81,38 @@ export class ScrollbarVisibilityController extends Disposable { } public ensureVisibility(): void { - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('Inside of ensureVisibility of ScrollbarVisibilityController'); + if (!this._isNeeded) { // Nothing to be rendered - // console.log('is not neeeded'); this._hide(false); return; } if (this._shouldBeVisible) { - // console.log('revealing'); this._reveal(); } else { - // console.log('hiding'); this._hide(true); } } private _reveal(): void { - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('Inside of _reveal of ScrollbarVisibilityController'); if (this._isVisible) { - // console.log('Early return because visible'); return; } this._isVisible = true; // The CSS animation doesn't play otherwise - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('set the visible class name'); - // console.log('this._visibleClassName : ', this._visibleClassName); this._revealTimer.setIfNotSet(() => { this._domNode?.setClassName(this._visibleClassName); }, 0); - // this._domNode?.setClassName(this._visibleClassName); - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); } private _hide(withFadeAway: boolean): void { - // console.log('this._domNode?.domNode.className: ', this._domNode?.domNode.className); - // console.log('Inside of _hide of ScrollbarVisibilityController'); this._revealTimer.cancel(); if (!this._isVisible) { - // console.log('Early return because not visible'); return; } this._isVisible = false; - // console.log('set the invisible class name'); this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : '')); } } diff --git a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts index 9b0414de5d75b..89078e6b8d414 100644 --- a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts @@ -18,7 +18,6 @@ export class VerticalScrollbar extends AbstractScrollbar { constructor(scrollable: Scrollable, options: ScrollableElementResolvedOptions, host: ScrollbarHost) { const scrollDimensions = scrollable.getScrollDimensions(); const scrollPosition = scrollable.getCurrentScrollPosition(); - // TODO; It would appear that the scroll dimensions height and scroll height are the same while they should not be the same super({ lazyRender: options.lazyRender, host: host, diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 9151afda75cf1..1be0752c3fd40 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -239,7 +239,6 @@ export class Scrollable extends Disposable { this._smoothScrollDuration = options.smoothScrollDuration; this._scheduleAtNextAnimationFrame = options.scheduleAtNextAnimationFrame; - // Initially the scroll state height and scroll height are zero this._state = new ScrollState(options.forceIntegerValues, 0, 0, 0, 0, 0, 0); this._smoothScrolling = null; } @@ -264,7 +263,6 @@ export class Scrollable extends Disposable { return this._state; } - // Can set the scroll dimensions or the height and the scroll height public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void { const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions); this._setState(newState, Boolean(this._smoothScrolling)); diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 50dc5e676e561..93c7923c14be5 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1431,7 +1431,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } public addContentWidget(widget: editorBrowser.IContentWidget): void { - // Data correspoding to the widget which is added const widgetData: IContentWidgetData = { widget: widget, position: widget.getPosition() diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 0204714889e45..8204fb7a887f9 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -11,7 +11,7 @@ import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IContentWidgetPosition, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions'; -import { IPosition, Position } from 'vs/editor/common/core/position'; +import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IModelDecoration, PositionAffinity } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; @@ -154,7 +154,6 @@ export class ContentHoverController extends Disposable { if (!anchor.canAdoptVisibleHover(this._currentResult.anchor, this._widget.position)) { // The new anchor is not compatible with the previous anchor this._setCurrentResult(null); - // TODO: Save the height and top after the hover operation has completed this._startHoverOperationIfNecessary(anchor, mode, source, focus, false); return true; } @@ -162,7 +161,6 @@ export class ContentHoverController extends Disposable { // We aren't getting any closer to the hover, so we will filter existing results // and keep those which also apply to the new anchor. this._setCurrentResult(this._currentResult.filter(anchor)); - // TODO: Save the height and top after the hover operation has completed this._startHoverOperationIfNecessary(anchor, mode, source, focus, false); return true; } @@ -181,7 +179,7 @@ export class ContentHoverController extends Disposable { this._hoverOperation.start(mode); } - private _setCurrentResult(hoverResult: HoverResult | null, initialRender: boolean = false): void { + private _setCurrentResult(hoverResult: HoverResult | null): void { if (this._currentResult === hoverResult) { // avoid updating the DOM to avoid resetting the user selection return; @@ -191,7 +189,7 @@ export class ContentHoverController extends Disposable { } this._currentResult = hoverResult; if (this._currentResult) { - this._renderMessages(this._currentResult.anchor, this._currentResult.messages, initialRender); + this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { this._widget.hide(); } @@ -247,12 +245,11 @@ export class ContentHoverController extends Disposable { return; } } - const initialRender = true; - this._setCurrentResult(hoverResult, initialRender); + + this._setCurrentResult(hoverResult); } - // Everything which is rendered - private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[], initialRender: boolean = false): void { + private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); @@ -292,7 +289,8 @@ export class ContentHoverController extends Disposable { highlightDecoration.clear(); })); } - const visibleData = new ContentHoverVisibleData( + + this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, showAtPosition, showAtSecondaryPosition, @@ -303,29 +301,7 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosX, anchor.initialMousePosY, disposables - ); - this._widget.showAt(fragment, visibleData); - - console.log('After showAt, this._widget.element.domNode : ', this._widget.element.domNode); - console.log('visibleData : ', visibleData); - if (initialRender) { - // Need to change the code so that we know when the hover has finished rendering - console.log('When initialRender is true inside of _renderMessage'); - const offsetTop = this._widget.element.domNode.offsetTop + 2; - const clientTop = this._widget.element.domNode.clientTop + 2; - const styleTop = this._widget.element.domNode.style.top; - const scrollTop = this._widget.element.domNode.scrollTop; - const height = this._widget.element.domNode.clientHeight; - console.log('offsetTop : ', offsetTop); - console.log('clientTop : ', clientTop); - console.log('styleTop : ', styleTop); - console.log('scrollTop : ', scrollTop); - console.log('height : ', height); - // TODO: Removed this._initialTop = this._element.domNode.offsetTop + 2; - // TODO: Removed this._initialHeight = this._element.domNode.clientHeight; - this._widget.initialTop = offsetTop; - this._widget.initialHeight = height; - } + )); } else { disposables.dispose(); } @@ -451,18 +427,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); - // private readonly _hoverCopy: HoverWidget = this._register(new HoverWidget()); - - // Adding a resizable element directly to the content hover widget - private readonly _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); - // The mouse position in the editor is needed in order to calculate the space above and below it - private _mousePosition: IPosition | null = null; - private _initialMousePosition: IPosition | null = null; private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - // When the content hover is rendered, the following two variables store the initial position from the top and the initial height - private _initialTop: number = -1; - private _initialHeight: number = -1; - // Storing the preference of whether we want to render above or below + private readonly _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; @@ -472,14 +438,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return this._element; } - public set initialTop(top: number) { - this._initialTop = top; - } - - public set initialHeight(height: number) { - this._initialHeight = height; - } - /** * Returns `null` if the hover is not visible. */ @@ -523,27 +481,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); - // Saving the approximate position of the mouse - this._register(this._editor.onMouseMove(e => { - this._mousePosition = e.target.position; - })); - this._element.domNode.appendChild(this._hover.containerDomNode); this._element.domNode.className = 'resizable-hover'; - // Place also the hover container dom node on top of the resizable element - // const boundingBox = this._hover.containerDomNode.getBoundingClientRect(); - // this._hoverCopy.containerDomNode.style.top = boundingBox.top + 'px'; - // this._hoverCopy.containerDomNode.style.left = boundingBox.left + 'px'; - // this._hoverCopy.containerDomNode.style.width = boundingBox.width + 'px'; - // this._hoverCopy.containerDomNode.style.height = boundingBox.height + 'px'; - // this._hoverCopy.containerDomNode.style.zIndex = '1000'; - // console.log('this_hoverCopy.containerDomNode : ', this._hoverCopy.containerDomNode); - - this._register(this._element.onDidWillResize(() => { - console.log('* Inside of onDidWillResize of ContentHoverWidget'); - })); - // The below is called when the resizable element is reized this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); @@ -557,14 +497,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size // TODO: Do not enable the sashes when the hover should not be resizable anymore - // Only called once, define here a default size private _setLayoutOfResizableElement(): void { // maxSize: dom.Dimension console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); - // console.log('maxSize : ', maxSize); - // console.log('this._mousePosition : ', this._mousePosition); - // console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); - // console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); if (!this._editor.hasModel()) { return; @@ -572,9 +507,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (!this._editor.getDomNode()) { return; } - if (!this._mousePosition) { - return; - } // The hover container dom node height and width are initial automatically determined by the browser before being changed this._hover.containerDomNode.style.height = 'auto'; @@ -613,10 +545,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Hard-coded in the hover.css file as 1.5em or 24px const minHeight = 24; - // console.log('defaultSize : ', maxSize); - // let height = maxSize.height; - // let width = maxSize.width; - // Hard-code the values for now! const maxWidth = bodyBox.width; if (width > maxWidth) { @@ -628,7 +556,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const fullHeight = height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); console.log('editorBox : ', editorBox); - const mouseBox = this._editor.getScrolledVisiblePosition(this._mousePosition); + if (!this._visibleData?.showAtPosition) { + return; + } + const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); console.log('mouseBox : ', mouseBox); // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; @@ -693,8 +624,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // TODO: Place the following line in order to use the calculated max width and max height - // this._element.maxSize = new dom.Dimension(maxWidth, maxHeight); // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 + this._element.minSize = new dom.Dimension(10, minHeight); this._maxRenderingHeight = this._findMaxRenderingHeight(); console.log('maxRenderingHeight : ', this._maxRenderingHeight); @@ -703,8 +634,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - // The last variable is true because it is the initial rendering - // this._resize(width, height, true); console.log('height : ', height); console.log('width : ', width); this._element.layout(height, width); @@ -718,13 +647,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } private _findMaxRenderingHeight(): number | undefined { - if (!this._initialMousePosition || !this._editor || !this._editor.hasModel()) { + if (!this._editor || !this._editor.hasModel()) { return; } const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - console.log('this._mousePosition : ', this._mousePosition); - const mouseBox = this._editor.getScrolledVisiblePosition(this._initialMousePosition); + if (!this._visibleData?.showAtPosition) { + return; + } + const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); const bodyBox = dom.getClientArea(document.body); // Different to availableSpaceAbove because we want to remove the tabs and breadcrumbs, since the content hover disappears as soon as below the tabs or breadcrumbs const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top - 4; @@ -755,46 +686,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('width : ', width); console.log('height : ', height); - /* - if (initialRedering) { - console.log('* Entered into the initial rendering inside of the resize function'); - - this._hover.containerDomNode.style.height = 'auto'; - this._hover.containerDomNode.style.width = 'auto'; - this._hover.contentsDomNode.style.height = 'auto'; - this._hover.contentsDomNode.style.width = 'auto'; - - this._hover.containerDomNode.style.maxHeight = height + 'px'; - this._hover.containerDomNode.style.maxWidth = width + 'px'; - this._hover.contentsDomNode.style.maxHeight = height + 'px'; - this._hover.contentsDomNode.style.maxWidth = width + 'px'; - const bodyBox = dom.getClientArea(document.body); - // Do the layout once - this._editor.layoutContentWidget(this); - - const heightAfterRender = this._hover.containerDomNode.offsetHeight; - const widthAfterRender = this._hover.containerDomNode.offsetWidth; - console.log('heightAfterRender : ', heightAfterRender); - console.log('widthAfterRender : ', widthAfterRender); - - this._hover.containerDomNode.style.height = heightAfterRender + 'px'; - this._hover.containerDomNode.style.width = widthAfterRender + 'px'; - this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; - this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; - - this._hover.containerDomNode.style.maxHeight = 'none'; - this._hover.containerDomNode.style.maxWidth = 'none'; - this._hover.contentsDomNode.style.maxHeight = 'none'; - this._hover.contentsDomNode.style.maxWidth = 'none'; - - this._element.layout(heightAfterRender + 2, widthAfterRender + 2); - - maxWidth = bodyBox.width; - - console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); - } else { - */ - this._hover.containerDomNode.style.maxHeight = 'none'; this._hover.containerDomNode.style.maxWidth = 'none'; this._hover.contentsDomNode.style.maxHeight = 'none'; @@ -819,9 +710,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.height = `${height - 2}px`; this._hover.contentsDomNode.style.width = `${width - 2}px`; - this._hover.scrollbar.scanDomNode(); - this._maxRenderingHeight = this._findMaxRenderingHeight(); console.log('maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight) { @@ -829,17 +718,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); this._editor.layoutContentWidget(this); - - // console.log('this._element.domNode : ', this._element.domNode); - // this._hoverCopy.scrollbar.scanDomNode(); - // console.log('this._hover.scrollbar : ', this._hover.scrollbar); - // Adding code for hover copy!! - // const boundingBox = this._hover.containerDomNode.getBoundingClientRect(); - // this._hoverCopy.containerDomNode.style.top = boundingBox.top + 'px'; - // this._hoverCopy.containerDomNode.style.left = boundingBox.left + 'px'; - // this._hoverCopy.containerDomNode.style.width = boundingBox.width + 'px'; - // this._hoverCopy.containerDomNode.style.height = boundingBox.height + 'px'; - // console.log('this_hoverCopy.containerDomNode : ', this._hoverCopy.containerDomNode); } public override dispose(): void { @@ -855,14 +733,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getDomNode(): HTMLElement { - // return this._hover.containerDomNode; - // Returning instead the resizable element return this._element.domNode; } public getPosition(): IContentWidgetPosition | null { - console.log('Inside of getPosition of the ContentHoverWidget'); - console.log('this._renderingType : ', this._renderingType); if (!this._visibleData) { return null; } @@ -879,11 +753,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, preference: [this._renderingType], - // ( - // preferAbove - // ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] - // : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] - // ), positionAffinity: affinity }; } @@ -918,23 +787,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._visibleData = visibleData; this._hoverVisibleKey.set(!!this._visibleData); this._hover.containerDomNode.classList.toggle('hidden', !this._visibleData); - // Also need to set the element dom node to hidden when hidden this._element.domNode.classList.toggle('hidden', !this._visibleData); } private _layout(): void { - const height = Math.max(this._editor.getLayoutInfo().height / 4, 250); const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo); - this._hover.contentsDomNode.style.fontSize = `${fontSize}px`; this._hover.contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; - // Removing the max width and the max height on the content - // this._hover.contentsDomNode.style.maxHeight = `${height}px`; - // this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; - - // TODO: Do we need this? - this._hover.maxHeight = height; - this._hover.maxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); } private _updateFont(): void { @@ -944,21 +803,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { - // TODO: Maybe should not be here, should the content widget be added? - // this._editor.addContentWidget(this); - - // Setting maximum so that the hover initially made to respect these conditions - // this._hover.containerDomNode.style.maxHeight = '150px'; - // this._hover.containerDomNode.style.maxWidth = '300px'; - - // Setting the initial mouse position - if (!this._initialMousePosition) { - this._initialMousePosition = this._mousePosition; - } - console.log(' * Entered into showAt of ContentHoverWidget'); - console.log('visibleData : ', visibleData); - this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -980,42 +825,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.focus(); } visibleData.colorPicker?.layout(); - - // console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); - // console.log('this._hover.contentsDomNode : ', this._hover.contentsDomNode); - // console.log('this._hover.containerDomNode.clientHeight : ', this._hover.containerDomNode.clientHeight); - // console.log('this._hover.containerDomNode.clientWidth : ', this._hover.containerDomNode.clientWidth); - /* - let height; - let width; - if (this._initialTop === -1) { - height = this._hover.containerDomNode.offsetHeight; - width = this._hover.containerDomNode.offsetWidth; - } else { - height = this._hover.containerDomNode.offsetHeight + 2; - width = this._hover.containerDomNode.offsetWidth + 2; // not sure why adding only 2 - } - */ - // console.log('height : ', height); - // console.log('width : ', width); - // const defaultMaxHeight = Math.min(150, height); - // const defaultMaxWidth = Math.min(300, width); - // const defaultSize = new dom.Dimension(defaultMaxWidth, defaultMaxHeight); - - // We specify the maximum size to which to cap the hover. But do we need to do that? If not capped it will achieve some default size - // const maxHeight = 150; - // const maxWidth = 300; - // const maxSize = new dom.Dimension(maxWidth, maxHeight); - // this._setLayoutOfResizableElement(maxSize); this._setLayoutOfResizableElement(); } public hide(): void { - console.log('calling hide'); this._element.enableSashes(false, false, false, false); this._element.clearSashHoverState(); - // this._editor.removeContentWidget(this); - if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); @@ -1024,11 +839,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.focus(); } } - - // resetting the distance to the top from the hover - this._initialTop = -1; - this._initialHeight = -1; - this._initialMousePosition = null; } public onContentsChanged(): void { @@ -1186,8 +996,7 @@ class ContentHoverComputer implements IHoverComputer { if (!participant.computeAsync) { return AsyncIterableObject.EMPTY; } - const computeAsync = participant.computeAsync(anchor, lineDecorations, token); - return computeAsync; + return participant.computeAsync(anchor, lineDecorations, token); }) ); } diff --git a/src/vs/editor/contrib/hover/browser/hoverOperation.ts b/src/vs/editor/contrib/hover/browser/hoverOperation.ts index c70908a621392..79c56ade663e3 100644 --- a/src/vs/editor/contrib/hover/browser/hoverOperation.ts +++ b/src/vs/editor/contrib/hover/browser/hoverOperation.ts @@ -111,7 +111,6 @@ export class HoverOperation extends Disposable { } private _triggerAsyncComputation(): void { - console.log('Inside of _triggerAsyncComputation()'); this._setState(HoverOperationState.SecondWait); this._secondWaitScheduler.schedule(this._secondWaitTime); @@ -128,7 +127,6 @@ export class HoverOperation extends Disposable { } } this._asyncIterableDone = true; - // Once everything is finished if (this._state === HoverOperationState.WaitingForAsync || this._state === HoverOperationState.WaitingForAsyncShowingLoading) { this._setState(HoverOperationState.Idle); @@ -145,7 +143,6 @@ export class HoverOperation extends Disposable { } private _triggerSyncComputation(): void { - console.log('Inside of _triggerSyncComputation()'); if (this._computer.computeSync) { this._result = this._result.concat(this._computer.computeSync()); } @@ -168,7 +165,6 @@ export class HoverOperation extends Disposable { this._onResult.fire(new HoverResult(this._result.slice(0), isComplete, hasLoadingMessage)); } - // Starting the hover operation public start(mode: HoverStartMode): void { if (mode === HoverStartMode.Delayed) { if (this._state === HoverOperationState.Idle) { From a87c073749beaabc4f2ebfbe5dea28e198efe467 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 15:02:37 +0100 Subject: [PATCH 24/95] Removing a comment --- src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts index 89078e6b8d414..672bde8e01777 100644 --- a/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts @@ -108,7 +108,6 @@ export class VerticalScrollbar extends AbstractScrollbar { } public updateOptions(options: ScrollableElementResolvedOptions): void { - // console.log('Inside of update options of VerticalScrollBar'); this.updateScrollbarSize(options.vertical === ScrollbarVisibility.Hidden ? 0 : options.verticalScrollbarSize); // give priority to vertical scroll bar over horizontal and let it scroll all the way to the bottom this._scrollbarState.setOppositeScrollbarSize(0); From dd42a36a1a178cdfdb5e00bd627ca44f5fdb64eb Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 15:08:06 +0100 Subject: [PATCH 25/95] Changing the order of the code in order to remove error --- src/vs/editor/contrib/hover/browser/contentHover.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 8204fb7a887f9..5cf48072e85ee 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -427,8 +427,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); - private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private readonly _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); + private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; From c8dcf77b372f549bf28808802afb571b4fddbb64 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 15:47:22 +0100 Subject: [PATCH 26/95] Adding comments --- src/vs/editor/contrib/hover/browser/contentHover.ts | 11 +++++++++++ src/vs/editor/contrib/hover/browser/hover.css | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 5cf48072e85ee..d8e3b04ba4b88 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -483,6 +483,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._element.domNode.appendChild(this._hover.containerDomNode); this._element.domNode.className = 'resizable-hover'; + // this._element.domNode.className = 'monaco-hover'; this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); @@ -496,6 +497,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: Render the correct initial size // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size // TODO: Do not enable the sashes when the hover should not be resizable anymore + // TODO: Add horizontal scroll-bar on the resizable element when part of the horizontal text is not visible + // TODO: Have the same hover size as by default, for that generate the initial rendering of the content hover widget private _setLayoutOfResizableElement(): void { // maxSize: dom.Dimension @@ -641,6 +644,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.style.width = `${width - 2}px`; this._hover.contentsDomNode.style.height = `${height - 2}px`; this._hover.contentsDomNode.style.width = `${width - 2}px`; + + console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); + console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); + this._hover.scrollbar.scanDomNode(); console.log('Before layoutContentWidget'); this._editor.layoutContentWidget(this); @@ -846,8 +855,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.onContentsChanged(); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); + console.log('scrollDimensions : ', scrollDimensions); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); if (hasHorizontalScrollbar) { + console.log('Entered into hasHorizontalScrollbar'); // There is just a horizontal scrollbar const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index d64c4887a287f..f69d1975177b4 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -30,5 +30,5 @@ } .monaco-editor .resizable-hover { - z-index: 10; + z-index: 50; } From a477cde8bdbf38db8f1c64b1631a9f644d629486 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 14 Mar 2023 18:24:36 +0100 Subject: [PATCH 27/95] adding a comment for debugging --- src/vs/editor/contrib/hover/browser/contentHover.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d8e3b04ba4b88..56d34030169de 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -523,6 +523,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._hover.contentsDomNode.style.maxWidth = width + 'px'; this._editor.layoutContentWidget(this); + // We want the following to be designed in a similar manner to the initial hover how it was in the main branch in order to give us the default size like initially + console.log('this._element.domNode : ', this._element.domNode); + let height = this._hover.containerDomNode.offsetHeight; let width = this._hover.containerDomNode.offsetWidth; console.log('height : ', height); @@ -653,6 +656,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.scrollbar.scanDomNode(); console.log('Before layoutContentWidget'); this._editor.layoutContentWidget(this); + console.log('this.getDomNode() : ', this.getDomNode()); } private _findMaxRenderingHeight(): number | undefined { From 8bf403fb3e6711c78032e96f8776bff6c23dfdf5 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 Mar 2023 09:41:33 +0100 Subject: [PATCH 28/95] Improvemenet in the sizes, somes sizes remain too small --- .../contrib/hover/browser/contentHover.ts | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 56d34030169de..58dc8975c2aaf 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -427,7 +427,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); - private readonly _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); + private _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _visibleData: ContentHoverVisibleData | null = null; @@ -512,19 +512,47 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // The hover container dom node height and width are initial automatically determined by the browser before being changed - this._hover.containerDomNode.style.height = 'auto'; - this._hover.containerDomNode.style.width = 'auto'; + + const initialMaxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250); + const initialMaxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); + this._hover.contentsDomNode.style.maxHeight = `${initialMaxHeight}px`; + this._hover.contentsDomNode.style.maxWidth = `${initialMaxWidth}px`; + this._hover.containerDomNode.style.maxHeight = `${initialMaxHeight}px`; + this._hover.containerDomNode.style.maxWidth = `${initialMaxWidth}px`; + // this._element.domNode.style.maxHeight = `${initialMaxHeight}px`; + // this._element.domNode.style.maxWidth = `${initialMaxWidth}px`; + // this._element.maxSize = new dom.Dimension(initialMaxWidth, initialMaxHeight); + this._hover.contentsDomNode.style.height = 'auto'; - this._hover.contentsDomNode.style.width = 'auto'; + this._hover.contentsDomNode.style.width = 'max-content'; + this._hover.containerDomNode.style.height = 'auto'; + this._hover.containerDomNode.style.width = 'max-content'; + + // this._element = this._register(new ResizableHTMLElement()); + // this._element.domNode.appendChild(this._hover.containerDomNode); + // this._element.domNode.className = 'resizable-hover'; + // this._element.domNode.style.position = 'fixed'; + // this._element.domNode.style.display = 'block'; + // this._element.domNode.style.visibility = 'inherit'; + + // this._hover.contentsDomNode.style.height = 'auto'; + // this._hover.contentsDomNode.style.width = 'auto'; + // If the following is set it causes errors + // this._element.domNode.style.height = 'auto'; + // this._element.domNode.style.width = 'auto'; // this._hover.containerDomNode.style.maxHeight = height + 'px'; // this._hover.containerDomNode.style.maxWidth = width + 'px'; // this._hover.contentsDomNode.style.maxHeight = height + 'px'; // this._hover.contentsDomNode.style.maxWidth = width + 'px'; + console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); + + // Maybe don't need this? this._editor.layoutContentWidget(this); + this._editor.render(); // We want the following to be designed in a similar manner to the initial hover how it was in the main branch in order to give us the default size like initially - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode after layoutContentWidget: ', this._element.domNode); let height = this._hover.containerDomNode.offsetHeight; let width = this._hover.containerDomNode.offsetWidth; @@ -859,6 +887,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.onContentsChanged(); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); + console.log('Inside of onContentsChanged'); console.log('scrollDimensions : ', scrollDimensions); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); if (hasHorizontalScrollbar) { From 0a400ab9d0f238c7a5bd435e64ccd27514349f21 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 Mar 2023 14:41:31 +0100 Subject: [PATCH 29/95] Save the code --- .../contrib/hover/browser/contentHover.ts | 62 +++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 58dc8975c2aaf..3d7fc8e924265 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -427,10 +427,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _hover: HoverWidget = this._register(new HoverWidget()); + private _visibleData: ContentHoverVisibleData | null = null; private _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; - private _visibleData: ContentHoverVisibleData | null = null; private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; private _maxRenderingHeight: number | undefined = -1; @@ -461,7 +461,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService, ) { + super(); + console.log('Very beginning of constructor'); + console.log('this._element.domNode : ', this._element.domNode); this._register(this._editor.onDidLayoutChange(() => this._layout())); this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => { @@ -472,7 +475,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._setVisibleData(null); this._layout(); - this._editor.addContentWidget(this); this._register(this._focusTracker.onDidFocus(() => { this._hoverFocusedKey.set(true); @@ -483,13 +485,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._element.domNode.appendChild(this._hover.containerDomNode); this._element.domNode.className = 'resizable-hover'; - // this._element.domNode.className = 'monaco-hover'; + this._element.domNode.tabIndex = 0; + this._element.domNode.role = 'tooltip'; this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); this._resize(e.dimension.width, e.dimension.height); })); + + console.log('Before adding the content widget'); + console.log('this._element.domNode : ', this._element.domNode); + this._editor.addContentWidget(this); + console.log('After adding the content widget'); + console.log('this._element.domNode : ', this._element.domNode); } // TODO: Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed @@ -500,9 +509,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: Add horizontal scroll-bar on the resizable element when part of the horizontal text is not visible // TODO: Have the same hover size as by default, for that generate the initial rendering of the content hover widget - private _setLayoutOfResizableElement(): void { // maxSize: dom.Dimension + private _setLayoutOfResizableElement(): void { console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); + console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); if (!this._editor.hasModel()) { return; @@ -523,10 +533,26 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._element.domNode.style.maxWidth = `${initialMaxWidth}px`; // this._element.maxSize = new dom.Dimension(initialMaxWidth, initialMaxHeight); - this._hover.contentsDomNode.style.height = 'auto'; this._hover.contentsDomNode.style.width = 'max-content'; - this._hover.containerDomNode.style.height = 'auto'; + this._hover.contentsDomNode.style.height = 'max-content'; this._hover.containerDomNode.style.width = 'max-content'; + this._hover.containerDomNode.style.height = 'max-content'; + + /* + const contentsHover = this._hover.contentsDomNode; + let maxContentWidth = 0; + for (const childContent of contentsHover.children) { + maxContentWidth = Math.max(maxContentWidth, this._findClientWidthOf(childContent)); + console.log('maxContentWidth : ', maxContentWidth); + maxContentWidth = Math.max(maxContentWidth, childContent.clientWidth); + console.log('maxContentWidth : ', maxContentWidth); + } + console.log('maxContentWidth : ', maxContentWidth); + if (maxContentWidth < initialMaxWidth) { + this._hover.contentsDomNode.style.width = `${maxContentWidth}px`; + this._hover.containerDomNode.style.width = `${maxContentWidth}px`; + } + */ // this._element = this._register(new ResizableHTMLElement()); // this._element.domNode.appendChild(this._hover.containerDomNode); @@ -545,6 +571,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._hover.containerDomNode.style.maxWidth = width + 'px'; // this._hover.contentsDomNode.style.maxHeight = height + 'px'; // this._hover.contentsDomNode.style.maxWidth = width + 'px'; + console.log('Before render'); console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); // Maybe don't need this? @@ -552,10 +579,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.render(); // We want the following to be designed in a similar manner to the initial hover how it was in the main branch in order to give us the default size like initially + console.log('After render'); console.log('this._element.domNode after layoutContentWidget: ', this._element.domNode); let height = this._hover.containerDomNode.offsetHeight; let width = this._hover.containerDomNode.offsetWidth; + console.log('height and width'); console.log('height : ', height); console.log('width : ', width); @@ -671,10 +700,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('height : ', height); console.log('width : ', width); this._element.layout(height, width); - this._hover.containerDomNode.style.height = `${height - 2}px`; - this._hover.containerDomNode.style.width = `${width - 2}px`; - this._hover.contentsDomNode.style.height = `${height - 2}px`; - this._hover.contentsDomNode.style.width = `${width - 2}px`; + this._hover.containerDomNode.style.height = `${height - 2}px`; // height - 2 + this._hover.containerDomNode.style.width = `${width - 2}px`; // width - 2 + this._hover.contentsDomNode.style.height = `${height - 2}px`; // height - 2 + this._hover.contentsDomNode.style.width = `${width - 2}px`; // width - 2 console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); @@ -774,10 +803,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getDomNode(): HTMLElement { + console.log('Inside of getDomNode'); return this._element.domNode; } public getPosition(): IContentWidgetPosition | null { + console.log('Inside of getPosition'); if (!this._visibleData) { return null; } @@ -845,6 +876,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { console.log(' * Entered into showAt of ContentHoverWidget'); + console.log('visibleData : ', visibleData); + console.log('node : ', node); + console.log('this._element.domNode : ', this._element.domNode); + this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -856,11 +891,17 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' + console.log('Before render'); + console.log('this._element.domNode : ', this._element.domNode); this._editor.render(); + console.log('After render'); + console.log('this._element.domNode : ', this._element.domNode); // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor this.onContentsChanged(); + console.log('After onContentsChanged'); + console.log('this._element.domNode : ', this._element.domNode); if (visibleData.stoleFocus) { this._hover.containerDomNode.focus(); @@ -870,7 +911,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public hide(): void { - this._element.enableSashes(false, false, false, false); this._element.clearSashHoverState(); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; From 2bd18c5b17ba3e308e2a76c96ac90129afdd2359 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 Mar 2023 17:24:49 +0100 Subject: [PATCH 30/95] Added code in order to persist the widget sizes inside of the file --- .../contrib/hover/browser/contentHover.ts | 457 +++++++++++------- 1 file changed, 291 insertions(+), 166 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 3d7fc8e924265..b54b6a1cccf41 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -25,13 +25,61 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/sug import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; const $ = dom.$; +class PersistedHoverWidgetSizes { + + private readonly _keyPrefix: string; + + constructor( + // Storing the size of the suggest widget inside of the storage service + private readonly _service: IStorageService, + editor: ICodeEditor + ) { + const textModelURI = editor.getModel()?.uri; + this._keyPrefix = `contentHover.size/${editor.getEditorType()}/${editor instanceof EmbeddedCodeEditorWidget}/${textModelURI}/`; + } + + restore(identifier: object): dom.Dimension | undefined { + const stringifiedIdentifier = JSON.stringify(identifier); + // Retrieving the key from the storage service + const raw = this._service.get(this._keyPrefix + stringifiedIdentifier, StorageScope.PROFILE) ?? ''; + try { + // Parsing the associated value + const obj = JSON.parse(raw); + // Checking if the associated value is of type dimension + if (dom.Dimension.is(obj)) { + return dom.Dimension.lift(obj); + } + } catch { + // ignore + } + return undefined; + } + + // Storing the size so that it can be retrieved later when the suggest widget appears again + store(identifier: object, size: dom.Dimension) { + const stringifiedIdentifier = JSON.stringify(identifier); + this._service.store(this._keyPrefix + stringifiedIdentifier, JSON.stringify(size), StorageScope.PROFILE, StorageTarget.MACHINE); + } + + resetAll() { + const keys = this._service.keys(StorageScope.PROFILE, StorageTarget.MACHINE); + for (const key of keys) { + if (key.includes(this._keyPrefix)) { + this._service.remove(key, StorageScope.PROFILE); + } + } + } +} + export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; - private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + private readonly _widget; private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; @@ -43,7 +91,7 @@ export class ContentHoverController extends Disposable { @IKeybindingService private readonly _keybindingService: IKeybindingService, ) { super(); - + this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -433,6 +481,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; private _maxRenderingHeight: number | undefined = -1; + private readonly _persistedHoverWidgetSizes: PersistedHoverWidgetSizes; public get element(): ResizableHTMLElement { return this._element; @@ -460,6 +509,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @IStorageService private readonly _storageService: IStorageService, ) { super(); @@ -483,15 +533,62 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); + this._persistedHoverWidgetSizes = new PersistedHoverWidgetSizes(this._storageService, this._editor); + this._editor.onDidChangeModel(() => { + this._persistedHoverWidgetSizes.resetAll(); + }); this._element.domNode.appendChild(this._hover.containerDomNode); this._element.domNode.className = 'resizable-hover'; this._element.domNode.tabIndex = 0; this._element.domNode.role = 'tooltip'; + class ResizeState { + constructor( + readonly persistedSize: dom.Dimension | undefined, + readonly currentSize: dom.Dimension, + public persistHeight = false, + public persistWidth = false, + ) { } + } + + let state: ResizeState | undefined; + + this._register(this.element.onDidWillResize(() => { + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); + const tokenIdentifier = { + startColumn: wordPosition?.startColumn, + endColumn: wordPosition?.endColumn, + line: this._visibleData!.showAtPosition.lineNumber + }; + const persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier); + state = new ResizeState(persistedSize, this.element.size); + })); this._register(this._element.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); this._resize(e.dimension.width, e.dimension.height); + + if (state) { + state.persistHeight = state.persistHeight || !!e.north || !!e.south; + state.persistWidth = state.persistWidth || !!e.east || !!e.west; + } + + if (!e.done) { + return; + } + + if (state) { + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); + const tokenIdentifier = { + startColumn: wordPosition?.startColumn, + endColumn: wordPosition?.endColumn, + line: this._visibleData!.showAtPosition.lineNumber + }; + const { width, height } = this.element.size; + const persistedSize = new dom.Dimension(width, height); + this._persistedHoverWidgetSizes.store(tokenIdentifier, persistedSize); + } + state = undefined; })); console.log('Before adding the content widget'); @@ -523,182 +620,207 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // The hover container dom node height and width are initial automatically determined by the browser before being changed - const initialMaxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250); - const initialMaxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); - this._hover.contentsDomNode.style.maxHeight = `${initialMaxHeight}px`; - this._hover.contentsDomNode.style.maxWidth = `${initialMaxWidth}px`; - this._hover.containerDomNode.style.maxHeight = `${initialMaxHeight}px`; - this._hover.containerDomNode.style.maxWidth = `${initialMaxWidth}px`; - // this._element.domNode.style.maxHeight = `${initialMaxHeight}px`; - // this._element.domNode.style.maxWidth = `${initialMaxWidth}px`; - // this._element.maxSize = new dom.Dimension(initialMaxWidth, initialMaxHeight); - - this._hover.contentsDomNode.style.width = 'max-content'; - this._hover.contentsDomNode.style.height = 'max-content'; - this._hover.containerDomNode.style.width = 'max-content'; - this._hover.containerDomNode.style.height = 'max-content'; - - /* - const contentsHover = this._hover.contentsDomNode; - let maxContentWidth = 0; - for (const childContent of contentsHover.children) { - maxContentWidth = Math.max(maxContentWidth, this._findClientWidthOf(childContent)); - console.log('maxContentWidth : ', maxContentWidth); - maxContentWidth = Math.max(maxContentWidth, childContent.clientWidth); - console.log('maxContentWidth : ', maxContentWidth); - } - console.log('maxContentWidth : ', maxContentWidth); - if (maxContentWidth < initialMaxWidth) { - this._hover.contentsDomNode.style.width = `${maxContentWidth}px`; - this._hover.containerDomNode.style.width = `${maxContentWidth}px`; - } - */ - - // this._element = this._register(new ResizableHTMLElement()); - // this._element.domNode.appendChild(this._hover.containerDomNode); - // this._element.domNode.className = 'resizable-hover'; - // this._element.domNode.style.position = 'fixed'; - // this._element.domNode.style.display = 'block'; - // this._element.domNode.style.visibility = 'inherit'; - - // this._hover.contentsDomNode.style.height = 'auto'; - // this._hover.contentsDomNode.style.width = 'auto'; - // If the following is set it causes errors - // this._element.domNode.style.height = 'auto'; - // this._element.domNode.style.width = 'auto'; - - // this._hover.containerDomNode.style.maxHeight = height + 'px'; - // this._hover.containerDomNode.style.maxWidth = width + 'px'; - // this._hover.contentsDomNode.style.maxHeight = height + 'px'; - // this._hover.contentsDomNode.style.maxWidth = width + 'px'; - console.log('Before render'); - console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); - - // Maybe don't need this? - this._editor.layoutContentWidget(this); - this._editor.render(); - - // We want the following to be designed in a similar manner to the initial hover how it was in the main branch in order to give us the default size like initially - console.log('After render'); - console.log('this._element.domNode after layoutContentWidget: ', this._element.domNode); - - let height = this._hover.containerDomNode.offsetHeight; - let width = this._hover.containerDomNode.offsetWidth; - console.log('height and width'); - console.log('height : ', height); - console.log('width : ', width); + let height; + let width; - // this._hover.containerDomNode.style.height = heightAfterRender + 'px'; - // this._hover.containerDomNode.style.width = widthAfterRender + 'px'; - // this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; - // this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; - - // this._hover.containerDomNode.style.maxHeight = 'none'; - // this._hover.containerDomNode.style.maxWidth = 'none'; - // this._hover.contentsDomNode.style.maxHeight = 'none'; - // this._hover.contentsDomNode.style.maxWidth = 'none'; - // this._element.layout(heightAfterRender + 2, widthAfterRender + 2); - - console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); - - // The dimensions of the document in which we are displaying the hover - const bodyBox = dom.getClientArea(document.body); - console.log('bodyBox : ', bodyBox); - - // Hard-coded in the hover.css file as 1.5em or 24px - const minHeight = 24; + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); + const tokenIdentifier = { + startColumn: wordPosition?.startColumn, + endColumn: wordPosition?.endColumn, + line: this._visibleData!.showAtPosition.lineNumber + }; + const persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier); + console.log('persistedSize : ', persistedSize); - // Hard-code the values for now! - const maxWidth = bodyBox.width; - if (width > maxWidth) { - console.log('width capped at the maxWidth'); - width = maxWidth; - } + if (persistedSize) { + console.log('When using the persisted size'); + height = persistedSize.height; + width = persistedSize.width; + } else { + console.log('When not using the persisted size'); + const initialMaxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250); + const initialMaxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); + // this._hover.contentsDomNode.style.maxHeight = `${initialMaxHeight}px`; + // this._hover.contentsDomNode.style.maxWidth = `${initialMaxWidth}px`; + this._hover.containerDomNode.style.maxHeight = `${initialMaxHeight}px`; + this._hover.containerDomNode.style.maxWidth = `${initialMaxWidth}px`; + this._hover.containerDomNode.style.minHeight = '24px'; + // this._element.domNode.style.maxHeight = `${initialMaxHeight}px`; + // this._element.domNode.style.maxWidth = `${initialMaxWidth}px`; + // this._element.maxSize = new dom.Dimension(initialMaxWidth, initialMaxHeight); + + this._hover.contentsDomNode.style.width = 'max-content'; + this._hover.contentsDomNode.style.height = 'fit-content'; + this._hover.containerDomNode.style.width = 'max-content'; + this._hover.containerDomNode.style.height = 'fit-content'; + + /* + const contentsHover = this._hover.contentsDomNode; + let maxContentWidth = 0; + for (const childContent of contentsHover.children) { + maxContentWidth = Math.max(maxContentWidth, this._findClientWidthOf(childContent)); + console.log('maxContentWidth : ', maxContentWidth); + maxContentWidth = Math.max(maxContentWidth, childContent.clientWidth); + console.log('maxContentWidth : ', maxContentWidth); + } + console.log('maxContentWidth : ', maxContentWidth); + if (maxContentWidth < initialMaxWidth) { + this._hover.contentsDomNode.style.width = `${maxContentWidth}px`; + this._hover.containerDomNode.style.width = `${maxContentWidth}px`; + } + */ + + // this._element = this._register(new ResizableHTMLElement()); + // this._element.domNode.appendChild(this._hover.containerDomNode); + // this._element.domNode.className = 'resizable-hover'; + // this._element.domNode.style.position = 'fixed'; + // this._element.domNode.style.display = 'block'; + // this._element.domNode.style.visibility = 'inherit'; + + // this._hover.contentsDomNode.style.height = 'auto'; + // this._hover.contentsDomNode.style.width = 'auto'; + // If the following is set it causes errors + // this._element.domNode.style.height = 'auto'; + // this._element.domNode.style.width = 'auto'; + + // this._hover.containerDomNode.style.maxHeight = height + 'px'; + // this._hover.containerDomNode.style.maxWidth = width + 'px'; + // this._hover.contentsDomNode.style.maxHeight = height + 'px'; + // this._hover.contentsDomNode.style.maxWidth = width + 'px'; + console.log('Before render'); + console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); + + // Maybe don't need this? + this._editor.layoutContentWidget(this); + this._editor.render(); + + // We want the following to be designed in a similar manner to the initial hover how it was in the main branch in order to give us the default size like initially + console.log('After render'); + console.log('this._element.domNode after layoutContentWidget: ', this._element.domNode); + + height = this._hover.containerDomNode.offsetHeight; + width = this._hover.containerDomNode.offsetWidth; + console.log('height and width'); + console.log('height : ', height); + console.log('width : ', width); + + const clientWidth = this._hover.containerDomNode.clientWidth; + const clientHeight = this._hover.containerDomNode.clientHeight; + console.log('clientWidth : ', clientWidth); + console.log('clientHeight : ', clientHeight); + + // this._hover.containerDomNode.style.height = heightAfterRender + 'px'; + // this._hover.containerDomNode.style.width = widthAfterRender + 'px'; + // this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; + // this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; + + // this._hover.containerDomNode.style.maxHeight = 'none'; + // this._hover.containerDomNode.style.maxWidth = 'none'; + // this._hover.contentsDomNode.style.maxHeight = 'none'; + // this._hover.contentsDomNode.style.maxWidth = 'none'; + // this._element.layout(heightAfterRender + 2, widthAfterRender + 2); + + console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); + + // The dimensions of the document in which we are displaying the hover + const bodyBox = dom.getClientArea(document.body); + console.log('bodyBox : ', bodyBox); + + // Hard-coded in the hover.css file as 1.5em or 24px + const minHeight = 24; + + // Hard-code the values for now! + const maxWidth = bodyBox.width; + if (width > maxWidth) { + console.log('width capped at the maxWidth'); + width = maxWidth; + } - // The full height is already passed in as a parameter - const fullHeight = height; - const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - console.log('editorBox : ', editorBox); - if (!this._visibleData?.showAtPosition) { - return; - } - const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); - console.log('mouseBox : ', mouseBox); - // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height - const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; - console.log('mouseBottom : ', mouseBottom); - // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position - const availableSpaceBelow = bodyBox.height - mouseBottom; - console.log('availableSpaceBelow : ', availableSpaceBelow); - // Max height below is the minimum of the available space below and the full height of the widget - const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); - console.log('maxHeightBelow : ', maxHeightBelow); - // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor - const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs - console.log('availableSpaceAbove : ', availableSpaceAbove); - // Max height above is the minimum of the available space above and the full height of the widget - const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); - console.log('maxHeightAbove : ', maxHeightAbove); - // We find the maximum height of the widget possible on the top or on the bottom - const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); - console.log('maxHeight : ', maxHeight); - - if (height < minHeight) { - console.log('height capped at the min height'); - height = minHeight; - } - if (height > maxHeight) { - console.log('height capped at the maximum height'); - // The maximum height has been limited due to not enough - height = maxHeight; - } + // The full height is already passed in as a parameter + const fullHeight = height; + const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); + console.log('editorBox : ', editorBox); + if (!this._visibleData?.showAtPosition) { + return; + } + const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); + console.log('mouseBox : ', mouseBox); + // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height + const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; + console.log('mouseBottom : ', mouseBottom); + // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position + const availableSpaceBelow = bodyBox.height - mouseBottom; + console.log('availableSpaceBelow : ', availableSpaceBelow); + // Max height below is the minimum of the available space below and the full height of the widget + const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); + console.log('maxHeightBelow : ', maxHeightBelow); + // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor + const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs + console.log('availableSpaceAbove : ', availableSpaceAbove); + // Max height above is the minimum of the available space above and the full height of the widget + const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); + console.log('maxHeightAbove : ', maxHeightAbove); + // We find the maximum height of the widget possible on the top or on the bottom + const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); + console.log('maxHeight : ', maxHeight); + + if (height < minHeight) { + console.log('height capped at the min height'); + height = minHeight; + } + if (height > maxHeight) { + console.log('height capped at the maximum height'); + // The maximum height has been limited due to not enough + height = maxHeight; + } - const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; - console.log('preferRenderingAbove : ', preferRenderingAbove); + const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; + console.log('preferRenderingAbove : ', preferRenderingAbove); - console.log('Before enabling sashes'); - if (preferRenderingAbove) { - console.log('first if condition'); + console.log('Before enabling sashes'); + if (preferRenderingAbove) { + console.log('first if condition'); - const westSash = false; - const eastSash = true; - const northSash = height <= maxHeightAbove; - const southSash = height > maxHeightAbove; - this._renderingAbove = height <= maxHeightAbove; - console.log('this._renderingAbove : ', this._renderingAbove); + const westSash = false; + const eastSash = true; + const northSash = height <= maxHeightAbove; + const southSash = height > maxHeightAbove; + this._renderingAbove = height <= maxHeightAbove; + console.log('this._renderingAbove : ', this._renderingAbove); - this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('this._renderingType : ', this._renderingType); - this._element.enableSashes(northSash, eastSash, southSash, westSash); + this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('this._renderingType : ', this._renderingType); + this._element.enableSashes(northSash, eastSash, southSash, westSash); - } else { - console.log('Second if condition'); - const westSash = false; - const eastSash = true; - const northSash = height > maxHeightBelow; - const southSash = height <= maxHeightBelow; - - this._renderingAbove = height > maxHeightBelow; - console.log('this._renderingAbove : ', this._renderingAbove); - - this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('this._renderingType : ', this._renderingType); - this._element.enableSashes(northSash, eastSash, southSash, westSash); - } + } else { + console.log('Second if condition'); + const westSash = false; + const eastSash = true; + const northSash = height > maxHeightBelow; + const southSash = height <= maxHeightBelow; + + this._renderingAbove = height > maxHeightBelow; + console.log('this._renderingAbove : ', this._renderingAbove); + + this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('this._renderingType : ', this._renderingType); + this._element.enableSashes(northSash, eastSash, southSash, westSash); + } - // TODO: Place the following line in order to use the calculated max width and max height - // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 + // TODO: Place the following line in order to use the calculated max width and max height + // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 - this._element.minSize = new dom.Dimension(10, minHeight); - this._maxRenderingHeight = this._findMaxRenderingHeight(); - console.log('maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { - return; + this._element.minSize = new dom.Dimension(10, minHeight); + this._maxRenderingHeight = this._findMaxRenderingHeight(); + console.log('maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { + return; + } + this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); + console.log('height : ', height); + console.log('width : ', width); } - this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - console.log('height : ', height); - console.log('width : ', width); this._element.layout(height, width); this._hover.containerDomNode.style.height = `${height - 2}px`; // height - 2 this._hover.containerDomNode.style.width = `${width - 2}px`; // width - 2 @@ -713,6 +835,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.scrollbar.scanDomNode(); console.log('Before layoutContentWidget'); this._editor.layoutContentWidget(this); + this._editor.render(); console.log('this.getDomNode() : ', this.getDomNode()); } @@ -774,6 +897,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // if (height >= this._maxRenderingHeight) { // this._element.enableSashes(false, true, false, false); // } + this._element.layout(height, width); this._hover.containerDomNode.style.height = `${height - 2}px`; this._hover.containerDomNode.style.width = `${width - 2}px`; @@ -878,6 +1002,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log(' * Entered into showAt of ContentHoverWidget'); console.log('visibleData : ', visibleData); console.log('node : ', node); + console.log('node.baseURI ', node.baseURI); console.log('this._element.domNode : ', this._element.domNode); this._setVisibleData(visibleData); From 69cd233f91507879497d9e252d646bac8470a441 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 Mar 2023 17:32:17 +0100 Subject: [PATCH 31/95] Changed the code so that the persisted size is taken into account of the sash calculations --- .../contrib/hover/browser/contentHover.ts | 193 +++++++++--------- 1 file changed, 100 insertions(+), 93 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index b54b6a1cccf41..77cab76e06e2a 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -700,112 +700,114 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = this._hover.containerDomNode.offsetHeight; width = this._hover.containerDomNode.offsetWidth; - console.log('height and width'); - console.log('height : ', height); - console.log('width : ', width); + } - const clientWidth = this._hover.containerDomNode.clientWidth; - const clientHeight = this._hover.containerDomNode.clientHeight; - console.log('clientWidth : ', clientWidth); - console.log('clientHeight : ', clientHeight); + console.log('height and width'); + console.log('height : ', height); + console.log('width : ', width); - // this._hover.containerDomNode.style.height = heightAfterRender + 'px'; - // this._hover.containerDomNode.style.width = widthAfterRender + 'px'; - // this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; - // this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; + const clientWidth = this._hover.containerDomNode.clientWidth; + const clientHeight = this._hover.containerDomNode.clientHeight; + console.log('clientWidth : ', clientWidth); + console.log('clientHeight : ', clientHeight); - // this._hover.containerDomNode.style.maxHeight = 'none'; - // this._hover.containerDomNode.style.maxWidth = 'none'; - // this._hover.contentsDomNode.style.maxHeight = 'none'; - // this._hover.contentsDomNode.style.maxWidth = 'none'; - // this._element.layout(heightAfterRender + 2, widthAfterRender + 2); + // this._hover.containerDomNode.style.height = heightAfterRender + 'px'; + // this._hover.containerDomNode.style.width = widthAfterRender + 'px'; + // this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; + // this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; - console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); + // this._hover.containerDomNode.style.maxHeight = 'none'; + // this._hover.containerDomNode.style.maxWidth = 'none'; + // this._hover.contentsDomNode.style.maxHeight = 'none'; + // this._hover.contentsDomNode.style.maxWidth = 'none'; + // this._element.layout(heightAfterRender + 2, widthAfterRender + 2); - // The dimensions of the document in which we are displaying the hover - const bodyBox = dom.getClientArea(document.body); - console.log('bodyBox : ', bodyBox); + console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); - // Hard-coded in the hover.css file as 1.5em or 24px - const minHeight = 24; + // The dimensions of the document in which we are displaying the hover + const bodyBox = dom.getClientArea(document.body); + console.log('bodyBox : ', bodyBox); - // Hard-code the values for now! - const maxWidth = bodyBox.width; - if (width > maxWidth) { - console.log('width capped at the maxWidth'); - width = maxWidth; - } + // Hard-coded in the hover.css file as 1.5em or 24px + const minHeight = 24; - // The full height is already passed in as a parameter - const fullHeight = height; - const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - console.log('editorBox : ', editorBox); - if (!this._visibleData?.showAtPosition) { - return; - } - const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); - console.log('mouseBox : ', mouseBox); - // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height - const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; - console.log('mouseBottom : ', mouseBottom); - // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position - const availableSpaceBelow = bodyBox.height - mouseBottom; - console.log('availableSpaceBelow : ', availableSpaceBelow); - // Max height below is the minimum of the available space below and the full height of the widget - const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); - console.log('maxHeightBelow : ', maxHeightBelow); - // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor - const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs - console.log('availableSpaceAbove : ', availableSpaceAbove); - // Max height above is the minimum of the available space above and the full height of the widget - const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); - console.log('maxHeightAbove : ', maxHeightAbove); - // We find the maximum height of the widget possible on the top or on the bottom - const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); - console.log('maxHeight : ', maxHeight); - - if (height < minHeight) { - console.log('height capped at the min height'); - height = minHeight; - } - if (height > maxHeight) { - console.log('height capped at the maximum height'); - // The maximum height has been limited due to not enough - height = maxHeight; - } + // Hard-code the values for now! + const maxWidth = bodyBox.width; + if (width > maxWidth) { + console.log('width capped at the maxWidth'); + width = maxWidth; + } + + // The full height is already passed in as a parameter + const fullHeight = height; + const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); + console.log('editorBox : ', editorBox); + if (!this._visibleData?.showAtPosition) { + return; + } + const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); + console.log('mouseBox : ', mouseBox); + // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height + const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; + console.log('mouseBottom : ', mouseBottom); + // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position + const availableSpaceBelow = bodyBox.height - mouseBottom; + console.log('availableSpaceBelow : ', availableSpaceBelow); + // Max height below is the minimum of the available space below and the full height of the widget + const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); + console.log('maxHeightBelow : ', maxHeightBelow); + // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor + const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs + console.log('availableSpaceAbove : ', availableSpaceAbove); + // Max height above is the minimum of the available space above and the full height of the widget + const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); + console.log('maxHeightAbove : ', maxHeightAbove); + // We find the maximum height of the widget possible on the top or on the bottom + const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); + console.log('maxHeight : ', maxHeight); + + if (height < minHeight) { + console.log('height capped at the min height'); + height = minHeight; + } + if (height > maxHeight) { + console.log('height capped at the maximum height'); + // The maximum height has been limited due to not enough + height = maxHeight; + } - const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; - console.log('preferRenderingAbove : ', preferRenderingAbove); + const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; + console.log('preferRenderingAbove : ', preferRenderingAbove); - console.log('Before enabling sashes'); - if (preferRenderingAbove) { - console.log('first if condition'); + console.log('Before enabling sashes'); + if (preferRenderingAbove) { + console.log('first if condition'); - const westSash = false; - const eastSash = true; - const northSash = height <= maxHeightAbove; - const southSash = height > maxHeightAbove; - this._renderingAbove = height <= maxHeightAbove; - console.log('this._renderingAbove : ', this._renderingAbove); + const westSash = false; + const eastSash = true; + const northSash = height <= maxHeightAbove; + const southSash = height > maxHeightAbove; + this._renderingAbove = height <= maxHeightAbove; + console.log('this._renderingAbove : ', this._renderingAbove); - this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('this._renderingType : ', this._renderingType); - this._element.enableSashes(northSash, eastSash, southSash, westSash); + this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('this._renderingType : ', this._renderingType); + this._element.enableSashes(northSash, eastSash, southSash, westSash); + + } else { + console.log('Second if condition'); + const westSash = false; + const eastSash = true; + const northSash = height > maxHeightBelow; + const southSash = height <= maxHeightBelow; + + this._renderingAbove = height > maxHeightBelow; + console.log('this._renderingAbove : ', this._renderingAbove); + + this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('this._renderingType : ', this._renderingType); + this._element.enableSashes(northSash, eastSash, southSash, westSash); - } else { - console.log('Second if condition'); - const westSash = false; - const eastSash = true; - const northSash = height > maxHeightBelow; - const southSash = height <= maxHeightBelow; - - this._renderingAbove = height > maxHeightBelow; - console.log('this._renderingAbove : ', this._renderingAbove); - - this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('this._renderingType : ', this._renderingType); - this._element.enableSashes(northSash, eastSash, southSash, westSash); - } // TODO: Place the following line in order to use the calculated max width and max height // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 @@ -912,6 +914,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); this._editor.layoutContentWidget(this); + + console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); + console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); } public override dispose(): void { From bab75aa31c1654607facf684fa915b16c10c77f9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 Mar 2023 18:22:31 +0100 Subject: [PATCH 32/95] needs more cleanup --- .../contrib/hover/browser/contentHover.ts | 321 ++++++------------ 1 file changed, 105 insertions(+), 216 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 77cab76e06e2a..e360773b6ecd2 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -26,31 +26,25 @@ import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; +import { URI } from 'vs/base/common/uri'; const $ = dom.$; +// TODO: Perhaps better to persist in map or array if does not save from session to session class PersistedHoverWidgetSizes { - private readonly _keyPrefix: string; + private readonly _prefix: string; - constructor( - // Storing the size of the suggest widget inside of the storage service - private readonly _service: IStorageService, - editor: ICodeEditor - ) { - const textModelURI = editor.getModel()?.uri; - this._keyPrefix = `contentHover.size/${editor.getEditorType()}/${editor instanceof EmbeddedCodeEditorWidget}/${textModelURI}/`; + constructor(private readonly _service: IStorageService) { + this._prefix = 'contentHover.size'; } - restore(identifier: object): dom.Dimension | undefined { + restore(identifier: TokenIdentifier, uri: URI): dom.Dimension | undefined { + const keyPrefix = `${this._prefix}/${uri.toString()}/`; const stringifiedIdentifier = JSON.stringify(identifier); - // Retrieving the key from the storage service - const raw = this._service.get(this._keyPrefix + stringifiedIdentifier, StorageScope.PROFILE) ?? ''; + const raw = this._service.get(keyPrefix + stringifiedIdentifier, StorageScope.PROFILE) ?? ''; try { - // Parsing the associated value const obj = JSON.parse(raw); - // Checking if the associated value is of type dimension if (dom.Dimension.is(obj)) { return dom.Dimension.lift(obj); } @@ -60,26 +54,44 @@ class PersistedHoverWidgetSizes { return undefined; } - // Storing the size so that it can be retrieved later when the suggest widget appears again - store(identifier: object, size: dom.Dimension) { + store(identifier: TokenIdentifier, size: dom.Dimension, uri: URI) { + const keyPrefix = `${this._prefix}/${uri.toString()}/`; const stringifiedIdentifier = JSON.stringify(identifier); - this._service.store(this._keyPrefix + stringifiedIdentifier, JSON.stringify(size), StorageScope.PROFILE, StorageTarget.MACHINE); + this._service.store(keyPrefix + stringifiedIdentifier, JSON.stringify(size), StorageScope.PROFILE, StorageTarget.MACHINE); } - resetAll() { + resetForUri(uri: URI) { + const keyPrefix = `${this._prefix}/${uri.toString()}/`; const keys = this._service.keys(StorageScope.PROFILE, StorageTarget.MACHINE); for (const key of keys) { - if (key.includes(this._keyPrefix)) { + if (key.includes(keyPrefix)) { this._service.remove(key, StorageScope.PROFILE); } } } } +class TokenIdentifier { + constructor( + public readonly _line: number, + public readonly _startColumn: number, + public readonly _endColumn: number + ) { } +} + +class ResizeState { + constructor( + readonly persistedSize: dom.Dimension | undefined, + readonly currentSize: dom.Dimension, + public persistHeight = false, + public persistWidth = false, + ) { } +} + export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; - private readonly _widget; + private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; @@ -91,7 +103,7 @@ export class ContentHoverController extends Disposable { @IKeybindingService private readonly _keybindingService: IKeybindingService, ) { super(); - this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -466,26 +478,26 @@ class ContentHoverVisibleData { ) { } } +// TODO: Find the correct initial hover size + export class ContentHoverWidget extends Disposable implements IContentWidget { static readonly ID = 'editor.contrib.contentHoverWidget'; public readonly allowEditorOverflow = true; - private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); - private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); + private readonly _hover: HoverWidget = this._register(new HoverWidget()); private _visibleData: ContentHoverVisibleData | null = null; - private _element: ResizableHTMLElement = this._register(new ResizableHTMLElement()); - private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; - private _renderingType: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; + private _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); + private _renderingAboveOption: boolean = this._editor.getOption(EditorOption.hover).above; + private _renderingAbove = this._renderingAboveOption; private _maxRenderingHeight: number | undefined = -1; private readonly _persistedHoverWidgetSizes: PersistedHoverWidgetSizes; + private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); + private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); + private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - public get element(): ResizableHTMLElement { - return this._element; - } /** * Returns `null` if the hover is not visible. @@ -511,16 +523,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IStorageService private readonly _storageService: IStorageService, ) { - super(); console.log('Very beginning of constructor'); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); this._register(this._editor.onDidLayoutChange(() => this._layout())); this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => { if (e.hasChanged(EditorOption.fontInfo)) { this._updateFont(); } + if (e.hasChanged(EditorOption.hover)) { + this._renderingAbove = this._editor.getOption(EditorOption.hover).above; + } })); this._setVisibleData(null); @@ -533,103 +547,76 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); - this._persistedHoverWidgetSizes = new PersistedHoverWidgetSizes(this._storageService, this._editor); - this._editor.onDidChangeModel(() => { - this._persistedHoverWidgetSizes.resetAll(); + this._persistedHoverWidgetSizes = new PersistedHoverWidgetSizes(this._storageService); + this._editor.onDidChangeModel((model) => { + if (model.oldModelUrl) { + this._persistedHoverWidgetSizes.resetForUri(model.oldModelUrl); + } }); - this._element.domNode.appendChild(this._hover.containerDomNode); - this._element.domNode.className = 'resizable-hover'; - this._element.domNode.tabIndex = 0; - this._element.domNode.role = 'tooltip'; - - class ResizeState { - constructor( - readonly persistedSize: dom.Dimension | undefined, - readonly currentSize: dom.Dimension, - public persistHeight = false, - public persistWidth = false, - ) { } - } + this._resizableElement.domNode.appendChild(this._hover.containerDomNode); + this._resizableElement.domNode.className = 'resizable-hover'; + this._resizableElement.domNode.tabIndex = 0; + this._resizableElement.domNode.role = 'tooltip'; let state: ResizeState | undefined; - this._register(this.element.onDidWillResize(() => { + this._register(this._resizableElement.onDidWillResize(() => { const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - const tokenIdentifier = { - startColumn: wordPosition?.startColumn, - endColumn: wordPosition?.endColumn, - line: this._visibleData!.showAtPosition.lineNumber - }; - const persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier); - state = new ResizeState(persistedSize, this.element.size); + if (wordPosition && this._editor.hasModel()) { + const tokenIdentifier = new TokenIdentifier(this._visibleData!.showAtPosition.lineNumber, wordPosition.startColumn, wordPosition.endColumn); + const persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier, this._editor.getModel().uri); + state = new ResizeState(persistedSize, this._resizableElement.size); + } })); - this._register(this._element.onDidResize(e => { + this._register(this._resizableElement.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); this._resize(e.dimension.width, e.dimension.height); - if (state) { state.persistHeight = state.persistHeight || !!e.north || !!e.south; state.persistWidth = state.persistWidth || !!e.east || !!e.west; } - if (!e.done) { return; } - if (state) { const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - const tokenIdentifier = { - startColumn: wordPosition?.startColumn, - endColumn: wordPosition?.endColumn, - line: this._visibleData!.showAtPosition.lineNumber - }; - const { width, height } = this.element.size; - const persistedSize = new dom.Dimension(width, height); - this._persistedHoverWidgetSizes.store(tokenIdentifier, persistedSize); + if (wordPosition && this._editor.hasModel()) { + const tokenIdentifier = new TokenIdentifier(this._visibleData!.showAtPosition.lineNumber, wordPosition.startColumn, wordPosition.endColumn); + const { width, height } = this._resizableElement.size; + const persistedSize = new dom.Dimension(width, height); + this._persistedHoverWidgetSizes.store(tokenIdentifier, persistedSize, this._editor.getModel().uri); + } } state = undefined; })); console.log('Before adding the content widget'); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); this._editor.addContentWidget(this); console.log('After adding the content widget'); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); } - // TODO: Polish code, annotate, make it cleaner. Understand what all the entites correspond to, if some are superfluous, not needed - // TODO: Find out why even if smaller than default max size, the whole widget is not shown, want the whole widget to be shown when smaller than default size - // TODO: Render the correct initial size - // TODO: Persist the maximum size, if bigger than this size then cap to this size, otherwise take the smaller size - // TODO: Do not enable the sashes when the hover should not be resizable anymore - // TODO: Add horizontal scroll-bar on the resizable element when part of the horizontal text is not visible - // TODO: Have the same hover size as by default, for that generate the initial rendering of the content hover widget - private _setLayoutOfResizableElement(): void { console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); - console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); + console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); - if (!this._editor.hasModel()) { - return; - } - if (!this._editor.getDomNode()) { + if (!this._editor.hasModel() || !this._editor.getDomNode() || !this._visibleData?.showAtPosition) { return; } - // The hover container dom node height and width are initial automatically determined by the browser before being changed - let height; let width; + let persistedSize; const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - const tokenIdentifier = { - startColumn: wordPosition?.startColumn, - endColumn: wordPosition?.endColumn, - line: this._visibleData!.showAtPosition.lineNumber - }; - const persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier); + if (wordPosition && this._editor.hasModel()) { + const tokenIdentifier = new TokenIdentifier(this._visibleData!.showAtPosition.lineNumber, wordPosition.startColumn, wordPosition.endColumn); + persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier, this._editor.getModel().uri); + } + console.log('persistedSize : ', persistedSize); if (persistedSize) { @@ -640,63 +627,23 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('When not using the persisted size'); const initialMaxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250); const initialMaxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); - // this._hover.contentsDomNode.style.maxHeight = `${initialMaxHeight}px`; - // this._hover.contentsDomNode.style.maxWidth = `${initialMaxWidth}px`; this._hover.containerDomNode.style.maxHeight = `${initialMaxHeight}px`; this._hover.containerDomNode.style.maxWidth = `${initialMaxWidth}px`; this._hover.containerDomNode.style.minHeight = '24px'; - // this._element.domNode.style.maxHeight = `${initialMaxHeight}px`; - // this._element.domNode.style.maxWidth = `${initialMaxWidth}px`; - // this._element.maxSize = new dom.Dimension(initialMaxWidth, initialMaxHeight); this._hover.contentsDomNode.style.width = 'max-content'; this._hover.contentsDomNode.style.height = 'fit-content'; this._hover.containerDomNode.style.width = 'max-content'; this._hover.containerDomNode.style.height = 'fit-content'; - /* - const contentsHover = this._hover.contentsDomNode; - let maxContentWidth = 0; - for (const childContent of contentsHover.children) { - maxContentWidth = Math.max(maxContentWidth, this._findClientWidthOf(childContent)); - console.log('maxContentWidth : ', maxContentWidth); - maxContentWidth = Math.max(maxContentWidth, childContent.clientWidth); - console.log('maxContentWidth : ', maxContentWidth); - } - console.log('maxContentWidth : ', maxContentWidth); - if (maxContentWidth < initialMaxWidth) { - this._hover.contentsDomNode.style.width = `${maxContentWidth}px`; - this._hover.containerDomNode.style.width = `${maxContentWidth}px`; - } - */ - - // this._element = this._register(new ResizableHTMLElement()); - // this._element.domNode.appendChild(this._hover.containerDomNode); - // this._element.domNode.className = 'resizable-hover'; - // this._element.domNode.style.position = 'fixed'; - // this._element.domNode.style.display = 'block'; - // this._element.domNode.style.visibility = 'inherit'; - - // this._hover.contentsDomNode.style.height = 'auto'; - // this._hover.contentsDomNode.style.width = 'auto'; - // If the following is set it causes errors - // this._element.domNode.style.height = 'auto'; - // this._element.domNode.style.width = 'auto'; - - // this._hover.containerDomNode.style.maxHeight = height + 'px'; - // this._hover.containerDomNode.style.maxWidth = width + 'px'; - // this._hover.contentsDomNode.style.maxHeight = height + 'px'; - // this._hover.contentsDomNode.style.maxWidth = width + 'px'; console.log('Before render'); - console.log('this._element.domNode before layoutContentWidget : ', this._element.domNode); + console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); - // Maybe don't need this? this._editor.layoutContentWidget(this); this._editor.render(); - // We want the following to be designed in a similar manner to the initial hover how it was in the main branch in order to give us the default size like initially console.log('After render'); - console.log('this._element.domNode after layoutContentWidget: ', this._element.domNode); + console.log('this._element.domNode after layoutContentWidget: ', this._resizableElement.domNode); height = this._hover.containerDomNode.offsetHeight; width = this._hover.containerDomNode.offsetWidth; @@ -706,128 +653,70 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('height : ', height); console.log('width : ', width); - const clientWidth = this._hover.containerDomNode.clientWidth; - const clientHeight = this._hover.containerDomNode.clientHeight; - console.log('clientWidth : ', clientWidth); - console.log('clientHeight : ', clientHeight); - - // this._hover.containerDomNode.style.height = heightAfterRender + 'px'; - // this._hover.containerDomNode.style.width = widthAfterRender + 'px'; - // this._hover.contentsDomNode.style.height = heightAfterRender + 'px'; - // this._hover.contentsDomNode.style.width = widthAfterRender + 'px'; - - // this._hover.containerDomNode.style.maxHeight = 'none'; - // this._hover.containerDomNode.style.maxWidth = 'none'; - // this._hover.contentsDomNode.style.maxHeight = 'none'; - // this._hover.contentsDomNode.style.maxWidth = 'none'; - // this._element.layout(heightAfterRender + 2, widthAfterRender + 2); - console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); - console.log('bodyBox : ', bodyBox); - - // Hard-coded in the hover.css file as 1.5em or 24px - const minHeight = 24; // Hard-code the values for now! const maxWidth = bodyBox.width; if (width > maxWidth) { - console.log('width capped at the maxWidth'); width = maxWidth; } + // Hard-coded in the hover.css file as 1.5em or 24px + const minHeight = 24; // The full height is already passed in as a parameter const fullHeight = height; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - console.log('editorBox : ', editorBox); - if (!this._visibleData?.showAtPosition) { - return; - } const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); - console.log('mouseBox : ', mouseBox); // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; - console.log('mouseBottom : ', mouseBottom); // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position const availableSpaceBelow = bodyBox.height - mouseBottom; - console.log('availableSpaceBelow : ', availableSpaceBelow); // Max height below is the minimum of the available space below and the full height of the widget const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); - console.log('maxHeightBelow : ', maxHeightBelow); // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs - console.log('availableSpaceAbove : ', availableSpaceAbove); // Max height above is the minimum of the available space above and the full height of the widget const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); - console.log('maxHeightAbove : ', maxHeightAbove); // We find the maximum height of the widget possible on the top or on the bottom const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); - console.log('maxHeight : ', maxHeight); if (height < minHeight) { - console.log('height capped at the min height'); height = minHeight; } if (height > maxHeight) { - console.log('height capped at the maximum height'); - // The maximum height has been limited due to not enough height = maxHeight; } - const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; - console.log('preferRenderingAbove : ', preferRenderingAbove); - - console.log('Before enabling sashes'); - if (preferRenderingAbove) { - console.log('first if condition'); - + if (this._renderingAboveOption) { const westSash = false; const eastSash = true; const northSash = height <= maxHeightAbove; const southSash = height > maxHeightAbove; this._renderingAbove = height <= maxHeightAbove; - console.log('this._renderingAbove : ', this._renderingAbove); - - this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('this._renderingType : ', this._renderingType); - this._element.enableSashes(northSash, eastSash, southSash, westSash); - + this._resizableElement.enableSashes(northSash, eastSash, southSash, westSash); } else { - console.log('Second if condition'); const westSash = false; const eastSash = true; const northSash = height > maxHeightBelow; const southSash = height <= maxHeightBelow; - this._renderingAbove = height > maxHeightBelow; - console.log('this._renderingAbove : ', this._renderingAbove); - - this._renderingType = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('this._renderingType : ', this._renderingType); - this._element.enableSashes(northSash, eastSash, southSash, westSash); - - - // TODO: Place the following line in order to use the calculated max width and max height - // TODO: It would appear that if the minimum width is 0, it will disappear, set some value larger than 0 - - this._element.minSize = new dom.Dimension(10, minHeight); + this._resizableElement.enableSashes(northSash, eastSash, southSash, westSash); + this._resizableElement.minSize = new dom.Dimension(10, minHeight); this._maxRenderingHeight = this._findMaxRenderingHeight(); - console.log('maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight) { return; } - this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - console.log('height : ', height); - console.log('width : ', width); + this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); } - this._element.layout(height, width); - this._hover.containerDomNode.style.height = `${height - 2}px`; // height - 2 - this._hover.containerDomNode.style.width = `${width - 2}px`; // width - 2 - this._hover.contentsDomNode.style.height = `${height - 2}px`; // height - 2 - this._hover.contentsDomNode.style.width = `${width - 2}px`; // width - 2 + this._resizableElement.layout(height, width); + this._hover.containerDomNode.style.height = `${height - 2}px`; + this._hover.containerDomNode.style.width = `${width - 2}px`; + this._hover.contentsDomNode.style.height = `${height - 2}px`; + this._hover.contentsDomNode.style.width = `${width - 2}px`; console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); @@ -886,8 +775,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; - const maxWidth = this._element.maxSize.width; - const maxHeight = this._element.maxSize.height; + const maxWidth = this._resizableElement.maxSize.width; + const maxHeight = this._resizableElement.maxSize.height; width = Math.min(maxWidth, width); height = Math.min(maxHeight, height); console.log('height : ', height); @@ -900,7 +789,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._element.enableSashes(false, true, false, false); // } - this._element.layout(height, width); + this._resizableElement.layout(height, width); this._hover.containerDomNode.style.height = `${height - 2}px`; this._hover.containerDomNode.style.width = `${width - 2}px`; this._hover.contentsDomNode.style.height = `${height - 2}px`; @@ -912,7 +801,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (!this._maxRenderingHeight) { return; } - this._element.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); + this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); this._editor.layoutContentWidget(this); console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); @@ -935,7 +824,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public getDomNode(): HTMLElement { console.log('Inside of getDomNode'); - return this._element.domNode; + return this._resizableElement.domNode; } public getPosition(): IContentWidgetPosition | null { @@ -951,11 +840,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // :before content can align left of the text content const affinity = this._visibleData.isBeforeContent ? PositionAffinity.LeftOfInjectedText : undefined; - + const rendering = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; return { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, - preference: [this._renderingType], + preference: [rendering], positionAffinity: affinity }; } @@ -990,7 +879,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._visibleData = visibleData; this._hoverVisibleKey.set(!!this._visibleData); this._hover.containerDomNode.classList.toggle('hidden', !this._visibleData); - this._element.domNode.classList.toggle('hidden', !this._visibleData); + this._resizableElement.domNode.classList.toggle('hidden', !this._visibleData); } private _layout(): void { @@ -1010,7 +899,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('visibleData : ', visibleData); console.log('node : ', node); console.log('node.baseURI ', node.baseURI); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); this._setVisibleData(visibleData); @@ -1024,16 +913,16 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' console.log('Before render'); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); this._editor.render(); console.log('After render'); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor this.onContentsChanged(); console.log('After onContentsChanged'); - console.log('this._element.domNode : ', this._element.domNode); + console.log('this._element.domNode : ', this._resizableElement.domNode); if (visibleData.stoleFocus) { this._hover.containerDomNode.focus(); @@ -1043,7 +932,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public hide(): void { - this._element.clearSashHoverState(); + this._resizableElement.clearSashHoverState(); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); From f5835d711e27c06c2183d6e660816e380f86460d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 Mar 2023 23:14:59 +0100 Subject: [PATCH 33/95] instead of using the persist widget class use a map that is valid only during this session --- .../contrib/hover/browser/contentHover.ts | 148 +++++++++--------- 1 file changed, 71 insertions(+), 77 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index e360773b6ecd2..aa62658fe1aab 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -25,60 +25,9 @@ import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/sug import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; -import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; -import { URI } from 'vs/base/common/uri'; const $ = dom.$; -// TODO: Perhaps better to persist in map or array if does not save from session to session -class PersistedHoverWidgetSizes { - - private readonly _prefix: string; - - constructor(private readonly _service: IStorageService) { - this._prefix = 'contentHover.size'; - } - - restore(identifier: TokenIdentifier, uri: URI): dom.Dimension | undefined { - const keyPrefix = `${this._prefix}/${uri.toString()}/`; - const stringifiedIdentifier = JSON.stringify(identifier); - const raw = this._service.get(keyPrefix + stringifiedIdentifier, StorageScope.PROFILE) ?? ''; - try { - const obj = JSON.parse(raw); - if (dom.Dimension.is(obj)) { - return dom.Dimension.lift(obj); - } - } catch { - // ignore - } - return undefined; - } - - store(identifier: TokenIdentifier, size: dom.Dimension, uri: URI) { - const keyPrefix = `${this._prefix}/${uri.toString()}/`; - const stringifiedIdentifier = JSON.stringify(identifier); - this._service.store(keyPrefix + stringifiedIdentifier, JSON.stringify(size), StorageScope.PROFILE, StorageTarget.MACHINE); - } - - resetForUri(uri: URI) { - const keyPrefix = `${this._prefix}/${uri.toString()}/`; - const keys = this._service.keys(StorageScope.PROFILE, StorageTarget.MACHINE); - for (const key of keys) { - if (key.includes(keyPrefix)) { - this._service.remove(key, StorageScope.PROFILE); - } - } - } -} - -class TokenIdentifier { - constructor( - public readonly _line: number, - public readonly _startColumn: number, - public readonly _endColumn: number - ) { } -} - class ResizeState { constructor( readonly persistedSize: dom.Dimension | undefined, @@ -493,7 +442,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private _renderingAboveOption: boolean = this._editor.getOption(EditorOption.hover).above; private _renderingAbove = this._renderingAboveOption; private _maxRenderingHeight: number | undefined = -1; - private readonly _persistedHoverWidgetSizes: PersistedHoverWidgetSizes; + private readonly _persistedHoverWidgetSizes = new Map>(); private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); @@ -520,8 +469,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, - @IStorageService private readonly _storageService: IStorageService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(); console.log('Very beginning of constructor'); @@ -547,10 +495,27 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hoverFocusedKey.set(false); })); - this._persistedHoverWidgetSizes = new PersistedHoverWidgetSizes(this._storageService); - this._editor.onDidChangeModel((model) => { - if (model.oldModelUrl) { - this._persistedHoverWidgetSizes.resetForUri(model.oldModelUrl); + this._editor.onDidChangeModelContent((e) => { + const uri = this._editor.getModel()?.uri.toString(); + if (!uri || !(uri in this._persistedHoverWidgetSizes)) { + return; + } + const mapToUpdate = this._persistedHoverWidgetSizes.get(uri)!; + for (const change of e.changes) { + const changeOffset = change.rangeOffset; + const length = change.rangeLength; + const endOffset = changeOffset + length; + for (const stringifiedEntry of mapToUpdate.keys()) { + const entry = JSON.parse(stringifiedEntry); + if (endOffset < entry[0]) { + const oldSize = mapToUpdate.get(entry)!; + const newEntry: [number, number] = [entry[0] + length, entry[1]]; + mapToUpdate.set(JSON.stringify(newEntry), oldSize); + mapToUpdate.delete(entry); + } else if (changeOffset < entry[0] + entry[1]) { + mapToUpdate.delete(entry); + } + } } }); this._resizableElement.domNode.appendChild(this._hover.containerDomNode); @@ -561,12 +526,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let state: ResizeState | undefined; this._register(this._resizableElement.onDidWillResize(() => { - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - if (wordPosition && this._editor.hasModel()) { - const tokenIdentifier = new TokenIdentifier(this._visibleData!.showAtPosition.lineNumber, wordPosition.startColumn, wordPosition.endColumn); - const persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier, this._editor.getModel().uri); - state = new ResizeState(persistedSize, this._resizableElement.size); - } + console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); + const persistedSize = this._findPersistedSize(); + state = new ResizeState(persistedSize, this._resizableElement.size); })); this._register(this._resizableElement.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); @@ -580,15 +542,34 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return; } if (state) { + if (!this._editor.hasModel()) { + return; + } + const uri = this._editor.getModel().uri.toString(); + if (!uri) { + return; + } + const { width, height } = this._resizableElement.size; + const persistedSize = new dom.Dimension(width, height); const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - if (wordPosition && this._editor.hasModel()) { - const tokenIdentifier = new TokenIdentifier(this._visibleData!.showAtPosition.lineNumber, wordPosition.startColumn, wordPosition.endColumn); - const { width, height } = this._resizableElement.size; - const persistedSize = new dom.Dimension(width, height); - this._persistedHoverWidgetSizes.store(tokenIdentifier, persistedSize, this._editor.getModel().uri); + if (!wordPosition || !this._editor.hasModel()) { + return; + } + const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._visibleData!.showAtPosition.lineNumber, column: wordPosition.startColumn }); + const length = wordPosition.word.length; + + if (!this._persistedHoverWidgetSizes.get(uri)) { + const map = new Map([]); + map.set(JSON.stringify([offset, length]), persistedSize); + this._persistedHoverWidgetSizes.set(uri, map); + } else { + const map = this._persistedHoverWidgetSizes.get(uri)!; + map.set(JSON.stringify([offset, length]), persistedSize); } } state = undefined; + + console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); })); console.log('Before adding the content widget'); @@ -598,6 +579,26 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('this._element.domNode : ', this._resizableElement.domNode); } + private _findPersistedSize(): dom.Dimension | undefined { + console.log('Inside of _findPersistedSize'); + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); + if (!wordPosition || !this._editor.hasModel()) { + return; + } + const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._visibleData!.showAtPosition.lineNumber, column: wordPosition.startColumn }); + const length = wordPosition.word.length; + const uri = this._editor.getModel().uri.toString(); + console.log('offset : ', offset); + console.log('length : ', length); + const textModelMap = this._persistedHoverWidgetSizes.get(uri); + console.log('textModelMap : ', textModelMap); + if (!textModelMap) { + return; + } + console.log('textModelMap.value : ', textModelMap.entries().next().value); + return textModelMap.get(JSON.stringify([offset, length])); + } + private _setLayoutOfResizableElement(): void { console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); @@ -609,14 +610,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let height; let width; - let persistedSize; - - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - if (wordPosition && this._editor.hasModel()) { - const tokenIdentifier = new TokenIdentifier(this._visibleData!.showAtPosition.lineNumber, wordPosition.startColumn, wordPosition.endColumn); - persistedSize = this._persistedHoverWidgetSizes.restore(tokenIdentifier, this._editor.getModel().uri); - } - + const persistedSize = this._findPersistedSize(); console.log('persistedSize : ', persistedSize); if (persistedSize) { From d8807ebbfb507d1483777f8ec968052c47952814 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 16 Mar 2023 00:19:53 +0100 Subject: [PATCH 34/95] working code, but not ideal --- src/vs/base/common/scrollable.ts | 2 + .../contrib/hover/browser/contentHover.ts | 40 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 1be0752c3fd40..47c94e79b125b 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -264,10 +264,12 @@ export class Scrollable extends Disposable { } public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void { + console.log('dimensions : ', dimensions); const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions); this._setState(newState, Boolean(this._smoothScrolling)); // Validate outstanding animated scroll position target + console.log('this._state inside setScrollDimension : ', this._state); this._smoothScrolling?.acceptScrollDimensions(this._state); } diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index aa62658fe1aab..cf7732411176a 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -446,7 +446,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - + private _resizeObserver: ResizeObserver = new ResizeObserver((entries) => { + console.log('inside of resize observer for element: ', entries); + }); + private _resizeContentsObserver: ResizeObserver = new ResizeObserver((entries) => { + console.log('inside of resize observer for contents: ', entries); + }); + private _resizeContainerObserver: ResizeObserver = new ResizeObserver((entries) => { + console.log('inside of resize observer for container: ', entries); + }); /** * Returns `null` if the hover is not visible. @@ -474,6 +482,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { super(); console.log('Very beginning of constructor'); console.log('this._element.domNode : ', this._resizableElement.domNode); + this._resizeObserver.observe(this._resizableElement.domNode); + this._resizeContentsObserver.observe(this._hover.contentsDomNode); + this._resizeContainerObserver.observe(this._hover.containerDomNode); this._register(this._editor.onDidLayoutChange(() => this._layout())); this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => { @@ -626,9 +637,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.style.minHeight = '24px'; this._hover.contentsDomNode.style.width = 'max-content'; - this._hover.contentsDomNode.style.height = 'fit-content'; + this._hover.contentsDomNode.style.height = 'auto'; this._hover.containerDomNode.style.width = 'max-content'; - this._hover.containerDomNode.style.height = 'fit-content'; + this._hover.containerDomNode.style.height = 'auto'; console.log('Before render'); console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); @@ -706,17 +717,37 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); } + console.log('height : ', height); + console.log('width : ', width); + this._resizableElement.layout(height, width); this._hover.containerDomNode.style.height = `${height - 2}px`; this._hover.containerDomNode.style.width = `${width - 2}px`; + this._hover.containerDomNode.style.overflow = 'hidden'; this._hover.contentsDomNode.style.height = `${height - 2}px`; this._hover.contentsDomNode.style.width = `${width - 2}px`; + this._hover.contentsDomNode.style.overflow = 'hidden'; + + // TODO: Replaces the scanDomNode() call below + /* + this._hover.scrollbar.setScrollDimensions({ + width: width - 2, + height: height - 2, + scrollWidth: this._hover.contentsDomNode.scrollWidth + 20, + scrollHeight: this._hover.contentsDomNode.scrollHeight + 20 + }); + this._hover.scrollbar.setScrollPosition({ + scrollLeft: this._hover.contentsDomNode.scrollLeft, + scrollTop: this._hover.contentsDomNode.scrollTop, + }); + */ console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); + // TODO: place back this._hover.scrollbar.scanDomNode(); console.log('Before layoutContentWidget'); this._editor.layoutContentWidget(this); @@ -786,6 +817,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._resizableElement.layout(height, width); this._hover.containerDomNode.style.height = `${height - 2}px`; this._hover.containerDomNode.style.width = `${width - 2}px`; + // TODO: Find out why adding the following two lines changes the scroll dimensions to reflect reality + // Potentially remove this._hover.contentsDomNode.style.height = `${height - 2}px`; this._hover.contentsDomNode.style.width = `${width - 2}px`; @@ -798,6 +831,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); this._editor.layoutContentWidget(this); + console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); From e42ab7f787466fc464fcbca67e7ad349f874c006 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 16 Mar 2023 13:44:07 +0100 Subject: [PATCH 35/95] The initial sizes are used and a resizable html element in the form of an overlay is used --- src/vs/base/browser/ui/hover/hover.css | 1 + src/vs/base/browser/ui/hover/hoverWidget.ts | 1 + src/vs/base/browser/ui/sash/sash.css | 2 +- src/vs/base/common/scrollable.ts | 4 +- src/vs/editor/common/core/position.ts | 4 +- .../contrib/hover/browser/contentHover.ts | 344 +++++++++++++++--- src/vs/monaco.d.ts | 4 +- 7 files changed, 293 insertions(+), 67 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 57a366d59e840..5d877dcde7b20 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -28,6 +28,7 @@ } .monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) { + max-width: 500px; word-wrap: break-word; } diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index 96e99cbec4a2f..eb40ee926a9a4 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -28,6 +28,7 @@ export class HoverWidget extends Disposable { this.containerDomNode = document.createElement('div'); this.containerDomNode.className = 'monaco-hover'; this.containerDomNode.tabIndex = 0; + this.containerDomNode.style.zIndex = '10'; this.containerDomNode.setAttribute('role', 'tooltip'); this.contentsDomNode = document.createElement('div'); diff --git a/src/vs/base/browser/ui/sash/sash.css b/src/vs/base/browser/ui/sash/sash.css index 0026c3c3b1c35..aae26390096fb 100644 --- a/src/vs/base/browser/ui/sash/sash.css +++ b/src/vs/base/browser/ui/sash/sash.css @@ -108,7 +108,7 @@ width: 100%; height: 100%; transition: background-color 0.1s ease-out; - background: transparent; + background: red; } .monaco-sash.hover:before, diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 47c94e79b125b..49c21b665aa2c 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -264,12 +264,12 @@ export class Scrollable extends Disposable { } public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void { - console.log('dimensions : ', dimensions); + // console.log('dimensions : ', dimensions); const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions); this._setState(newState, Boolean(this._smoothScrolling)); // Validate outstanding animated scroll position target - console.log('this._state inside setScrollDimension : ', this._state); + // console.log('this._state inside setScrollDimension : ', this._state); this._smoothScrolling?.acceptScrollDimensions(this._state); } diff --git a/src/vs/editor/common/core/position.ts b/src/vs/editor/common/core/position.ts index b8b29f9e14fae..37da2e4dbe68a 100644 --- a/src/vs/editor/common/core/position.ts +++ b/src/vs/editor/common/core/position.ts @@ -24,11 +24,11 @@ export class Position { /** * line number (starts at 1) */ - public readonly lineNumber: number; + public lineNumber: number; /** * column (the first character in a line is between column 1 and column 2) */ - public readonly column: number; + public column: number; constructor(lineNumber: number, column: number) { this.lineNumber = lineNumber; diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index cf7732411176a..b89fa96196c84 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -9,9 +9,9 @@ import { coalesce } from 'vs/base/common/arrays'; import { CancellationToken } from 'vs/base/common/cancellation'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; -import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IContentWidgetPosition, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; +import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IContentWidgetPosition, IEditorMouseEvent, IOverlayWidget, IOverlayWidgetPosition, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions'; -import { Position } from 'vs/editor/common/core/position'; +import { IPosition, Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { IModelDecoration, PositionAffinity } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; @@ -40,7 +40,9 @@ class ResizeState { export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; - private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + private readonly _resizableWidget = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); + private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor, this._contextKeyService, this._resizableWidget)); + private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; @@ -50,9 +52,14 @@ export class ContentHoverController extends Disposable { private readonly _editor: ICodeEditor, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(); + // const widgetPosition = this._widget.getPosition(); + // console.log('widgetPosition : ', widgetPosition); + // this._resizableWidget.setPosition(widgetPosition); + // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -68,6 +75,7 @@ export class ContentHoverController extends Disposable { // invalid state, ignore result return; } + console.log('this result of the hover operation is attained'); const messages = (result.hasLoadingMessage ? this._addLoadingMessage(result.value) : result.value); this._withResult(new HoverResult(this._computer.anchor, messages, result.isComplete)); })); @@ -82,6 +90,9 @@ export class ContentHoverController extends Disposable { this._setCurrentResult(this._currentResult); // render again } })); + this._register(this._editor.onDidChangeModel(() => { + this._resizableWidget.hide(); + })); } /** @@ -201,6 +212,7 @@ export class ContentHoverController extends Disposable { this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { this._widget.hide(); + this._resizableWidget.hide(); } } @@ -259,6 +271,7 @@ export class ContentHoverController extends Disposable { } private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { + console.log('Inside of _renderMessage'); const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); @@ -270,7 +283,14 @@ export class ContentHoverController extends Disposable { fragment, statusBar, setColorPicker: (widget) => colorPicker = widget, - onContentsChanged: () => this._widget.onContentsChanged(), + onContentsChanged: () => { + this._widget.onContentsChanged(); + const clientWidth = this._widget.getDomNode().clientWidth; + const clientHeight = this._widget.getDomNode().clientHeight; + this._resizableWidget.resizableElement().layout(clientHeight, clientWidth); + this._editor.layoutOverlayWidget(this._resizableWidget); + this._editor.render(); + }, hide: () => this.hide() }; @@ -298,12 +318,13 @@ export class ContentHoverController extends Disposable { highlightDecoration.clear(); })); } - + const preferAbove = this._editor.getOption(EditorOption.hover).above; + console.log('Before this._widget.showAt'); this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, showAtPosition, showAtSecondaryPosition, - this._editor.getOption(EditorOption.hover).above, + preferAbove, this._computer.shouldFocus, this._computer.source, isBeforeContent, @@ -311,6 +332,42 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosY, disposables )); + this._editor.layoutContentWidget(this._widget); + this._editor.render(); + + // showAtPosition.lineNumber = showAtPosition.lineNumber + 10; + const containerDomNode = this._widget.getDomNode(); + const offsetWidth = containerDomNode.offsetWidth; + const clientWidth = containerDomNode.clientWidth; + const scrollWidth = containerDomNode.scrollWidth; + const width = containerDomNode.style.width; + console.log('offsetWidth : ', offsetWidth); + console.log('clientWidth : ', clientWidth); + console.log('scrollWidth : ', scrollWidth); + console.log('width : ', width); + + const contentsDomNode = this._widget.getContentsDomNode(); + const contentsOffsetWidth = contentsDomNode.offsetWidth; + const contentsClientWidth = contentsDomNode.clientWidth; + const contentsScrollWidth = contentsDomNode.scrollWidth; + const contentsWidth = contentsDomNode.style.width; + console.log('contentsOffsetWidth : ', contentsOffsetWidth); + console.log('contentsClientWidth : ', contentsClientWidth); + console.log('contentsScrollWidth : ', contentsScrollWidth); + console.log('contentsWidth : ', contentsWidth); + + console.log('this._widget.getDomNode() : ', this._widget.getDomNode()); + + const size = new dom.Dimension(this._widget.getDomNode().clientWidth, this._widget.getDomNode().clientHeight); + console.log('this._widget.size() : ', this._widget.getSize()); + console.log('Before this._resizableWidget.showAt'); + console.log('clientTop: this._widget.getDomNode().clientTop : ', this._widget.getDomNode().clientTop); + console.log('clientTop: this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); + console.log('clientTop: this._widget.getDomNode().style.top : ', this._widget.getDomNode().style.top); + const position = { clientTop: this._widget.getDomNode().offsetTop, clientLeft: this._widget.getDomNode().offsetLeft }; + this._resizableWidget.showAt(position, size); + this._editor.layoutOverlayWidget(this._resizableWidget); + this._editor.render(); } else { disposables.dispose(); } @@ -427,6 +484,77 @@ class ContentHoverVisibleData { ) { } } +export class ResizableHoverOverlay extends Disposable implements IOverlayWidget { + + static readonly ID = 'editor.contrib.resizableHoverOverlay'; + private _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); + private _position: IContentWidgetPosition | null = null; + + constructor(private readonly _editor: ICodeEditor) { + super(); + console.log('Inside of constructor of ResizableHoverOverlay'); + // TODO: When the following is added the initial content hover appears to disappear + this._editor.addOverlayWidget(this); + this._resizableElement.domNode.style.zIndex = '100'; + this._resizableElement.domNode.style.position = 'fixed'; + } + + public hide(): void { + console.log('hiding the resizable hover overlay'); + this._resizableElement.clearSashHoverState(); + this._resizableElement.layout(0, 0); + } + + public resizableElement(): ResizableHTMLElement { + return this._resizableElement; + } + + public getId(): string { + return ResizableHoverOverlay.ID; + } + + public getDomNode(): HTMLElement { + console.log('Inside of getDomNode() of ResizableHoverOverlay'); + return this._resizableElement.domNode; + } + + public setPosition(position: any): void { + console.log('Inside of setPosition of ResizableHOverOverlay'); + console.log('this._position : ', this._position); + this._position = position; + if (!position || !position.position) { + return; + } + this._resizableElement.domNode.style.top = position.clientTop + 'px'; + this._resizableElement.domNode.style.left = position.clientLeft + 'px'; + } + + public getPosition(): IOverlayWidgetPosition | null { + console.log('Inside of getPosition of ResizableHoverOverlay'); + console.log('this._position : ', this._position); + return null; + } + + public showAt(position: any, size: dom.Dimension): void { + console.log('Inside of showAt of ResizableHoverOverlay'); + // this._position = widgetPosition; + console.log('position : ', position); + console.log('size : ', size); + + this._resizableElement.enableSashes(true, true, true, true); + this._resizableElement.domNode.style.top = position.clientTop + 'px'; + this._resizableElement.domNode.style.left = position.clientLeft + 'px'; + this._resizableElement.layout(size.height + 4, size.width + 4); + this._editor.layoutOverlayWidget(this); + this._editor.render(); + const resizableDomNode = this._resizableElement.domNode; + console.log('this._resizableElement.domNode : ', resizableDomNode); + console.log('resizableDomNode.clientWidth : ', resizableDomNode.clientWidth); + console.log('resizableDomNode.clientHeight : ', resizableDomNode.clientHeight); + console.log('this._resizableElement.size : ', this._resizableElement.size); + } + +} // TODO: Find the correct initial hover size export class ContentHoverWidget extends Disposable implements IContentWidget { @@ -447,13 +575,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _resizeObserver: ResizeObserver = new ResizeObserver((entries) => { - console.log('inside of resize observer for element: ', entries); + // console.log('inside of resize observer for element: ', entries); }); private _resizeContentsObserver: ResizeObserver = new ResizeObserver((entries) => { - console.log('inside of resize observer for contents: ', entries); + // console.log('inside of resize observer for contents: ', entries); }); private _resizeContainerObserver: ResizeObserver = new ResizeObserver((entries) => { - console.log('inside of resize observer for container: ', entries); + // console.log('inside of resize observer for container: ', entries); }); /** @@ -477,11 +605,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, - @IContextKeyService private readonly _contextKeyService: IContextKeyService + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + private readonly _resizableWidget: ResizableHoverOverlay ) { super(); - console.log('Very beginning of constructor'); - console.log('this._element.domNode : ', this._resizableElement.domNode); + // console.log('Very beginning of constructor'); + // console.log('this._element.domNode : ', this._resizableElement.domNode); this._resizeObserver.observe(this._resizableElement.domNode); this._resizeContentsObserver.observe(this._hover.contentsDomNode); this._resizeContainerObserver.observe(this._hover.containerDomNode); @@ -498,6 +627,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._setVisibleData(null); this._layout(); + this._editor.addContentWidget(this); this._register(this._focusTracker.onDidFocus(() => { this._hoverFocusedKey.set(true); @@ -505,7 +635,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._focusTracker.onDidBlur(() => { this._hoverFocusedKey.set(false); })); - + /* this._editor.onDidChangeModelContent((e) => { const uri = this._editor.getModel()?.uri.toString(); if (!uri || !(uri in this._persistedHoverWidgetSizes)) { @@ -588,10 +718,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.addContentWidget(this); console.log('After adding the content widget'); console.log('this._element.domNode : ', this._resizableElement.domNode); + */ + } + + public getSize() { + return new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); } private _findPersistedSize(): dom.Dimension | undefined { - console.log('Inside of _findPersistedSize'); + // console.log('Inside of _findPersistedSize'); const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); if (!wordPosition || !this._editor.hasModel()) { return; @@ -599,21 +734,21 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._visibleData!.showAtPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; const uri = this._editor.getModel().uri.toString(); - console.log('offset : ', offset); - console.log('length : ', length); + // console.log('offset : ', offset); + // console.log('length : ', length); const textModelMap = this._persistedHoverWidgetSizes.get(uri); - console.log('textModelMap : ', textModelMap); + // console.log('textModelMap : ', textModelMap); if (!textModelMap) { return; } - console.log('textModelMap.value : ', textModelMap.entries().next().value); + // console.log('textModelMap.value : ', textModelMap.entries().next().value); return textModelMap.get(JSON.stringify([offset, length])); } private _setLayoutOfResizableElement(): void { - console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); - console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); + // console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); + // console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); if (!this._editor.hasModel() || !this._editor.getDomNode() || !this._visibleData?.showAtPosition) { return; @@ -622,14 +757,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let height; let width; const persistedSize = this._findPersistedSize(); - console.log('persistedSize : ', persistedSize); + // console.log('persistedSize : ', persistedSize); if (persistedSize) { - console.log('When using the persisted size'); + // console.log('When using the persisted size'); height = persistedSize.height; width = persistedSize.width; } else { - console.log('When not using the persisted size'); + // console.log('When not using the persisted size'); const initialMaxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250); const initialMaxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); this._hover.containerDomNode.style.maxHeight = `${initialMaxHeight}px`; @@ -641,24 +776,24 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.style.width = 'max-content'; this._hover.containerDomNode.style.height = 'auto'; - console.log('Before render'); - console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); + // console.log('Before render'); + // console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); this._editor.layoutContentWidget(this); this._editor.render(); - console.log('After render'); - console.log('this._element.domNode after layoutContentWidget: ', this._resizableElement.domNode); + // console.log('After render'); + // console.log('this._element.domNode after layoutContentWidget: ', this._resizableElement.domNode); height = this._hover.containerDomNode.offsetHeight; width = this._hover.containerDomNode.offsetWidth; } - console.log('height and width'); - console.log('height : ', height); - console.log('width : ', width); + // console.log('height and width'); + // console.log('height : ', height); + // console.log('width : ', width); - console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); + // console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); @@ -717,8 +852,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); } - console.log('height : ', height); - console.log('width : ', width); + // console.log('height : ', height); + // console.log('width : ', width); this._resizableElement.layout(height, width); this._hover.containerDomNode.style.height = `${height - 2}px`; @@ -742,17 +877,17 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { }); */ - console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); - console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); - console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); + // console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + // console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); + // console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); + // console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); // TODO: place back this._hover.scrollbar.scanDomNode(); - console.log('Before layoutContentWidget'); + // console.log('Before layoutContentWidget'); this._editor.layoutContentWidget(this); this._editor.render(); - console.log('this.getDomNode() : ', this.getDomNode()); + // console.log('this.getDomNode() : ', this.getDomNode()); } private _findMaxRenderingHeight(): number | undefined { @@ -766,7 +901,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); const bodyBox = dom.getClientArea(document.body); - // Different to availableSpaceAbove because we want to remove the tabs and breadcrumbs, since the content hover disappears as soon as below the tabs or breadcrumbs const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top - 4; const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; const availableSpaceBelow = bodyBox.height - mouseBottom; @@ -777,12 +911,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } else { maxRenderingHeight = this._renderingAbove ? availableSpaceBelow : availableSpaceAboveMinusTabsAndBreadcrumbs; } - console.log('maxRenderingHeight : ', maxRenderingHeight); let actualMaxHeight = 0; for (const childHtmlElement of this._hover.contentsDomNode.children) { actualMaxHeight += childHtmlElement.clientHeight; } - console.log('actualMaxHeight : ', actualMaxHeight); maxRenderingHeight = Math.min(maxRenderingHeight, actualMaxHeight + 2); return maxRenderingHeight; } @@ -851,13 +983,21 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getDomNode(): HTMLElement { - console.log('Inside of getDomNode'); - return this._resizableElement.domNode; + // return this._resizableElement.domNode; + // Forcing the visiblity: + // this._hover.containerDomNode.style.display = 'block'; + // this._hover.containerDomNode.style.visibility = 'visible'; + return this._hover.containerDomNode; + } + + public getContentsDomNode(): HTMLElement { + return this._hover.contentsDomNode; } public getPosition(): IContentWidgetPosition | null { - console.log('Inside of getPosition'); + console.log('Inside of getPosition of ContentHoverWidget'); if (!this._visibleData) { + console.log('Early return'); return null; } let preferAbove = this._visibleData.preferAbove; @@ -869,10 +1009,26 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // :before content can align left of the text content const affinity = this._visibleData.isBeforeContent ? PositionAffinity.LeftOfInjectedText : undefined; const rendering = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + console.log('position inside of ContentHoverWidget : ', { + position: this._visibleData.showAtPosition, + secondaryPosition: this._visibleData.showAtSecondaryPosition, + // TODO: place back, preference: [rendering], + preference: ( + preferAbove + ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] + : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] + ), + positionAffinity: affinity + }); return { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, - preference: [rendering], + // TODO: place back, preference: [rendering], + preference: ( + preferAbove + ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] + : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] + ), positionAffinity: affinity }; } @@ -911,9 +1067,17 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } private _layout(): void { + // TODO: place back + // const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo); + // this._hover.contentsDomNode.style.fontSize = `${fontSize}px`; + // this._hover.contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; + const height = Math.max(this._editor.getLayoutInfo().height / 4, 250); const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo); + this._hover.contentsDomNode.style.fontSize = `${fontSize}px`; this._hover.contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; + this._hover.contentsDomNode.style.maxHeight = `${height}px`; + this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; } private _updateFont(): void { @@ -924,10 +1088,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { console.log(' * Entered into showAt of ContentHoverWidget'); - console.log('visibleData : ', visibleData); - console.log('node : ', node); - console.log('node.baseURI ', node.baseURI); - console.log('this._element.domNode : ', this._resizableElement.domNode); + // console.log('visibleData : ', visibleData); + // console.log('node : ', node); + // console.log('node.baseURI ', node.baseURI); + // console.log('this._element.domNode : ', this._resizableElement.domNode); + + this._hover.contentsDomNode.style.visibility = 'visibility'; this._setVisibleData(visibleData); @@ -940,27 +1106,31 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' - console.log('Before render'); - console.log('this._element.domNode : ', this._resizableElement.domNode); + // console.log('Before render'); + // console.log('this._element.domNode : ', this._resizableElement.domNode); this._editor.render(); - console.log('After render'); - console.log('this._element.domNode : ', this._resizableElement.domNode); + // console.log('After render'); + // console.log('this._element.domNode : ', this._resizableElement.domNode); // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor this.onContentsChanged(); - console.log('After onContentsChanged'); - console.log('this._element.domNode : ', this._resizableElement.domNode); + // console.log('After onContentsChanged'); + // console.log('this._element.domNode : ', this._resizableElement.domNode); if (visibleData.stoleFocus) { this._hover.containerDomNode.focus(); } visibleData.colorPicker?.layout(); - this._setLayoutOfResizableElement(); + // TODO: Place back + // this._setLayoutOfResizableElement(); + console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); } public hide(): void { + console.log('Inside of hide'); this._resizableElement.clearSashHoverState(); + this._resizableElement.layout(0, 0); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); @@ -972,15 +1142,37 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public onContentsChanged(): void { + console.log('Inside of contents changed'); + let containerDomNode = this.getDomNode(); + let offsetWidth = containerDomNode.offsetWidth; + let clientWidth = containerDomNode.clientWidth; + let clientHeight = containerDomNode.clientHeight; + let scrollWidth = containerDomNode.scrollWidth; + let width = containerDomNode.style.width; + console.log('offsetWidth : ', offsetWidth); + console.log('clientWidth : ', clientWidth); + console.log('scrollWidth : ', scrollWidth); + console.log('width : ', width); + + let contentsDomNode = this.getContentsDomNode(); + let contentsOffsetWidth = contentsDomNode.offsetWidth; + let contentsClientWidth = contentsDomNode.clientWidth; + let contentsScrollWidth = contentsDomNode.scrollWidth; + let contentsWidth = contentsDomNode.style.width; + console.log('contentsOffsetWidth : ', contentsOffsetWidth); + console.log('contentsClientWidth : ', contentsClientWidth); + console.log('contentsScrollWidth : ', contentsScrollWidth); + console.log('contentsWidth : ', contentsWidth); + this._editor.layoutContentWidget(this); this._hover.onContentsChanged(); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); - console.log('Inside of onContentsChanged'); - console.log('scrollDimensions : ', scrollDimensions); + // console.log('Inside of onContentsChanged'); + // console.log('scrollDimensions : ', scrollDimensions); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); if (hasHorizontalScrollbar) { - console.log('Entered into hasHorizontalScrollbar'); + // console.log('Entered into hasHorizontalScrollbar'); // There is just a horizontal scrollbar const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { @@ -989,6 +1181,38 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.onContentsChanged(); } } + + containerDomNode = this.getDomNode(); + offsetWidth = containerDomNode.offsetWidth; + clientWidth = containerDomNode.clientWidth; + clientHeight = containerDomNode.clientHeight; + scrollWidth = containerDomNode.scrollWidth; + width = containerDomNode.style.width; + console.log('offsetWidth : ', offsetWidth); + console.log('clientWidth : ', clientWidth); + console.log('scrollWidth : ', scrollWidth); + console.log('width : ', width); + + contentsDomNode = this.getContentsDomNode(); + contentsOffsetWidth = contentsDomNode.offsetWidth; + contentsClientWidth = contentsDomNode.clientWidth; + contentsScrollWidth = contentsDomNode.scrollWidth; + contentsWidth = contentsDomNode.style.width; + console.log('contentsOffsetWidth : ', contentsOffsetWidth); + console.log('contentsClientWidth : ', contentsClientWidth); + console.log('contentsScrollWidth : ', contentsScrollWidth); + console.log('contentsWidth : ', contentsWidth); + + + console.log('this._resizableWidget : ', this._resizableWidget); + if (!this._resizableWidget) { + console.log('early returns'); + return; + } + console.log('setting the layout of the resizable element'); + this._resizableWidget.resizableElement().layout(clientHeight, clientWidth); + this._editor.layoutOverlayWidget(this._resizableWidget); + this._editor.render(); } public clear(): void { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 03a2626ef908d..ba0f1e271a80a 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -502,11 +502,11 @@ declare namespace monaco { /** * line number (starts at 1) */ - readonly lineNumber: number; + lineNumber: number; /** * column (the first character in a line is between column 1 and column 2) */ - readonly column: number; + column: number; constructor(lineNumber: number, column: number); /** * Create a new position from this position. From 7b6261d1d8a1a5bf2be37af6df4610c62dd8018b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 16 Mar 2023 16:37:53 +0100 Subject: [PATCH 36/95] Work in progress, improvement --- src/vs/base/browser/ui/hover/hover.css | 1 - .../contrib/hover/browser/contentHover.ts | 274 ++++++++++++------ src/vs/editor/contrib/hover/browser/hover.css | 2 +- src/vs/editor/contrib/hover/browser/hover.ts | 16 +- 4 files changed, 197 insertions(+), 96 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 5d877dcde7b20..57a366d59e840 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -28,7 +28,6 @@ } .monaco-hover .markdown-hover > .hover-contents:not(.code-hover-contents) { - max-width: 500px; word-wrap: break-word; } diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index b89fa96196c84..5ea3aae68dea0 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -24,7 +24,9 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Context as SuggestContext } from 'vs/editor/contrib/suggest/browser/suggest'; import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; +import { IResizeEvent, ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; +import { Emitter, Event } from 'vs/base/common/event'; +import { ConsoleObservableLogger } from 'vs/base/common/observableImpl/logging'; const $ = dom.$; @@ -41,7 +43,8 @@ export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; private readonly _resizableWidget = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); - private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor, this._contextKeyService, this._resizableWidget)); + private readonly _focusTracker = this._register(dom.trackFocus(this._resizableWidget.getDomNode())); + private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; @@ -56,9 +59,12 @@ export class ContentHoverController extends Disposable { ) { super(); - // const widgetPosition = this._widget.getPosition(); - // console.log('widgetPosition : ', widgetPosition); - // this._resizableWidget.setPosition(widgetPosition); + this._register(this._focusTracker.onDidFocus(() => { + console.log('On did focus on resizable widget'); + })); + this._register(this._focusTracker.onDidBlur(() => { + console.log('on did blur on resizable widget'); + })); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; @@ -93,6 +99,15 @@ export class ContentHoverController extends Disposable { this._register(this._editor.onDidChangeModel(() => { this._resizableWidget.hide(); })); + + this._register(this._resizableWidget.onDidResize((e) => { + console.log('Inside of the listener of the resizable widget size'); + this._widget.resize(e.dimension); + })); + } + + get resizableWidget() { + return this._resizableWidget; } /** @@ -200,6 +215,7 @@ export class ContentHoverController extends Disposable { } private _setCurrentResult(hoverResult: HoverResult | null): void { + console.log('hover result : ', hoverResult); if (this._currentResult === hoverResult) { // avoid updating the DOM to avoid resetting the user selection return; @@ -217,6 +233,7 @@ export class ContentHoverController extends Disposable { } public hide(): void { + console.log('Inside of hide of content hover controller'); this._computer.anchor = null; this._hoverOperation.cancel(); this._setCurrentResult(null); @@ -335,39 +352,18 @@ export class ContentHoverController extends Disposable { this._editor.layoutContentWidget(this._widget); this._editor.render(); - // showAtPosition.lineNumber = showAtPosition.lineNumber + 10; - const containerDomNode = this._widget.getDomNode(); - const offsetWidth = containerDomNode.offsetWidth; - const clientWidth = containerDomNode.clientWidth; - const scrollWidth = containerDomNode.scrollWidth; - const width = containerDomNode.style.width; - console.log('offsetWidth : ', offsetWidth); - console.log('clientWidth : ', clientWidth); - console.log('scrollWidth : ', scrollWidth); - console.log('width : ', width); - - const contentsDomNode = this._widget.getContentsDomNode(); - const contentsOffsetWidth = contentsDomNode.offsetWidth; - const contentsClientWidth = contentsDomNode.clientWidth; - const contentsScrollWidth = contentsDomNode.scrollWidth; - const contentsWidth = contentsDomNode.style.width; - console.log('contentsOffsetWidth : ', contentsOffsetWidth); - console.log('contentsClientWidth : ', contentsClientWidth); - console.log('contentsScrollWidth : ', contentsScrollWidth); - console.log('contentsWidth : ', contentsWidth); - - console.log('this._widget.getDomNode() : ', this._widget.getDomNode()); - const size = new dom.Dimension(this._widget.getDomNode().clientWidth, this._widget.getDomNode().clientHeight); - console.log('this._widget.size() : ', this._widget.getSize()); - console.log('Before this._resizableWidget.showAt'); - console.log('clientTop: this._widget.getDomNode().clientTop : ', this._widget.getDomNode().clientTop); - console.log('clientTop: this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); - console.log('clientTop: this._widget.getDomNode().style.top : ', this._widget.getDomNode().style.top); - const position = { clientTop: this._widget.getDomNode().offsetTop, clientLeft: this._widget.getDomNode().offsetLeft }; + console.log('offsetLeft : ', this._widget.getDomNode().offsetLeft); + console.log('offsetTop : ', this._widget.getDomNode().offsetTop); + console.log('scrollLeft : ', this._widget.getDomNode().scrollLeft); + console.log('scrollTop : ', this._widget.getDomNode().scrollTop); + + // TODO: Unclear why we need to add these values which appear to be consistent + const position = { clientTop: this._widget.getDomNode().offsetTop - 84, clientLeft: this._widget.getDomNode().offsetLeft - 218 }; + console.log('position used when showing the overlay widget, position : ', position); this._resizableWidget.showAt(position, size); - this._editor.layoutOverlayWidget(this._resizableWidget); - this._editor.render(); + // this._editor.layoutOverlayWidget(this._resizableWidget); + // this._editor.render(); } else { disposables.dispose(); } @@ -488,7 +484,17 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget static readonly ID = 'editor.contrib.resizableHoverOverlay'; private _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); - private _position: IContentWidgetPosition | null = null; + private _resizing: boolean = false; + private readonly _persistedHoverWidgetSizes = new Map>(); + private _size: dom.Dimension | null = null; + private _initialHeight: number = -1; + private _initialTop: number = -1; + private _maxRenderingHeight: number | undefined = 10000; + private _position: IPosition | null = null; + private _renderingAbove: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; + + private readonly _onDidResize = new Emitter(); + readonly onDidResize: Event = this._onDidResize.event; constructor(private readonly _editor: ICodeEditor) { super(); @@ -497,12 +503,129 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._editor.addOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '100'; this._resizableElement.domNode.style.position = 'fixed'; + + let state: ResizeState | undefined; + + this._register(this._resizableElement.onDidWillResize(() => { + console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); + const persistedSize = this._findPersistedSize(); + state = new ResizeState(persistedSize, this._resizableElement.size); + this._resizing = true; + this._initialHeight = this._resizableElement.domNode.clientHeight; + this._initialTop = this._resizableElement.domNode.offsetTop; + })); + this._register(this._resizableElement.onDidResize(e => { + console.log('* Inside of onDidResize of ContentHoverWidget'); + console.log('e : ', e); + let height = e.dimension.height; + let width = e.dimension.width; + const maxWidth = this._resizableElement.maxSize.width; + const maxHeight = this._resizableElement.maxSize.height; + width = Math.min(maxWidth, width); + height = Math.min(maxHeight, height); + if (!this._maxRenderingHeight) { + return; + } + this._size = new dom.Dimension(width, height); + console.log('this._initialTop : ', this._initialTop); + console.log('this._intiialHeight : ', this._initialHeight); + console.log('height : ', height); + console.log('this._initialTop - (height - this._initialHeight) : ', this._initialTop - (height - this._initialHeight)); + this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; + this._onDidResize.fire({ dimension: this._size, done: false }); + this._resizableElement.layout(height, width); + // this._maxRenderingHeight = this._findMaxRenderingHeight(); + if (!this._maxRenderingHeight) { + return; + } + this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); + + if (state) { + state.persistHeight = state.persistHeight || !!e.north || !!e.south; + state.persistWidth = state.persistWidth || !!e.east || !!e.west; + } + if (!e.done) { + return; + } + if (state) { + if (!this._editor.hasModel()) { + return; + } + const uri = this._editor.getModel().uri.toString(); + if (!uri) { + return; + } + const persistedSize = new dom.Dimension(width, height); + if (!this._position) { + return; + } + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._position); + if (!wordPosition || !this._editor.hasModel()) { + return; + } + const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._position.lineNumber, column: wordPosition.startColumn }); + const length = wordPosition.word.length; + + if (!this._persistedHoverWidgetSizes.get(uri)) { + const map = new Map([]); + map.set(JSON.stringify([offset, length]), persistedSize); + this._persistedHoverWidgetSizes.set(uri, map); + } else { + const map = this._persistedHoverWidgetSizes.get(uri)!; + map.set(JSON.stringify([offset, length]), persistedSize); + } + } + if (e.done) { + console.log('Inside of the case when done'); + this._resizing = false; + } + + this._editor.layoutOverlayWidget(this); + this._editor.render(); + + })); + state = undefined; + } + + public get size(): dom.Dimension | null { + return this._size; + } + + private _findPersistedSize(): dom.Dimension | undefined { + // console.log('Inside of _findPersistedSize'); + if (!this._position) { + return; + } + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._position); + if (!wordPosition || !this._editor.hasModel()) { + return; + } + const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._position.lineNumber, column: wordPosition.startColumn }); + const length = wordPosition.word.length; + const uri = this._editor.getModel().uri.toString(); + // console.log('offset : ', offset); + // console.log('length : ', length); + const textModelMap = this._persistedHoverWidgetSizes.get(uri); + // console.log('textModelMap : ', textModelMap); + if (!textModelMap) { + return; + } + // console.log('textModelMap.value : ', textModelMap.entries().next().value); + return textModelMap.get(JSON.stringify([offset, length])); + } + + public isResizing(): boolean { + return this._resizing; } public hide(): void { console.log('hiding the resizable hover overlay'); + this._resizableElement.enableSashes(false, false, false, false); this._resizableElement.clearSashHoverState(); - this._resizableElement.layout(0, 0); + // this._resizableElement.layout(0, 0); + // this._editor.layoutOverlayWidget(this); + this._editor.removeOverlayWidget(this); + this._editor.render(); } public resizableElement(): ResizableHTMLElement { @@ -540,7 +663,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // this._position = widgetPosition; console.log('position : ', position); console.log('size : ', size); - + this._editor.addOverlayWidget(this); this._resizableElement.enableSashes(true, true, true, true); this._resizableElement.domNode.style.top = position.clientTop + 'px'; this._resizableElement.domNode.style.left = position.clientLeft + 'px'; @@ -566,7 +689,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hover: HoverWidget = this._register(new HoverWidget()); private _visibleData: ContentHoverVisibleData | null = null; - private _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); + private _resizableHoverOverlay: ResizableHoverOverlay | null = null; private _renderingAboveOption: boolean = this._editor.getOption(EditorOption.hover).above; private _renderingAbove = this._renderingAboveOption; private _maxRenderingHeight: number | undefined = -1; @@ -574,15 +697,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - private _resizeObserver: ResizeObserver = new ResizeObserver((entries) => { - // console.log('inside of resize observer for element: ', entries); - }); - private _resizeContentsObserver: ResizeObserver = new ResizeObserver((entries) => { - // console.log('inside of resize observer for contents: ', entries); - }); - private _resizeContainerObserver: ResizeObserver = new ResizeObserver((entries) => { - // console.log('inside of resize observer for container: ', entries); - }); /** * Returns `null` if the hover is not visible. @@ -605,15 +719,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { constructor( private readonly _editor: ICodeEditor, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, - private readonly _resizableWidget: ResizableHoverOverlay + @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(); - // console.log('Very beginning of constructor'); - // console.log('this._element.domNode : ', this._resizableElement.domNode); - this._resizeObserver.observe(this._resizableElement.domNode); - this._resizeContentsObserver.observe(this._hover.contentsDomNode); - this._resizeContainerObserver.observe(this._hover.containerDomNode); this._register(this._editor.onDidLayoutChange(() => this._layout())); this._register(this._editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => { @@ -721,6 +829,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { */ } + public setResizableHoverOverlay(resizablHoverOverlay: ResizableHoverOverlay): void { + this._resizableHoverOverlay = resizablHoverOverlay; + } + + public resize(size: dom.Dimension | null) { + console.log('Inside of the resize of the content hover widget'); + this._hover.containerDomNode.style.width = size?.width + 'px'; + this._hover.containerDomNode.style.height = size?.height + 'px'; + this._editor.layoutContentWidget(this); + this._editor.render(); + } + public getSize() { return new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); } @@ -745,6 +865,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return textModelMap.get(JSON.stringify([offset, length])); } + /* private _setLayoutOfResizableElement(): void { // console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); @@ -863,32 +984,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.width = `${width - 2}px`; this._hover.contentsDomNode.style.overflow = 'hidden'; - // TODO: Replaces the scanDomNode() call below - /* - this._hover.scrollbar.setScrollDimensions({ - width: width - 2, - height: height - 2, - scrollWidth: this._hover.contentsDomNode.scrollWidth + 20, - scrollHeight: this._hover.contentsDomNode.scrollHeight + 20 - }); - this._hover.scrollbar.setScrollPosition({ - scrollLeft: this._hover.contentsDomNode.scrollLeft, - scrollTop: this._hover.contentsDomNode.scrollTop, - }); - */ - - // console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - // console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); - // console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); - // console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); - - // TODO: place back this._hover.scrollbar.scanDomNode(); // console.log('Before layoutContentWidget'); this._editor.layoutContentWidget(this); this._editor.render(); // console.log('this.getDomNode() : ', this.getDomNode()); } + */ private _findMaxRenderingHeight(): number | undefined { if (!this._editor || !this._editor.hasModel()) { @@ -920,6 +1022,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // Initiall height and width are the maximmum dimensions to give to the hover + /* private _resize(width: number, height: number): void { console.log(' * Entered into the _resize function of ContentHoverWidget'); @@ -969,8 +1072,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); } + */ public override dispose(): void { + console.log('Inside of dispose of the ContentHoverWidget'); this._editor.removeContentWidget(this); if (this._visibleData) { this._visibleData.disposables.dispose(); @@ -1063,7 +1168,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._visibleData = visibleData; this._hoverVisibleKey.set(!!this._visibleData); this._hover.containerDomNode.classList.toggle('hidden', !this._visibleData); - this._resizableElement.domNode.classList.toggle('hidden', !this._visibleData); } private _layout(): void { @@ -1128,9 +1232,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public hide(): void { - console.log('Inside of hide'); - this._resizableElement.clearSashHoverState(); - this._resizableElement.layout(0, 0); + + console.log('Inside of hide of the content hover widget'); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); @@ -1202,17 +1305,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsClientWidth : ', contentsClientWidth); console.log('contentsScrollWidth : ', contentsScrollWidth); console.log('contentsWidth : ', contentsWidth); - - - console.log('this._resizableWidget : ', this._resizableWidget); - if (!this._resizableWidget) { - console.log('early returns'); - return; - } - console.log('setting the layout of the resizable element'); - this._resizableWidget.resizableElement().layout(clientHeight, clientWidth); - this._editor.layoutOverlayWidget(this._resizableWidget); - this._editor.render(); } public clear(): void { diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index f69d1975177b4..58246c7bf3c1d 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -30,5 +30,5 @@ } .monaco-editor .resizable-hover { - z-index: 50; + z-index: 5; } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 290d1f9b7261c..054c4e955e230 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -15,7 +15,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { GotoDefinitionAtPositionEditorContribution } from 'vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition'; import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation'; -import { ContentHoverWidget, ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHover'; +import { ContentHoverWidget, ContentHoverController, ResizableHoverOverlay } from 'vs/editor/contrib/hover/browser/contentHover'; import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHover'; import * as nls from 'vs/nls'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; @@ -118,10 +118,14 @@ export class ModesHoverController implements IEditorContribution { return; } + if (target.type === MouseTargetType.OVERLAY_WIDGET && target.detail === ResizableHoverOverlay.ID) { + return; + } + if (target.type !== MouseTargetType.OVERLAY_WIDGET) { this._hoverClicked = false; } - + console.log('mouseEvent : ', mouseEvent); this._hideWidgets(); } @@ -210,6 +214,7 @@ export class ModesHoverController implements IEditorContribution { if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift && !mightTriggerFocus) { // Do not hide hover when a modifier key is pressed + this._hideWidgets(); } } @@ -219,9 +224,14 @@ export class ModesHoverController implements IEditorContribution { return; } + console.log('Inside of _hideWidgets'); this._hoverClicked = false; this._glyphWidget?.hide(); - this._contentWidget?.hide(); + console.log('this._contentWidget?.resizableWidget.isResizing() : ', this._contentWidget?.resizableWidget.isResizing()); + if (!this._contentWidget?.resizableWidget.isResizing()) { + console.log('Hiding the content widget'); + this._contentWidget?.hide(); + } } private _getOrCreateContentWidget(): ContentHoverController { From 0bcf469b02a6eda30517f9a6d4f16280d3c5fa5e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 16 Mar 2023 16:51:37 +0100 Subject: [PATCH 37/95] Placed css in different places and added pointer events none in order to allow scroll events detected by the lower layer --- src/vs/editor/contrib/hover/browser/contentHover.ts | 11 +++++++---- src/vs/editor/contrib/hover/browser/hover.css | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 5ea3aae68dea0..33564b086c1b3 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -61,9 +61,7 @@ export class ContentHoverController extends Disposable { this._register(this._focusTracker.onDidFocus(() => { console.log('On did focus on resizable widget'); - })); - this._register(this._focusTracker.onDidBlur(() => { - console.log('on did blur on resizable widget'); + this._widget.focus(); })); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. @@ -359,7 +357,7 @@ export class ContentHoverController extends Disposable { console.log('scrollTop : ', this._widget.getDomNode().scrollTop); // TODO: Unclear why we need to add these values which appear to be consistent - const position = { clientTop: this._widget.getDomNode().offsetTop - 84, clientLeft: this._widget.getDomNode().offsetLeft - 218 }; + const position = { clientTop: this._widget.getDomNode().offsetTop, clientLeft: this._widget.getDomNode().offsetLeft }; console.log('position used when showing the overlay widget, position : ', position); this._resizableWidget.showAt(position, size); // this._editor.layoutOverlayWidget(this._resizableWidget); @@ -502,6 +500,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // TODO: When the following is added the initial content hover appears to disappear this._editor.addOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '100'; + this._resizableElement.domNode.tabIndex = 0; this._resizableElement.domNode.style.position = 'fixed'; let state: ResizeState | undefined; @@ -668,6 +667,10 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.domNode.style.top = position.clientTop + 'px'; this._resizableElement.domNode.style.left = position.clientLeft + 'px'; this._resizableElement.layout(size.height + 4, size.width + 4); + this._resizableElement.domNode.style.zIndex = '100'; + this._resizableElement.domNode.tabIndex = 0; + this._resizableElement.domNode.style.position = 'fixed'; + this._resizableElement.domNode.style.pointerEvents = 'none'; this._editor.layoutOverlayWidget(this); this._editor.render(); const resizableDomNode = this._resizableElement.domNode; diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 58246c7bf3c1d..7c47450911cfb 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -31,4 +31,5 @@ .monaco-editor .resizable-hover { z-index: 5; + pointer-events: none; } From 8ba746a4c1b39681d113541c2405f87b0390d4d8 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 11:04:40 +0100 Subject: [PATCH 38/95] Saving changes before changing back to a content widget --- .../editor/browser/widget/codeEditorWidget.ts | 1 + .../contrib/hover/browser/contentHover.ts | 269 ++++++++++-------- src/vs/editor/contrib/hover/browser/hover.css | 9 +- src/vs/editor/contrib/hover/browser/hover.ts | 6 +- 4 files changed, 164 insertions(+), 121 deletions(-) diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 93c7923c14be5..ca86c515a731c 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1489,6 +1489,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE public layoutOverlayWidget(widget: editorBrowser.IOverlayWidget): void { const widgetId = widget.getId(); if (this._overlayWidgets.hasOwnProperty(widgetId)) { + console.log('Entered into the if statement of layoutOverlayWidget'); const widgetData = this._overlayWidgets[widgetId]; widgetData.position = widget.getPosition(); if (this._modelData && this._modelData.hasRealView) { diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 33564b086c1b3..7277a5b96cb5d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -26,7 +26,6 @@ import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IResizeEvent, ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { Emitter, Event } from 'vs/base/common/event'; -import { ConsoleObservableLogger } from 'vs/base/common/observableImpl/logging'; const $ = dom.$; @@ -55,7 +54,6 @@ export class ContentHoverController extends Disposable { private readonly _editor: ICodeEditor, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IKeybindingService private readonly _keybindingService: IKeybindingService, - @IContextKeyService private readonly _contextKeyService: IContextKeyService ) { super(); @@ -79,7 +77,7 @@ export class ContentHoverController extends Disposable { // invalid state, ignore result return; } - console.log('this result of the hover operation is attained'); + console.log('* Result of the hover operation is attained'); const messages = (result.hasLoadingMessage ? this._addLoadingMessage(result.value) : result.value); this._withResult(new HoverResult(this._computer.anchor, messages, result.isComplete)); })); @@ -99,9 +97,12 @@ export class ContentHoverController extends Disposable { })); this._register(this._resizableWidget.onDidResize((e) => { - console.log('Inside of the listener of the resizable widget size'); this._widget.resize(e.dimension); })); + + this._register(this._editor.onDidScrollChange(() => { + + })); } get resizableWidget() { @@ -213,7 +214,7 @@ export class ContentHoverController extends Disposable { } private _setCurrentResult(hoverResult: HoverResult | null): void { - console.log('hover result : ', hoverResult); + // console.log('hover result : ', hoverResult); if (this._currentResult === hoverResult) { // avoid updating the DOM to avoid resetting the user selection return; @@ -231,7 +232,7 @@ export class ContentHoverController extends Disposable { } public hide(): void { - console.log('Inside of hide of content hover controller'); + // console.log('Inside of hide of content hover controller'); this._computer.anchor = null; this._hoverOperation.cancel(); this._setCurrentResult(null); @@ -299,6 +300,7 @@ export class ContentHoverController extends Disposable { statusBar, setColorPicker: (widget) => colorPicker = widget, onContentsChanged: () => { + console.log('Inside of onContentsChanged of the context inside of _renderMessage'); this._widget.onContentsChanged(); const clientWidth = this._widget.getDomNode().clientWidth; const clientHeight = this._widget.getDomNode().clientHeight; @@ -334,7 +336,7 @@ export class ContentHoverController extends Disposable { })); } const preferAbove = this._editor.getOption(EditorOption.hover).above; - console.log('Before this._widget.showAt'); + console.log('* Before this._widget.showAt'); this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, showAtPosition, @@ -347,21 +349,47 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosY, disposables )); + console.log('* After this._widget.showAt'); + console.log('* Before layoutContentWidget and render'); + // Before there wasn't any of this below this._editor.layoutContentWidget(this._widget); this._editor.render(); + console.log('* After layoutContentWidget and render'); + const containerDomNode = this._widget.getDomNode(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + const contentsDomNode = this._widget.getContentsDomNode(); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); const size = new dom.Dimension(this._widget.getDomNode().clientWidth, this._widget.getDomNode().clientHeight); - console.log('offsetLeft : ', this._widget.getDomNode().offsetLeft); - console.log('offsetTop : ', this._widget.getDomNode().offsetTop); - console.log('scrollLeft : ', this._widget.getDomNode().scrollLeft); - console.log('scrollTop : ', this._widget.getDomNode().scrollTop); - - // TODO: Unclear why we need to add these values which appear to be consistent + console.log('size : ', size); const position = { clientTop: this._widget.getDomNode().offsetTop, clientLeft: this._widget.getDomNode().offsetLeft }; - console.log('position used when showing the overlay widget, position : ', position); + console.log('position : ', position); + + console.log('* Before showAt of resizableWidget'); + let resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + this._resizableWidget.showAt(position, size); - // this._editor.layoutOverlayWidget(this._resizableWidget); - // this._editor.render(); + + console.log('* After showAt of resizableWidget'); + resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); } else { disposables.dispose(); } @@ -488,7 +516,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget private _initialHeight: number = -1; private _initialTop: number = -1; private _maxRenderingHeight: number | undefined = 10000; - private _position: IPosition | null = null; + private _tooltipPosition: IPosition | null = null; + private _renderingPosition: IOverlayWidgetPosition | null = null; private _renderingAbove: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; private readonly _onDidResize = new Emitter(); @@ -497,11 +526,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget constructor(private readonly _editor: ICodeEditor) { super(); console.log('Inside of constructor of ResizableHoverOverlay'); - // TODO: When the following is added the initial content hover appears to disappear - this._editor.addOverlayWidget(this); - this._resizableElement.domNode.style.zIndex = '100'; - this._resizableElement.domNode.tabIndex = 0; - this._resizableElement.domNode.style.position = 'fixed'; + // TODO: persist sizes during the session instead of persisting on reload + // TODO: The resizable element size does not align with the container dom size when there is not enouhg space for normal rendering + // TODO: Upon resizing the, the persisted size is used everywhere, even if previously was not used everywhere + // TODO: Calculate correctly the container dom node size and resizable container dom node size + // TODO: When hovering over the scroll dom, show the scrollbar let state: ResizeState | undefined; @@ -555,14 +584,14 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return; } const persistedSize = new dom.Dimension(width, height); - if (!this._position) { + if (!this._tooltipPosition) { return; } - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._position); + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._tooltipPosition); if (!wordPosition || !this._editor.hasModel()) { return; } - const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._position.lineNumber, column: wordPosition.startColumn }); + const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; if (!this._persistedHoverWidgetSizes.get(uri)) { @@ -590,16 +619,24 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._size; } + public get initialTop(): number { + return this._initialTop; + } + + public get initialHeight(): number { + return this._initialTop; + } + private _findPersistedSize(): dom.Dimension | undefined { // console.log('Inside of _findPersistedSize'); - if (!this._position) { + if (!this._tooltipPosition) { return; } - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._position); + const wordPosition = this._editor.getModel()?.getWordAtPosition(this._tooltipPosition); if (!wordPosition || !this._editor.hasModel()) { return; } - const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._position.lineNumber, column: wordPosition.startColumn }); + const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; const uri = this._editor.getModel().uri.toString(); // console.log('offset : ', offset); @@ -640,44 +677,73 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._resizableElement.domNode; } - public setPosition(position: any): void { - console.log('Inside of setPosition of ResizableHOverOverlay'); - console.log('this._position : ', this._position); - this._position = position; - if (!position || !position.position) { - return; - } - this._resizableElement.domNode.style.top = position.clientTop + 'px'; - this._resizableElement.domNode.style.left = position.clientLeft + 'px'; + public setToooltipPosition(position: IPosition): void { + console.log('Inside of setTooltipPosition of ResizableHOverOverlay'); + console.log('this._position : ', this._tooltipPosition); + this._tooltipPosition = position; + } + + public setPosition(renderingPosition: IOverlayWidgetPosition): void { + this._renderingPosition = renderingPosition; } public getPosition(): IOverlayWidgetPosition | null { console.log('Inside of getPosition of ResizableHoverOverlay'); - console.log('this._position : ', this._position); - return null; + console.log('this._renderingPosition : ', this._renderingPosition); + return this._renderingPosition; } + + // TODO; The problem with not being able to change the height is most probably linked to the persisting of the height too public showAt(position: any, size: dom.Dimension): void { console.log('Inside of showAt of ResizableHoverOverlay'); - // this._position = widgetPosition; - console.log('position : ', position); - console.log('size : ', size); + this._editor.addOverlayWidget(this); + console.log('After add overlay widget'); + let resizableWidgetDomNode = this.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + this._resizableElement.enableSashes(true, true, true, true); - this._resizableElement.domNode.style.top = position.clientTop + 'px'; - this._resizableElement.domNode.style.left = position.clientLeft + 'px'; + this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; + this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; + + this._resizableElement.domNode.style.height = size.height + 4 + 'px'; + this._resizableElement.domNode.style.width = size.width + 4 + 'px'; this._resizableElement.layout(size.height + 4, size.width + 4); - this._resizableElement.domNode.style.zIndex = '100'; + + console.log('After layout'); + resizableWidgetDomNode = this.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + + this._resizableElement.domNode.style.zIndex = '5'; this._resizableElement.domNode.tabIndex = 0; this._resizableElement.domNode.style.position = 'fixed'; - this._resizableElement.domNode.style.pointerEvents = 'none'; + this._editor.layoutOverlayWidget(this); + console.log('After layout overlay widget'); + resizableWidgetDomNode = this.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + this._editor.render(); - const resizableDomNode = this._resizableElement.domNode; - console.log('this._resizableElement.domNode : ', resizableDomNode); - console.log('resizableDomNode.clientWidth : ', resizableDomNode.clientWidth); - console.log('resizableDomNode.clientHeight : ', resizableDomNode.clientHeight); - console.log('this._resizableElement.size : ', this._resizableElement.size); + console.log('After render'); + resizableWidgetDomNode = this.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); } } @@ -1091,10 +1157,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getDomNode(): HTMLElement { - // return this._resizableElement.domNode; - // Forcing the visiblity: - // this._hover.containerDomNode.style.display = 'block'; - // this._hover.containerDomNode.style.visibility = 'visible'; return this._hover.containerDomNode; } @@ -1174,10 +1236,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } private _layout(): void { - // TODO: place back - // const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo); - // this._hover.contentsDomNode.style.fontSize = `${fontSize}px`; - // this._hover.contentsDomNode.style.lineHeight = `${lineHeight / fontSize}`; const height = Math.max(this._editor.getLayoutInfo().height / 4, 250); const { fontSize, lineHeight } = this._editor.getOption(EditorOption.fontInfo); @@ -1195,13 +1253,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { console.log(' * Entered into showAt of ContentHoverWidget'); - // console.log('visibleData : ', visibleData); - // console.log('node : ', node); - // console.log('node.baseURI ', node.baseURI); - // console.log('this._element.domNode : ', this._resizableElement.domNode); - - this._hover.contentsDomNode.style.visibility = 'visibility'; - + // this._hover.contentsDomNode.style.visibility = 'visibility'; this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -1209,33 +1261,38 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.paddingBottom = ''; this._updateFont(); + console.log('* Before the first onContentsChanged of showAt of ContentHoverWidget'); this.onContentsChanged(); // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' - // console.log('Before render'); - // console.log('this._element.domNode : ', this._resizableElement.domNode); this._editor.render(); - // console.log('After render'); - // console.log('this._element.domNode : ', this._resizableElement.domNode); + console.log('* After render inside of showAt of ContentHoverWidget'); + const containerDomNode = this.getDomNode(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + const contentsDomNode = this.getContentsDomNode(); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor + console.log('* Before the second onContentsChanged of showAt of ContentHoverWidget'); this.onContentsChanged(); - // console.log('After onContentsChanged'); - // console.log('this._element.domNode : ', this._resizableElement.domNode); if (visibleData.stoleFocus) { this._hover.containerDomNode.focus(); } visibleData.colorPicker?.layout(); - // TODO: Place back - // this._setLayoutOfResizableElement(); - console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); } public hide(): void { - console.log('Inside of hide of the content hover widget'); if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; @@ -1248,27 +1305,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public onContentsChanged(): void { - console.log('Inside of contents changed'); + console.log('* Inside of contents changed'); + console.log('* Before changes'); let containerDomNode = this.getDomNode(); - let offsetWidth = containerDomNode.offsetWidth; - let clientWidth = containerDomNode.clientWidth; - let clientHeight = containerDomNode.clientHeight; - let scrollWidth = containerDomNode.scrollWidth; - let width = containerDomNode.style.width; - console.log('offsetWidth : ', offsetWidth); - console.log('clientWidth : ', clientWidth); - console.log('scrollWidth : ', scrollWidth); - console.log('width : ', width); - + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); let contentsDomNode = this.getContentsDomNode(); - let contentsOffsetWidth = contentsDomNode.offsetWidth; - let contentsClientWidth = contentsDomNode.clientWidth; - let contentsScrollWidth = contentsDomNode.scrollWidth; - let contentsWidth = contentsDomNode.style.width; - console.log('contentsOffsetWidth : ', contentsOffsetWidth); - console.log('contentsClientWidth : ', contentsClientWidth); - console.log('contentsScrollWidth : ', contentsScrollWidth); - console.log('contentsWidth : ', contentsWidth); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); this._editor.layoutContentWidget(this); this._hover.onContentsChanged(); @@ -1288,26 +1338,19 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } + console.log('* After changes'); containerDomNode = this.getDomNode(); - offsetWidth = containerDomNode.offsetWidth; - clientWidth = containerDomNode.clientWidth; - clientHeight = containerDomNode.clientHeight; - scrollWidth = containerDomNode.scrollWidth; - width = containerDomNode.style.width; - console.log('offsetWidth : ', offsetWidth); - console.log('clientWidth : ', clientWidth); - console.log('scrollWidth : ', scrollWidth); - console.log('width : ', width); - + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); contentsDomNode = this.getContentsDomNode(); - contentsOffsetWidth = contentsDomNode.offsetWidth; - contentsClientWidth = contentsDomNode.clientWidth; - contentsScrollWidth = contentsDomNode.scrollWidth; - contentsWidth = contentsDomNode.style.width; - console.log('contentsOffsetWidth : ', contentsOffsetWidth); - console.log('contentsClientWidth : ', contentsClientWidth); - console.log('contentsScrollWidth : ', contentsScrollWidth); - console.log('contentsWidth : ', contentsWidth); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); } public clear(): void { diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 7c47450911cfb..b667c09e174c0 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ .monaco-editor .hoverHighlight { - background-color: var(--vscode-editor-hoverHighlightBackground); + background-color: transparent; } .monaco-editor .monaco-hover { color: var(--vscode-editorHoverWidget-foreground); - background-color: var(--vscode-editorHoverWidget-background); + background-color: transparent; border: 1px solid var(--vscode-editorHoverWidget-border); } @@ -22,14 +22,13 @@ } .monaco-editor .monaco-hover .hover-row .actions { - background-color: var(--vscode-editorHoverWidget-statusBarBackground); + background-color: transparent; } .monaco-editor .monaco-hover code { - background-color: var(--vscode-textCodeBlock-background); + background-color: transparent; } .monaco-editor .resizable-hover { z-index: 5; - pointer-events: none; } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 054c4e955e230..9996939a57740 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -224,12 +224,12 @@ export class ModesHoverController implements IEditorContribution { return; } - console.log('Inside of _hideWidgets'); + // console.log('Inside of _hideWidgets'); this._hoverClicked = false; this._glyphWidget?.hide(); - console.log('this._contentWidget?.resizableWidget.isResizing() : ', this._contentWidget?.resizableWidget.isResizing()); + // console.log('this._contentWidget?.resizableWidget.isResizing() : ', this._contentWidget?.resizableWidget.isResizing()); if (!this._contentWidget?.resizableWidget.isResizing()) { - console.log('Hiding the content widget'); + // console.log('Hiding the content widget'); this._contentWidget?.hide(); } } From 6c438bb1b1d58ba6225abd6034b6becafd5982fa Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 11:44:58 +0100 Subject: [PATCH 39/95] Changed the code so that the sashes are around the content hover --- .../contrib/hover/browser/contentHover.ts | 67 ++++++++++++++++--- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 7277a5b96cb5d..168cd03d5a357 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -301,12 +301,27 @@ export class ContentHoverController extends Disposable { setColorPicker: (widget) => colorPicker = widget, onContentsChanged: () => { console.log('Inside of onContentsChanged of the context inside of _renderMessage'); + console.log('Before onContentsChanged'); + let resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); this._widget.onContentsChanged(); const clientWidth = this._widget.getDomNode().clientWidth; const clientHeight = this._widget.getDomNode().clientHeight; - this._resizableWidget.resizableElement().layout(clientHeight, clientWidth); + this._resizableWidget.resizableElement().layout(clientHeight + 4, clientWidth + 4); this._editor.layoutOverlayWidget(this._resizableWidget); this._editor.render(); + + resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('After onContentsChanged'); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); }, hide: () => this.hide() }; @@ -337,6 +352,13 @@ export class ContentHoverController extends Disposable { } const preferAbove = this._editor.getOption(EditorOption.hover).above; console.log('* Before this._widget.showAt'); + let resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, showAtPosition, @@ -361,12 +383,25 @@ export class ContentHoverController extends Disposable { console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + const contentsDomNode = this._widget.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + resizableWidgetDomNode = this._resizableWidget.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); const size = new dom.Dimension(this._widget.getDomNode().clientWidth, this._widget.getDomNode().clientHeight); console.log('size : ', size); @@ -374,7 +409,7 @@ export class ContentHoverController extends Disposable { console.log('position : ', position); console.log('* Before showAt of resizableWidget'); - let resizableWidgetDomNode = this._resizableWidget.getDomNode(); + resizableWidgetDomNode = this._resizableWidget.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); @@ -697,9 +732,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // TODO; The problem with not being able to change the height is most probably linked to the persisting of the height too public showAt(position: any, size: dom.Dimension): void { console.log('Inside of showAt of ResizableHoverOverlay'); + console.log('Before adding overlay widget'); - this._editor.addOverlayWidget(this); - console.log('After add overlay widget'); let resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); @@ -707,15 +741,10 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - this._resizableElement.enableSashes(true, true, true, true); - this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; - this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; - this._resizableElement.domNode.style.height = size.height + 4 + 'px'; - this._resizableElement.domNode.style.width = size.width + 4 + 'px'; - this._resizableElement.layout(size.height + 4, size.width + 4); - console.log('After layout'); + this._editor.addOverlayWidget(this); + console.log('After adding overlay widget'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); @@ -723,9 +752,24 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + this._resizableElement.enableSashes(true, true, false, false); + this._resizableElement.domNode.style.top = position.clientTop - 1 + 'px'; + this._resizableElement.domNode.style.left = position.clientLeft - 1 + 'px'; this._resizableElement.domNode.style.zIndex = '5'; this._resizableElement.domNode.tabIndex = 0; this._resizableElement.domNode.style.position = 'fixed'; + this._resizableElement.domNode.style.height = size.height + 'px'; + this._resizableElement.domNode.style.width = size.width + 'px'; + this._resizableElement.layout(size.height, size.width); + + + console.log('After style chamge of overlay widget'); + resizableWidgetDomNode = this.getDomNode(); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); + console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); this._editor.layoutOverlayWidget(this); console.log('After layout overlay widget'); @@ -1281,6 +1325,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor console.log('* Before the second onContentsChanged of showAt of ContentHoverWidget'); From 1e8ff811c6e1fac60e7dcc9ac5b97f70130b8b2c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 11:53:42 +0100 Subject: [PATCH 40/95] Changed the pixel sizes for better rendering --- .../editor/contrib/hover/browser/contentHover.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 168cd03d5a357..f97c6f7f32178 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -311,7 +311,7 @@ export class ContentHoverController extends Disposable { this._widget.onContentsChanged(); const clientWidth = this._widget.getDomNode().clientWidth; const clientHeight = this._widget.getDomNode().clientHeight; - this._resizableWidget.resizableElement().layout(clientHeight + 4, clientWidth + 4); + this._resizableWidget.resizableElement().layout(clientHeight + 7, clientWidth + 7); this._editor.layoutOverlayWidget(this._resizableWidget); this._editor.render(); @@ -741,8 +741,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - - this._editor.addOverlayWidget(this); console.log('After adding overlay widget'); resizableWidgetDomNode = this.getDomNode(); @@ -753,16 +751,15 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); this._resizableElement.enableSashes(true, true, false, false); - this._resizableElement.domNode.style.top = position.clientTop - 1 + 'px'; - this._resizableElement.domNode.style.left = position.clientLeft - 1 + 'px'; + this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; + this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; this._resizableElement.domNode.style.zIndex = '5'; this._resizableElement.domNode.tabIndex = 0; this._resizableElement.domNode.style.position = 'fixed'; - this._resizableElement.domNode.style.height = size.height + 'px'; - this._resizableElement.domNode.style.width = size.width + 'px'; + this._resizableElement.domNode.style.height = size.height + 7 + 'px'; + this._resizableElement.domNode.style.width = size.width + 7 + 'px'; this._resizableElement.layout(size.height, size.width); - console.log('After style chamge of overlay widget'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -799,7 +796,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public readonly allowEditorOverflow = true; - private readonly _hover: HoverWidget = this._register(new HoverWidget()); private _visibleData: ContentHoverVisibleData | null = null; private _resizableHoverOverlay: ResizableHoverOverlay | null = null; From 6b47b7ab35c81fad150d55db0e94da680fc56cf9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 15:18:50 +0100 Subject: [PATCH 41/95] persisting the widget sizes --- .../contrib/hover/browser/contentHover.ts | 236 ++++++++++-------- 1 file changed, 125 insertions(+), 111 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index f97c6f7f32178..133ab9d1ac518 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -308,7 +308,23 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - this._widget.onContentsChanged(); + + const persistedSize = this._resizableWidget.findPersistedSize(); + console.log('persistedSize : ', persistedSize); + this._widget.onContentsChanged(persistedSize); + this._editor.render(); + + console.log('After onContentsChanged'); + console.log('this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); + console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableWidget.getDomNode().offsetTop); + + const top = this._widget.getDomNode().offsetTop; + const left = this._widget.getDomNode().offsetLeft; + this._resizableWidget.resizableElement().domNode.style.top = top - 2 + 'px'; + this._resizableWidget.resizableElement().domNode.style.left = left - 2 + 'px'; + this._resizableWidget.resizableElement().domNode.style.zIndex = '5'; + this._resizableWidget.resizableElement().domNode.tabIndex = 0; + this._resizableWidget.resizableElement().domNode.style.position = 'fixed'; const clientWidth = this._widget.getDomNode().clientWidth; const clientHeight = this._widget.getDomNode().clientHeight; this._resizableWidget.resizableElement().layout(clientHeight + 7, clientWidth + 7); @@ -316,12 +332,27 @@ export class ContentHoverController extends Disposable { this._editor.render(); resizableWidgetDomNode = this._resizableWidget.getDomNode(); - console.log('After onContentsChanged'); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + + const containerDomNode = this._widget.getDomNode(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + const contentsDomNode = this._widget.getContentsDomNode(); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + + console.log('At the end of onContentsChanged of _renderMessages'); }, hide: () => this.hide() }; @@ -351,6 +382,22 @@ export class ContentHoverController extends Disposable { })); } const preferAbove = this._editor.getOption(EditorOption.hover).above; + + const tooltipPosition: IPosition = { lineNumber: showAtPosition.lineNumber, column: showAtPosition.column }; + this._resizableWidget.setToooltipPosition(tooltipPosition); + const persistedSize = this._resizableWidget.findPersistedSize(); + + console.log('persisted size : ', persistedSize); + + // Added here but does not seem to have an effect + if (persistedSize) { + this._widget.getDomNode().style.width = persistedSize.width + 'px'; + this._widget.getDomNode().style.height = persistedSize.height + 'px'; + this._editor.addContentWidget(this._widget); + this._editor.layoutContentWidget(this._widget); + this._editor.render(); + } + console.log('* Before this._widget.showAt'); let resizableWidgetDomNode = this._resizableWidget.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -567,11 +614,35 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // TODO: Calculate correctly the container dom node size and resizable container dom node size // TODO: When hovering over the scroll dom, show the scrollbar + this._editor.onDidChangeModelContent((e) => { + const uri = this._editor.getModel()?.uri.toString(); + if (!uri || !(uri in this._persistedHoverWidgetSizes)) { + return; + } + const mapToUpdate = this._persistedHoverWidgetSizes.get(uri)!; + for (const change of e.changes) { + const changeOffset = change.rangeOffset; + const length = change.rangeLength; + const endOffset = changeOffset + length; + for (const stringifiedEntry of mapToUpdate.keys()) { + const entry = JSON.parse(stringifiedEntry); + if (endOffset < entry[0]) { + const oldSize = mapToUpdate.get(entry)!; + const newEntry: [number, number] = [entry[0] + length, entry[1]]; + mapToUpdate.set(JSON.stringify(newEntry), oldSize); + mapToUpdate.delete(entry); + } else if (changeOffset < entry[0] + entry[1]) { + mapToUpdate.delete(entry); + } + } + } + }); + let state: ResizeState | undefined; this._register(this._resizableElement.onDidWillResize(() => { console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); - const persistedSize = this._findPersistedSize(); + const persistedSize = this.findPersistedSize(); state = new ResizeState(persistedSize, this._resizableElement.size); this._resizing = true; this._initialHeight = this._resizableElement.domNode.clientHeight; @@ -662,7 +733,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._initialTop; } - private _findPersistedSize(): dom.Dimension | undefined { + public findPersistedSize(): dom.Dimension | undefined { // console.log('Inside of _findPersistedSize'); if (!this._tooltipPosition) { return; @@ -852,90 +923,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._register(this._focusTracker.onDidBlur(() => { this._hoverFocusedKey.set(false); })); - /* - this._editor.onDidChangeModelContent((e) => { - const uri = this._editor.getModel()?.uri.toString(); - if (!uri || !(uri in this._persistedHoverWidgetSizes)) { - return; - } - const mapToUpdate = this._persistedHoverWidgetSizes.get(uri)!; - for (const change of e.changes) { - const changeOffset = change.rangeOffset; - const length = change.rangeLength; - const endOffset = changeOffset + length; - for (const stringifiedEntry of mapToUpdate.keys()) { - const entry = JSON.parse(stringifiedEntry); - if (endOffset < entry[0]) { - const oldSize = mapToUpdate.get(entry)!; - const newEntry: [number, number] = [entry[0] + length, entry[1]]; - mapToUpdate.set(JSON.stringify(newEntry), oldSize); - mapToUpdate.delete(entry); - } else if (changeOffset < entry[0] + entry[1]) { - mapToUpdate.delete(entry); - } - } - } - }); - this._resizableElement.domNode.appendChild(this._hover.containerDomNode); - this._resizableElement.domNode.className = 'resizable-hover'; - this._resizableElement.domNode.tabIndex = 0; - this._resizableElement.domNode.role = 'tooltip'; - - let state: ResizeState | undefined; - - this._register(this._resizableElement.onDidWillResize(() => { - console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); - const persistedSize = this._findPersistedSize(); - state = new ResizeState(persistedSize, this._resizableElement.size); - })); - this._register(this._resizableElement.onDidResize(e => { - console.log('* Inside of onDidResize of ContentHoverWidget'); - console.log('e : ', e); - this._resize(e.dimension.width, e.dimension.height); - if (state) { - state.persistHeight = state.persistHeight || !!e.north || !!e.south; - state.persistWidth = state.persistWidth || !!e.east || !!e.west; - } - if (!e.done) { - return; - } - if (state) { - if (!this._editor.hasModel()) { - return; - } - const uri = this._editor.getModel().uri.toString(); - if (!uri) { - return; - } - const { width, height } = this._resizableElement.size; - const persistedSize = new dom.Dimension(width, height); - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - if (!wordPosition || !this._editor.hasModel()) { - return; - } - const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._visibleData!.showAtPosition.lineNumber, column: wordPosition.startColumn }); - const length = wordPosition.word.length; - - if (!this._persistedHoverWidgetSizes.get(uri)) { - const map = new Map([]); - map.set(JSON.stringify([offset, length]), persistedSize); - this._persistedHoverWidgetSizes.set(uri, map); - } else { - const map = this._persistedHoverWidgetSizes.get(uri)!; - map.set(JSON.stringify([offset, length]), persistedSize); - } - } - state = undefined; - - console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); - })); - - console.log('Before adding the content widget'); - console.log('this._element.domNode : ', this._resizableElement.domNode); - this._editor.addContentWidget(this); - console.log('After adding the content widget'); - console.log('this._element.domNode : ', this._resizableElement.domNode); - */ } public setResizableHoverOverlay(resizablHoverOverlay: ResizableHoverOverlay): void { @@ -944,8 +931,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public resize(size: dom.Dimension | null) { console.log('Inside of the resize of the content hover widget'); - this._hover.containerDomNode.style.width = size?.width + 'px'; - this._hover.containerDomNode.style.height = size?.height + 'px'; + if (!size) { + return; + } + this._hover.containerDomNode.style.width = size.width - 6 + 'px'; + this._hover.containerDomNode.style.height = size.height - 6 + 'px'; this._editor.layoutContentWidget(this); this._editor.render(); } @@ -954,26 +944,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); } - private _findPersistedSize(): dom.Dimension | undefined { - // console.log('Inside of _findPersistedSize'); - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._visibleData!.showAtPosition); - if (!wordPosition || !this._editor.hasModel()) { - return; - } - const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._visibleData!.showAtPosition.lineNumber, column: wordPosition.startColumn }); - const length = wordPosition.word.length; - const uri = this._editor.getModel().uri.toString(); - // console.log('offset : ', offset); - // console.log('length : ', length); - const textModelMap = this._persistedHoverWidgetSizes.get(uri); - // console.log('textModelMap : ', textModelMap); - if (!textModelMap) { - return; - } - // console.log('textModelMap.value : ', textModelMap.entries().next().value); - return textModelMap.get(JSON.stringify([offset, length])); - } - /* private _setLayoutOfResizableElement(): void { @@ -1345,7 +1315,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } - public onContentsChanged(): void { + public onContentsChanged(persistedSize?: dom.Dimension | undefined): void { + console.log('* Inside of contents changed'); console.log('* Before changes'); let containerDomNode = this.getDomNode(); @@ -1361,9 +1332,52 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + console.log('persisted size : ', persistedSize); + + // Added here but does not seem to have an effect + if (persistedSize) { + containerDomNode.style.width = persistedSize.width - 8 + 'px'; + containerDomNode.style.height = persistedSize.height - 8 + 'px'; + // this._editor.addContentWidget(this._widget); + // this._editor.layoutContentWidget(this._widget); + // this._editor.render(); + } else { + containerDomNode.style.width = 'auto'; + containerDomNode.style.height = 'auto'; + } + this._editor.layoutContentWidget(this); + + console.log('* After layout content widget'); + containerDomNode = this.getDomNode(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + contentsDomNode = this.getContentsDomNode(); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + this._hover.onContentsChanged(); + console.log('* After hover on contents changed'); + containerDomNode = this.getDomNode(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + contentsDomNode = this.getContentsDomNode(); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); // console.log('Inside of onContentsChanged'); // console.log('scrollDimensions : ', scrollDimensions); From 8a187e39aea01b8bc24a29b8f8282b3b64a5b1ea Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 15:37:17 +0100 Subject: [PATCH 42/95] persist the size event when abrupt disapperance --- .../editor/contrib/hover/browser/contentHover.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 133ab9d1ac518..a9e88079a7b37 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -600,6 +600,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget private _maxRenderingHeight: number | undefined = 10000; private _tooltipPosition: IPosition | null = null; private _renderingPosition: IOverlayWidgetPosition | null = null; + private _visible: boolean = false; private _renderingAbove: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; private readonly _onDidResize = new Emitter(); @@ -651,6 +652,13 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._register(this._resizableElement.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); + console.log('this._visible : ', this._visible); + + if (!this._visible) { + this._resizing = false; + return; + } + let height = e.dimension.height; let width = e.dimension.width; const maxWidth = this._resizableElement.maxSize.width; @@ -678,9 +686,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget state.persistHeight = state.persistHeight || !!e.north || !!e.south; state.persistWidth = state.persistWidth || !!e.east || !!e.west; } - if (!e.done) { - return; - } if (state) { if (!this._editor.hasModel()) { return; @@ -705,6 +710,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget map.set(JSON.stringify([offset, length]), persistedSize); this._persistedHoverWidgetSizes.set(uri, map); } else { + console.log('saving the new persist size'); const map = this._persistedHoverWidgetSizes.get(uri)!; map.set(JSON.stringify([offset, length]), persistedSize); } @@ -764,6 +770,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('hiding the resizable hover overlay'); this._resizableElement.enableSashes(false, false, false, false); this._resizableElement.clearSashHoverState(); + this._visible = false; // this._resizableElement.layout(0, 0); // this._editor.layoutOverlayWidget(this); this._editor.removeOverlayWidget(this); @@ -812,6 +819,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + this._visible = true; this._editor.addOverlayWidget(this); console.log('After adding overlay widget'); resizableWidgetDomNode = this.getDomNode(); From 5b4795fb6c3ef8979cdc80fe1448aa3c79d4d1d8 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 15:45:35 +0100 Subject: [PATCH 43/95] Changed the code so as to not have sudden disapperance of the content hover --- src/vs/editor/contrib/hover/browser/contentHover.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a9e88079a7b37..6da13e28a3993 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -113,6 +113,12 @@ export class ContentHoverController extends Disposable { * Returns true if the hover shows now or will show. */ public maybeShowAt(mouseEvent: IEditorMouseEvent): boolean { + + // if resizing should not do anything, until resizing done + if (this._resizableWidget.isResizing()) { + return true; + } + const anchorCandidates: HoverAnchor[] = []; for (const participant of this._participants) { @@ -232,7 +238,7 @@ export class ContentHoverController extends Disposable { } public hide(): void { - // console.log('Inside of hide of content hover controller'); + console.log('Inside of hide of content hover controller'); this._computer.anchor = null; this._hoverOperation.cancel(); this._setCurrentResult(null); From a05844b97911f20020466dbc3958073afe1eb231 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 16:02:45 +0100 Subject: [PATCH 44/95] scanning the dom node so as to update the scrollbar on resize --- src/vs/editor/contrib/hover/browser/contentHover.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 6da13e28a3993..77c30e6f7cce5 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -950,8 +950,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._hover.containerDomNode.style.width = size.width - 6 + 'px'; this._hover.containerDomNode.style.height = size.height - 6 + 'px'; + this._hover.contentsDomNode.style.width = size.width - 6 + 'px'; + this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; this._editor.layoutContentWidget(this); this._editor.render(); + this._hover.scrollbar.scanDomNode(); } public getSize() { From 0315f7e32ea063d3d9a19f0d45efb86f4b0bf2ee Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 16:11:43 +0100 Subject: [PATCH 45/95] removing the max height and max width on the resize --- src/vs/editor/contrib/hover/browser/contentHover.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 77c30e6f7cce5..4bfb037979656 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -944,6 +944,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public resize(size: dom.Dimension | null) { + this._hover.contentsDomNode.style.maxHeight = 'none'; + this._hover.contentsDomNode.style.maxWidth = 'none'; console.log('Inside of the resize of the content hover widget'); if (!size) { return; @@ -1280,12 +1282,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { console.log(' * Entered into showAt of ContentHoverWidget'); + // this._hover.contentsDomNode.style.visibility = 'visibility'; this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; this._hover.contentsDomNode.appendChild(node); this._hover.contentsDomNode.style.paddingBottom = ''; + this._updateFont(); console.log('* Before the first onContentsChanged of showAt of ContentHoverWidget'); From 623a5a95c063cddf786517010299ef747ce8f718 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 18:24:13 +0100 Subject: [PATCH 46/95] Added a maximum height for the resize after rendering --- .../contentWidgets/contentWidgets.ts | 1 + .../contrib/hover/browser/contentHover.ts | 134 +++++++++--------- 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index b494ba60cc284..0fea304d3222c 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -16,6 +16,7 @@ import { IDimension } from 'vs/editor/common/core/dimension'; import { PositionAffinity } from 'vs/editor/common/model'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IViewModel } from 'vs/editor/common/viewModel'; +import { ContentViewOverlays } from 'vs/editor/browser/view/viewOverlays'; export class ViewContentWidgets extends ViewPart { diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 4bfb037979656..26d7ff077820c 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -42,7 +42,6 @@ export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; private readonly _resizableWidget = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); - private readonly _focusTracker = this._register(dom.trackFocus(this._resizableWidget.getDomNode())); private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); private readonly _computer: ContentHoverComputer; @@ -57,10 +56,7 @@ export class ContentHoverController extends Disposable { ) { super(); - this._register(this._focusTracker.onDidFocus(() => { - console.log('On did focus on resizable widget'); - this._widget.focus(); - })); + this._resizableWidget.containingWidget = this._widget; // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; @@ -95,14 +91,9 @@ export class ContentHoverController extends Disposable { this._register(this._editor.onDidChangeModel(() => { this._resizableWidget.hide(); })); - this._register(this._resizableWidget.onDidResize((e) => { this._widget.resize(e.dimension); })); - - this._register(this._editor.onDidScrollChange(() => { - - })); } get resizableWidget() { @@ -429,6 +420,7 @@ export class ContentHoverController extends Disposable { // Before there wasn't any of this below this._editor.layoutContentWidget(this._widget); this._editor.render(); + console.log('* After layoutContentWidget and render'); const containerDomNode = this._widget.getDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -469,7 +461,25 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - this._resizableWidget.showAt(position, size); + // Find if rendered above or below + + const topLineNumber = anchor.initialMousePosY; + console.log('topLineNumber : ', topLineNumber); + console.log('position.clientTop : ', position.clientTop); + + let renderingAbove: boolean = true; + + if (topLineNumber) { + if (position.clientTop <= topLineNumber) { + renderingAbove = true; + } else { + renderingAbove = false; + } + } + + console.log('Rendering above : ', renderingAbove); + + this._resizableWidget.showAt(position, size, renderingAbove); console.log('* After showAt of resizableWidget'); resizableWidgetDomNode = this._resizableWidget.getDomNode(); @@ -608,6 +618,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget private _renderingPosition: IOverlayWidgetPosition | null = null; private _visible: boolean = false; private _renderingAbove: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; + private _containingWidget: ContentHoverWidget | null = null; private readonly _onDidResize = new Emitter(); readonly onDidResize: Event = this._onDidResize.event; @@ -616,10 +627,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget super(); console.log('Inside of constructor of ResizableHoverOverlay'); // TODO: persist sizes during the session instead of persisting on reload - // TODO: The resizable element size does not align with the container dom size when there is not enouhg space for normal rendering // TODO: Upon resizing the, the persisted size is used everywhere, even if previously was not used everywhere - // TODO: Calculate correctly the container dom node size and resizable container dom node size - // TODO: When hovering over the scroll dom, show the scrollbar this._editor.onDidChangeModelContent((e) => { const uri = this._editor.getModel()?.uri.toString(); @@ -675,24 +683,35 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return; } this._size = new dom.Dimension(width, height); + this._resizableElement.layout(height, width); console.log('this._initialTop : ', this._initialTop); console.log('this._intiialHeight : ', this._initialHeight); console.log('height : ', height); console.log('this._initialTop - (height - this._initialHeight) : ', this._initialTop - (height - this._initialHeight)); - this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; + + if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { + this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; + } + this._onDidResize.fire({ dimension: this._size, done: false }); - this._resizableElement.layout(height, width); - // this._maxRenderingHeight = this._findMaxRenderingHeight(); + + console.log('this._containingWidget : ', this._containingWidget); + + if (!this._containingWidget) { + return; + } + this._maxRenderingHeight = this._containingWidget.findMaxRenderingHeight(this._renderingAbove); + console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight) { return; } + this._resizableElement.minSize = new dom.Dimension(10, 24); this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); + if (state) { state.persistHeight = state.persistHeight || !!e.north || !!e.south; state.persistWidth = state.persistWidth || !!e.east || !!e.west; - } - if (state) { if (!this._editor.hasModel()) { return; } @@ -704,8 +723,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget if (!this._tooltipPosition) { return; } - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._tooltipPosition); - if (!wordPosition || !this._editor.hasModel()) { + const wordPosition = this._editor.getModel().getWordAtPosition(this._tooltipPosition); + if (!wordPosition) { return; } const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); @@ -725,7 +744,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('Inside of the case when done'); this._resizing = false; } - + console.log('Before layout overlay widget of the onDidResize listener'); this._editor.layoutOverlayWidget(this); this._editor.render(); @@ -745,8 +764,12 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._initialTop; } + public set containingWidget(containingWidget: ContentHoverWidget) { + console.log('setting the containing widget'); + this._containingWidget = containingWidget; + } + public findPersistedSize(): dom.Dimension | undefined { - // console.log('Inside of _findPersistedSize'); if (!this._tooltipPosition) { return; } @@ -757,14 +780,10 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; const uri = this._editor.getModel().uri.toString(); - // console.log('offset : ', offset); - // console.log('length : ', length); const textModelMap = this._persistedHoverWidgetSizes.get(uri); - // console.log('textModelMap : ', textModelMap); if (!textModelMap) { return; } - // console.log('textModelMap.value : ', textModelMap.entries().next().value); return textModelMap.get(JSON.stringify([offset, length])); } @@ -777,8 +796,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.enableSashes(false, false, false, false); this._resizableElement.clearSashHoverState(); this._visible = false; - // this._resizableElement.layout(0, 0); - // this._editor.layoutOverlayWidget(this); + this._resizing = false; this._editor.removeOverlayWidget(this); this._editor.render(); } @@ -812,9 +830,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._renderingPosition; } - // TODO; The problem with not being able to change the height is most probably linked to the persisting of the height too - public showAt(position: any, size: dom.Dimension): void { + public showAt(position: any, size: dom.Dimension, renderingAbove: boolean): void { console.log('Inside of showAt of ResizableHoverOverlay'); console.log('Before adding overlay widget'); @@ -835,7 +852,14 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - this._resizableElement.enableSashes(true, true, false, false); + this._renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + + if (renderingAbove) { + this._resizableElement.enableSashes(true, true, false, false); + } else { + this._resizableElement.enableSashes(false, true, true, false); + } + this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; this._resizableElement.domNode.style.zIndex = '5'; @@ -883,11 +907,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hover: HoverWidget = this._register(new HoverWidget()); private _visibleData: ContentHoverVisibleData | null = null; - private _resizableHoverOverlay: ResizableHoverOverlay | null = null; - private _renderingAboveOption: boolean = this._editor.getOption(EditorOption.hover).above; - private _renderingAbove = this._renderingAboveOption; - private _maxRenderingHeight: number | undefined = -1; - private readonly _persistedHoverWidgetSizes = new Map>(); private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); @@ -922,9 +941,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (e.hasChanged(EditorOption.fontInfo)) { this._updateFont(); } - if (e.hasChanged(EditorOption.hover)) { - this._renderingAbove = this._editor.getOption(EditorOption.hover).above; - } })); this._setVisibleData(null); @@ -939,9 +955,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { })); } - public setResizableHoverOverlay(resizablHoverOverlay: ResizableHoverOverlay): void { - this._resizableHoverOverlay = resizablHoverOverlay; - } public resize(size: dom.Dimension | null) { this._hover.contentsDomNode.style.maxHeight = 'none'; @@ -1090,32 +1103,33 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } */ - private _findMaxRenderingHeight(): number | undefined { + public findMaxRenderingHeight(rendering: ContentWidgetPositionPreference): number | undefined { + console.log('rendering : ', rendering); if (!this._editor || !this._editor.hasModel()) { return; } - const preferRenderingAbove = this._editor.getOption(EditorOption.hover).above; const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); if (!this._visibleData?.showAtPosition) { return; } const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); const bodyBox = dom.getClientArea(document.body); - const availableSpaceAboveMinusTabsAndBreadcrumbs = mouseBox!.top - 4; - const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; - const availableSpaceBelow = bodyBox.height - mouseBottom; + let availableSpace: number; - let maxRenderingHeight; - if (preferRenderingAbove) { - maxRenderingHeight = this._renderingAbove ? availableSpaceAboveMinusTabsAndBreadcrumbs : availableSpaceBelow; + if (rendering === ContentWidgetPositionPreference.ABOVE) { + availableSpace = editorBox.top + mouseBox.top; } else { - maxRenderingHeight = this._renderingAbove ? availableSpaceBelow : availableSpaceAboveMinusTabsAndBreadcrumbs; + const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; + availableSpace = bodyBox.height - mouseBottom; } + console.log('availableSpace : ', availableSpace); let actualMaxHeight = 0; for (const childHtmlElement of this._hover.contentsDomNode.children) { actualMaxHeight += childHtmlElement.clientHeight; } - maxRenderingHeight = Math.min(maxRenderingHeight, actualMaxHeight + 2); + console.log('actual max height : ', actualMaxHeight); + const maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 7); + console.log('maxRenderingHeight : ', maxRenderingHeight); return maxRenderingHeight; } @@ -1207,22 +1221,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // :before content can align left of the text content const affinity = this._visibleData.isBeforeContent ? PositionAffinity.LeftOfInjectedText : undefined; - const rendering = this._renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - console.log('position inside of ContentHoverWidget : ', { - position: this._visibleData.showAtPosition, - secondaryPosition: this._visibleData.showAtSecondaryPosition, - // TODO: place back, preference: [rendering], - preference: ( - preferAbove - ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] - : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] - ), - positionAffinity: affinity - }); + return { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, - // TODO: place back, preference: [rendering], preference: ( preferAbove ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] From a0ecb24f63f5fd3876a6d3ce7f1565aae0ead94b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 18:26:26 +0100 Subject: [PATCH 47/95] Max size but for some reason the persist size from before is applied everywhere? --- src/vs/editor/contrib/hover/browser/contentHover.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 26d7ff077820c..4c72050913830 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -1117,7 +1117,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let availableSpace: number; if (rendering === ContentWidgetPositionPreference.ABOVE) { - availableSpace = editorBox.top + mouseBox.top; + availableSpace = editorBox.top + mouseBox.top - 30; } else { const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; availableSpace = bodyBox.height - mouseBottom; From 4a91de7074508ec6f3296df2005679cefc350379 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 18:39:31 +0100 Subject: [PATCH 48/95] Added code in order to cancel the max size on the hiding of the resizable element --- src/vs/editor/contrib/hover/browser/contentHover.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 4c72050913830..eeb7b7ed653e4 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -708,7 +708,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.minSize = new dom.Dimension(10, 24); this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - if (state) { state.persistHeight = state.persistHeight || !!e.north || !!e.south; state.persistWidth = state.persistWidth || !!e.east || !!e.west; @@ -795,6 +794,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('hiding the resizable hover overlay'); this._resizableElement.enableSashes(false, false, false, false); this._resizableElement.clearSashHoverState(); + this._resizableElement.maxSize = new dom.Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); this._visible = false; this._resizing = false; this._editor.removeOverlayWidget(this); @@ -1367,6 +1367,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } else { containerDomNode.style.width = 'auto'; containerDomNode.style.height = 'auto'; + contentsDomNode.style.width = 'auto'; + contentsDomNode.style.height = 'auto'; } this._editor.layoutContentWidget(this); From 383bb305d844a13d6ae090a205d9513aefd2e446 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 Mar 2023 19:20:32 +0100 Subject: [PATCH 49/95] Changed the code so as to update the persisted widget sizes on model content change --- .../contentWidgets/contentWidgets.ts | 1 - .../contrib/hover/browser/contentHover.ts | 41 +++++++++++++++---- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index 0fea304d3222c..b494ba60cc284 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -16,7 +16,6 @@ import { IDimension } from 'vs/editor/common/core/dimension'; import { PositionAffinity } from 'vs/editor/common/model'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IViewModel } from 'vs/editor/common/viewModel'; -import { ContentViewOverlays } from 'vs/editor/browser/view/viewOverlays'; export class ViewContentWidgets extends ViewPart { diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index eeb7b7ed653e4..39ba25430b758 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -628,29 +628,50 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('Inside of constructor of ResizableHoverOverlay'); // TODO: persist sizes during the session instead of persisting on reload // TODO: Upon resizing the, the persisted size is used everywhere, even if previously was not used everywhere + // TODO: continue persisting the size on model content changed this._editor.onDidChangeModelContent((e) => { + console.log('onDidChangeModelContent'); + console.log('e : ', e); const uri = this._editor.getModel()?.uri.toString(); - if (!uri || !(uri in this._persistedHoverWidgetSizes)) { + console.log('uri : ', uri); + console.log('this._persistedHoverWidgetSizes : ', this._persistedHoverWidgetSizes); + if (!uri) { + return; + } + if (!uri || !this._persistedHoverWidgetSizes.has(uri)) { return; } const mapToUpdate = this._persistedHoverWidgetSizes.get(uri)!; + const newMap = new Map(); + console.log('mapToUpdate : ', mapToUpdate); for (const change of e.changes) { const changeOffset = change.rangeOffset; - const length = change.rangeLength; - const endOffset = changeOffset + length; + const rangeLength = change.rangeLength; + const endOffset = changeOffset + rangeLength; + const textLength = change.text.length; + console.log('changeOffset : ', changeOffset); + console.log('rangeLength : ', rangeLength); + console.log('endOffset : ', endOffset); + console.log('textLength : ', textLength); for (const stringifiedEntry of mapToUpdate.keys()) { const entry = JSON.parse(stringifiedEntry); + console.log('entry : ', entry); if (endOffset < entry[0]) { - const oldSize = mapToUpdate.get(entry)!; - const newEntry: [number, number] = [entry[0] + length, entry[1]]; - mapToUpdate.set(JSON.stringify(newEntry), oldSize); - mapToUpdate.delete(entry); - } else if (changeOffset < entry[0] + entry[1]) { - mapToUpdate.delete(entry); + console.log('first if statement'); + const oldSize = mapToUpdate.get(stringifiedEntry)!; + console.log('oldSize : ', oldSize); + console.log('entry[0] - rangeLength + textLength : ', entry[0] - rangeLength + textLength); + const newEntry: [number, number] = [entry[0] - rangeLength + textLength, entry[1]]; + console.log('newEntry : ', newEntry); + newMap.set(JSON.stringify(newEntry), oldSize); + } else if (changeOffset >= entry[0] + entry[1]) { + console.log('second if statement'); + newMap.set(entry[0], entry[1]); } } } + this._persistedHoverWidgetSizes.set(uri, newMap); }); let state: ResizeState | undefined; @@ -783,6 +804,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget if (!textModelMap) { return; } + console.log('Inside of findPersistedSize'); + console.log('[offset, length] : ', [offset, length]); return textModelMap.get(JSON.stringify([offset, length])); } From 39439ebedee8b75ec3f0f6ebc97ad9fbecc01063 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 15:22:04 +0100 Subject: [PATCH 50/95] scanning the dom node right after the resizable widget and widget are created --- src/vs/editor/contrib/hover/browser/contentHover.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 39ba25430b758..8a824bc63c96c 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -57,6 +57,7 @@ export class ContentHoverController extends Disposable { super(); this._resizableWidget.containingWidget = this._widget; + this._widget._hover.scrollbar.scanDomNode(); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; @@ -928,7 +929,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public readonly allowEditorOverflow = true; - private readonly _hover: HoverWidget = this._register(new HoverWidget()); + public readonly _hover: HoverWidget = this._register(new HoverWidget()); private _visibleData: ContentHoverVisibleData | null = null; private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); From 443b088a4a965c068f81546e82aa6a32a9f8d9f3 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 16:42:42 +0100 Subject: [PATCH 51/95] Cleaning the code --- src/vs/base/common/scrollable.ts | 2 - .../editor/browser/widget/codeEditorWidget.ts | 1 - src/vs/editor/common/core/position.ts | 4 +- .../contrib/hover/browser/contentHover.ts | 208 +----------------- src/vs/editor/contrib/hover/browser/hover.ts | 4 - .../contrib/suggest/browser/suggestWidget.ts | 20 +- src/vs/monaco.d.ts | 4 +- 7 files changed, 20 insertions(+), 223 deletions(-) diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 49c21b665aa2c..1be0752c3fd40 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -264,12 +264,10 @@ export class Scrollable extends Disposable { } public setScrollDimensions(dimensions: INewScrollDimensions, useRawScrollPositions: boolean): void { - // console.log('dimensions : ', dimensions); const newState = this._state.withScrollDimensions(dimensions, useRawScrollPositions); this._setState(newState, Boolean(this._smoothScrolling)); // Validate outstanding animated scroll position target - // console.log('this._state inside setScrollDimension : ', this._state); this._smoothScrolling?.acceptScrollDimensions(this._state); } diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index ca86c515a731c..93c7923c14be5 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -1489,7 +1489,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE public layoutOverlayWidget(widget: editorBrowser.IOverlayWidget): void { const widgetId = widget.getId(); if (this._overlayWidgets.hasOwnProperty(widgetId)) { - console.log('Entered into the if statement of layoutOverlayWidget'); const widgetData = this._overlayWidgets[widgetId]; widgetData.position = widget.getPosition(); if (this._modelData && this._modelData.hasRealView) { diff --git a/src/vs/editor/common/core/position.ts b/src/vs/editor/common/core/position.ts index 37da2e4dbe68a..b8b29f9e14fae 100644 --- a/src/vs/editor/common/core/position.ts +++ b/src/vs/editor/common/core/position.ts @@ -24,11 +24,11 @@ export class Position { /** * line number (starts at 1) */ - public lineNumber: number; + public readonly lineNumber: number; /** * column (the first character in a line is between column 1 and column 2) */ - public column: number; + public readonly column: number; constructor(lineNumber: number, column: number) { this.lineNumber = lineNumber; diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 8a824bc63c96c..b67be3c6b2e30 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -43,7 +43,6 @@ export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; private readonly _resizableWidget = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); - private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; @@ -106,11 +105,9 @@ export class ContentHoverController extends Disposable { */ public maybeShowAt(mouseEvent: IEditorMouseEvent): boolean { - // if resizing should not do anything, until resizing done if (this._resizableWidget.isResizing()) { return true; } - const anchorCandidates: HoverAnchor[] = []; for (const participant of this._participants) { @@ -212,7 +209,6 @@ export class ContentHoverController extends Disposable { } private _setCurrentResult(hoverResult: HoverResult | null): void { - // console.log('hover result : ', hoverResult); if (this._currentResult === hoverResult) { // avoid updating the DOM to avoid resetting the user selection return; @@ -316,8 +312,10 @@ export class ContentHoverController extends Disposable { console.log('this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableWidget.getDomNode().offsetTop); - const top = this._widget.getDomNode().offsetTop; - const left = this._widget.getDomNode().offsetLeft; + const widgetDomNode = this._widget.getDomNode(); + const top = widgetDomNode.offsetTop; + const left = widgetDomNode.offsetLeft; + this._resizableWidget.resizableElement().domNode.style.top = top - 2 + 'px'; this._resizableWidget.resizableElement().domNode.style.left = left - 2 + 'px'; this._resizableWidget.resizableElement().domNode.style.zIndex = '5'; @@ -614,7 +612,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget private _size: dom.Dimension | null = null; private _initialHeight: number = -1; private _initialTop: number = -1; - private _maxRenderingHeight: number | undefined = 10000; + private _maxRenderingHeight: number | undefined; private _tooltipPosition: IPosition | null = null; private _renderingPosition: IOverlayWidgetPosition | null = null; private _visible: boolean = false; @@ -626,10 +624,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget constructor(private readonly _editor: ICodeEditor) { super(); + this._maxRenderingHeight = this._editor.getLayoutInfo().height; console.log('Inside of constructor of ResizableHoverOverlay'); - // TODO: persist sizes during the session instead of persisting on reload - // TODO: Upon resizing the, the persisted size is used everywhere, even if previously was not used everywhere - // TODO: continue persisting the size on model content changed this._editor.onDidChangeModelContent((e) => { console.log('onDidChangeModelContent'); @@ -637,9 +633,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget const uri = this._editor.getModel()?.uri.toString(); console.log('uri : ', uri); console.log('this._persistedHoverWidgetSizes : ', this._persistedHoverWidgetSizes); - if (!uri) { - return; - } if (!uri || !this._persistedHoverWidgetSizes.has(uri)) { return; } @@ -854,7 +847,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._renderingPosition; } - // TODO; The problem with not being able to change the height is most probably linked to the persisting of the height too public showAt(position: any, size: dom.Dimension, renderingAbove: boolean): void { console.log('Inside of showAt of ResizableHoverOverlay'); console.log('Before adding overlay widget'); @@ -921,7 +913,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } } -// TODO: Find the correct initial hover size export class ContentHoverWidget extends Disposable implements IContentWidget { @@ -979,7 +970,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { })); } - public resize(size: dom.Dimension | null) { this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; @@ -1000,133 +990,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); } - /* - private _setLayoutOfResizableElement(): void { - - // console.log('* Entered into _setLayoutOfResizableElement of ContentHoverWidget'); - // console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); - - if (!this._editor.hasModel() || !this._editor.getDomNode() || !this._visibleData?.showAtPosition) { - return; - } - - let height; - let width; - const persistedSize = this._findPersistedSize(); - // console.log('persistedSize : ', persistedSize); - - if (persistedSize) { - // console.log('When using the persisted size'); - height = persistedSize.height; - width = persistedSize.width; - } else { - // console.log('When not using the persisted size'); - const initialMaxHeight = Math.max(this._editor.getLayoutInfo().height / 4, 250); - const initialMaxWidth = Math.max(this._editor.getLayoutInfo().width * 0.66, 500); - this._hover.containerDomNode.style.maxHeight = `${initialMaxHeight}px`; - this._hover.containerDomNode.style.maxWidth = `${initialMaxWidth}px`; - this._hover.containerDomNode.style.minHeight = '24px'; - - this._hover.contentsDomNode.style.width = 'max-content'; - this._hover.contentsDomNode.style.height = 'auto'; - this._hover.containerDomNode.style.width = 'max-content'; - this._hover.containerDomNode.style.height = 'auto'; - - // console.log('Before render'); - // console.log('this._element.domNode before layoutContentWidget : ', this._resizableElement.domNode); - - this._editor.layoutContentWidget(this); - this._editor.render(); - - // console.log('After render'); - // console.log('this._element.domNode after layoutContentWidget: ', this._resizableElement.domNode); - - height = this._hover.containerDomNode.offsetHeight; - width = this._hover.containerDomNode.offsetWidth; - } - - // console.log('height and width'); - // console.log('height : ', height); - // console.log('width : ', width); - - // console.log('this._hover.containerDomNode from initial rendering : ', this._hover.containerDomNode); - - // The dimensions of the document in which we are displaying the hover - const bodyBox = dom.getClientArea(document.body); - - // Hard-code the values for now! - const maxWidth = bodyBox.width; - if (width > maxWidth) { - width = maxWidth; - } - - // Hard-coded in the hover.css file as 1.5em or 24px - const minHeight = 24; - // The full height is already passed in as a parameter - const fullHeight = height; - const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); - // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height - const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; - // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position - const availableSpaceBelow = bodyBox.height - mouseBottom; - // Max height below is the minimum of the available space below and the full height of the widget - const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); - // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor - const availableSpaceAbove = mouseBox.top; // + 35 + 22; // Removing 35 because that is the height of the tabs // editorBox.top // adding 22 because height of breadcrumbs - // Max height above is the minimum of the available space above and the full height of the widget - const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); - // We find the maximum height of the widget possible on the top or on the bottom - const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); - - if (height < minHeight) { - height = minHeight; - } - if (height > maxHeight) { - height = maxHeight; - } - - if (this._renderingAboveOption) { - const westSash = false; - const eastSash = true; - const northSash = height <= maxHeightAbove; - const southSash = height > maxHeightAbove; - this._renderingAbove = height <= maxHeightAbove; - this._resizableElement.enableSashes(northSash, eastSash, southSash, westSash); - } else { - const westSash = false; - const eastSash = true; - const northSash = height > maxHeightBelow; - const southSash = height <= maxHeightBelow; - this._renderingAbove = height > maxHeightBelow; - this._resizableElement.enableSashes(northSash, eastSash, southSash, westSash); - this._resizableElement.minSize = new dom.Dimension(10, minHeight); - this._maxRenderingHeight = this._findMaxRenderingHeight(); - if (!this._maxRenderingHeight) { - return; - } - this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - } - - // console.log('height : ', height); - // console.log('width : ', width); - - this._resizableElement.layout(height, width); - this._hover.containerDomNode.style.height = `${height - 2}px`; - this._hover.containerDomNode.style.width = `${width - 2}px`; - this._hover.containerDomNode.style.overflow = 'hidden'; - this._hover.contentsDomNode.style.height = `${height - 2}px`; - this._hover.contentsDomNode.style.width = `${width - 2}px`; - this._hover.contentsDomNode.style.overflow = 'hidden'; - - this._hover.scrollbar.scanDomNode(); - // console.log('Before layoutContentWidget'); - this._editor.layoutContentWidget(this); - this._editor.render(); - // console.log('this.getDomNode() : ', this.getDomNode()); - } - */ - public findMaxRenderingHeight(rendering: ContentWidgetPositionPreference): number | undefined { console.log('rendering : ', rendering); if (!this._editor || !this._editor.hasModel()) { @@ -1157,59 +1020,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return maxRenderingHeight; } - // Initiall height and width are the maximmum dimensions to give to the hover - /* - private _resize(width: number, height: number): void { - - console.log(' * Entered into the _resize function of ContentHoverWidget'); - - console.log('width : ', width); - console.log('height : ', height); - - this._hover.containerDomNode.style.maxHeight = 'none'; - this._hover.containerDomNode.style.maxWidth = 'none'; - this._hover.contentsDomNode.style.maxHeight = 'none'; - this._hover.contentsDomNode.style.maxWidth = 'none'; - - const maxWidth = this._resizableElement.maxSize.width; - const maxHeight = this._resizableElement.maxSize.height; - width = Math.min(maxWidth, width); - height = Math.min(maxHeight, height); - console.log('height : ', height); - console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { - return; - } - // TODO: the following should be tweaked so that the sashes are still there for making it smaller but, it should not be possible to resize when the maxRenderingHeight is the minimal value of 18 cm - // if (height >= this._maxRenderingHeight) { - // this._element.enableSashes(false, true, false, false); - // } - - this._resizableElement.layout(height, width); - this._hover.containerDomNode.style.height = `${height - 2}px`; - this._hover.containerDomNode.style.width = `${width - 2}px`; - // TODO: Find out why adding the following two lines changes the scroll dimensions to reflect reality - // Potentially remove - this._hover.contentsDomNode.style.height = `${height - 2}px`; - this._hover.contentsDomNode.style.width = `${width - 2}px`; - - this._hover.scrollbar.scanDomNode(); - this._maxRenderingHeight = this._findMaxRenderingHeight(); - console.log('maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { - return; - } - this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); - this._editor.layoutContentWidget(this); - - console.log('this._hover.containerDomNode : ', this._hover.containerDomNode); - console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - console.log('this._hover.contentsDomNode.scrollHeight : ', this._hover.contentsDomNode.scrollHeight); - console.log('this._hover.contentsDomNode.clientWidth : ', this._hover.contentsDomNode.clientWidth); - console.log('this._hover.contentsDomNode.scrollWidth : ', this._hover.contentsDomNode.scrollWidth); - } - */ - public override dispose(): void { console.log('Inside of dispose of the ContentHoverWidget'); this._editor.removeContentWidget(this); @@ -1308,14 +1118,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { console.log(' * Entered into showAt of ContentHoverWidget'); - - // this._hover.contentsDomNode.style.visibility = 'visibility'; this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; this._hover.contentsDomNode.appendChild(node); this._hover.contentsDomNode.style.paddingBottom = ''; - this._updateFont(); console.log('* Before the first onContentsChanged of showAt of ContentHoverWidget'); @@ -1428,11 +1235,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); - // console.log('Inside of onContentsChanged'); - // console.log('scrollDimensions : ', scrollDimensions); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); if (hasHorizontalScrollbar) { - // console.log('Entered into hasHorizontalScrollbar'); // There is just a horizontal scrollbar const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 9996939a57740..891dfdf6a8c7f 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -214,7 +214,6 @@ export class ModesHoverController implements IEditorContribution { if (e.keyCode !== KeyCode.Ctrl && e.keyCode !== KeyCode.Alt && e.keyCode !== KeyCode.Meta && e.keyCode !== KeyCode.Shift && !mightTriggerFocus) { // Do not hide hover when a modifier key is pressed - this._hideWidgets(); } } @@ -224,12 +223,9 @@ export class ModesHoverController implements IEditorContribution { return; } - // console.log('Inside of _hideWidgets'); this._hoverClicked = false; this._glyphWidget?.hide(); - // console.log('this._contentWidget?.resizableWidget.isResizing() : ', this._contentWidget?.resizableWidget.isResizing()); if (!this._contentWidget?.resizableWidget.isResizing()) { - // console.log('Hiding the content widget'); this._contentWidget?.hide(); } } diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index ab06705d407d1..d2e86783c8a0f 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -63,7 +63,7 @@ export interface ISelectedSuggestion { model: CompletionModel; } -export class PersistedWidgetSize { +class PersistedWidgetSize { private readonly _key: string; @@ -96,15 +96,6 @@ export class PersistedWidgetSize { } } -export class ResizeState { - constructor( - readonly persistedSize: dom.Dimension | undefined, - readonly currentSize: dom.Dimension, - public persistHeight = false, - public persistWidth = false, - ) { } -} - export class SuggestWidget implements IDisposable { private static LOADING_MESSAGE: string = nls.localize('suggestWidget.loading', "Loading..."); @@ -167,6 +158,15 @@ export class SuggestWidget implements IDisposable { this._contentWidget = new SuggestContentWidget(this, editor); this._persistedSize = new PersistedWidgetSize(_storageService, editor); + class ResizeState { + constructor( + readonly persistedSize: dom.Dimension | undefined, + readonly currentSize: dom.Dimension, + public persistHeight = false, + public persistWidth = false, + ) { } + } + let state: ResizeState | undefined; this._disposables.add(this.element.onDidWillResize(() => { this._contentWidget.lockPreference(); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index ba0f1e271a80a..03a2626ef908d 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -502,11 +502,11 @@ declare namespace monaco { /** * line number (starts at 1) */ - lineNumber: number; + readonly lineNumber: number; /** * column (the first character in a line is between column 1 and column 2) */ - column: number; + readonly column: number; constructor(lineNumber: number, column: number); /** * Create a new position from this position. From 35039160558e61156aaf8acb6d59903958be2d79 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 17:22:48 +0100 Subject: [PATCH 52/95] changed the code so that the content hover does not change sides on resizes, simplifies the code, makes it more robust --- .../contrib/hover/browser/contentHover.ts | 79 ++++++++++++++++--- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index b67be3c6b2e30..7270a1357b25d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -413,7 +413,7 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosX, anchor.initialMousePosY, disposables - )); + ), persistedSize); console.log('* After this._widget.showAt'); console.log('* Before layoutContentWidget and render'); // Before there wasn't any of this below @@ -679,6 +679,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._initialTop = this._resizableElement.domNode.offsetTop; })); this._register(this._resizableElement.onDidResize(e => { + console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); console.log('this._visible : ', this._visible); @@ -704,6 +705,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('height : ', height); console.log('this._initialTop - (height - this._initialHeight) : ', this._initialTop - (height - this._initialHeight)); + // When resizing and then the size is smaller so that can be displayed above, display above + // if (height <= maxHeightAbove && this._renderingAbove === ContentWidgetPositionPreference.BELOW) { + // this._renderingAbove = ContentWidgetPositionPreference.ABOVE; + // } + if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; } @@ -885,7 +891,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.domNode.style.width = size.width + 7 + 'px'; this._resizableElement.layout(size.height, size.width); - console.log('After style chamge of overlay widget'); + console.log('After style change of overlay widget'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); @@ -925,6 +931,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); + private _renderingType: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; /** * Returns `null` if the hover is not visible. @@ -1056,14 +1063,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // :before content can align left of the text content const affinity = this._visibleData.isBeforeContent ? PositionAffinity.LeftOfInjectedText : undefined; + // Instead use a specfic preference as to the rendering and do not have it dynamically change return { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, - preference: ( - preferAbove - ? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW] - : [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] - ), + preference: ([this._renderingType]), positionAffinity: affinity }; } @@ -1115,7 +1119,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { codeClasses.forEach(node => this._editor.applyFontInfo(node)); } - public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData): void { + public showAt(node: DocumentFragment, visibleData: ContentHoverVisibleData, persistedSize: dom.Dimension | undefined): void { + + if (!this._editor || !this._editor.hasModel()) { + return; + } console.log(' * Entered into showAt of ContentHoverWidget'); this._setVisibleData(visibleData); @@ -1131,13 +1139,66 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' this._editor.render(); - console.log('* After render inside of showAt of ContentHoverWidget'); + const containerDomNode = this.getDomNode(); + let height; + + if (persistedSize) { + height = persistedSize.height; + } else { + + height = containerDomNode.clientHeight; + } + console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + + console.log('* After render inside of showAt of ContentHoverWidget'); + + // TODO: Should be added in the final rendering after the persisted size is used, because that is the one that should be applied + /** Specifying the side on which to render the content hover **/ + // Initial height is not used without persisting + + // The dimensions of the document in which we are displaying the hover + const bodyBox = dom.getClientArea(document.body); + + // Hard-coded in the hover.css file as 1.5em or 24px + const minHeight = 24; + // The full height is already passed in as a parameter + const fullHeight = height; + const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); + const mouseBox = this._editor.getScrolledVisiblePosition(visibleData.showAtPosition); + // Position where the editor box starts + the top of the mouse box relatve to the editor + mouse box height + const mouseBottom = editorBox.top + mouseBox.top + mouseBox.height; + // Total height of the box minus the position of the bottom of the mouse, this is the maximum height below the mouse position + const availableSpaceBelow = bodyBox.height - mouseBottom; + // Max height below is the minimum of the available space below and the full height of the widget + const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); + // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor + const availableSpaceAbove = editorBox.top + mouseBox.top; + + const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); + // We find the maximum height of the widget possible on the top or on the bottom + const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); + + if (height < minHeight) { + height = minHeight; + } + if (height > maxHeight) { + height = maxHeight; + } + if (this._editor.getOption(EditorOption.hover).above) { + this._renderingType = height <= maxHeightAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + } else { + this._renderingType = height <= maxHeightBelow ? ContentWidgetPositionPreference.BELOW : ContentWidgetPositionPreference.ABOVE; + } + + /** End of specifying the side on which to render **/ + // specify the rendering position here + const contentsDomNode = this.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); From 892df255e375548914656308f4b9f6dcbdd45b5b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 17:52:58 +0100 Subject: [PATCH 53/95] Adding the maximum height and width on the content dom node after the resize once again depending on whether the persisted size exists or not --- src/vs/editor/contrib/hover/browser/contentHover.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 7270a1357b25d..42dc45ea60518 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -38,6 +38,9 @@ class ResizeState { ) { } } +// TODO: For some reason, when resizing the function name hover, the function hover becomes oversizes +// TODO: Set the maximum width + export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; @@ -721,6 +724,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget if (!this._containingWidget) { return; } + + this._maxRenderingHeight = this._containingWidget.findMaxRenderingHeight(this._renderingAbove); console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight) { @@ -1146,8 +1151,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (persistedSize) { height = persistedSize.height; } else { - height = containerDomNode.clientHeight; + this._hover.contentsDomNode.style.maxHeight = `${Math.max(this._editor.getLayoutInfo().height / 4, 250)}px`; + this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; } console.log('containerDomNode : ', containerDomNode); @@ -1178,7 +1184,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Max height below is the minimum of the available space below and the full height of the widget const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor - const availableSpaceAbove = editorBox.top + mouseBox.top; + const availableSpaceAbove = editorBox.top + mouseBox.top - 30; const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); // We find the maximum height of the widget possible on the top or on the bottom From f9a6afdfbe011f376b1c98ab2b56d7768ddf8472 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 17:53:15 +0100 Subject: [PATCH 54/95] removing a comment --- src/vs/editor/contrib/hover/browser/contentHover.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 42dc45ea60518..85cb508ee8ddb 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -39,7 +39,6 @@ class ResizeState { } // TODO: For some reason, when resizing the function name hover, the function hover becomes oversizes -// TODO: Set the maximum width export class ContentHoverController extends Disposable { From 15302983a8c1c8bff96c43b7c9adc2ed86260dd2 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 18:01:47 +0100 Subject: [PATCH 55/95] changed the code so that the else if statement is also correctly handled in the saving of the persisted sizes --- src/vs/editor/contrib/hover/browser/contentHover.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 85cb508ee8ddb..878e8ad389c6e 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -38,8 +38,6 @@ class ResizeState { ) { } } -// TODO: For some reason, when resizing the function name hover, the function hover becomes oversizes - export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; @@ -663,7 +661,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget newMap.set(JSON.stringify(newEntry), oldSize); } else if (changeOffset >= entry[0] + entry[1]) { console.log('second if statement'); - newMap.set(entry[0], entry[1]); + newMap.set(stringifiedEntry, mapToUpdate.get(stringifiedEntry)!); } } } @@ -684,7 +682,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); - console.log('this._visible : ', this._visible); if (!this._visible) { this._resizing = false; From ca27764c83edaf09c7175225455aa3255a24138f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 18:26:00 +0100 Subject: [PATCH 56/95] Making the resizable eleemnt resize the left side correctly if left offset changes on resize --- src/vs/editor/contrib/hover/browser/contentHover.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 878e8ad389c6e..d9b28462ee713 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -29,6 +29,11 @@ import { Emitter, Event } from 'vs/base/common/event'; const $ = dom.$; +// TODO: set maximum width +// TODO: remove the double flickering that happens on double rendering, but is it possible to remove it really? +// TODO: correct potential errors on sticky hover +// TODO: update the left position on the resize + class ResizeState { constructor( readonly persistedSize: dom.Dimension | undefined, @@ -683,6 +688,12 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); + // update the left position of the resizable overlay on resize + const offsetLeft = this._containingWidget?.getDomNode().offsetLeft; + if (offsetLeft) { + this._resizableElement.domNode.style.left = offsetLeft - 1 + 'px'; + } + if (!this._visible) { this._resizing = false; return; From 09ec6744e9f05aef05209cf1a352d1078e5a64b9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 18:26:53 +0100 Subject: [PATCH 57/95] changing left offset --- src/vs/editor/contrib/hover/browser/contentHover.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d9b28462ee713..d556c32c8a508 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -32,7 +32,6 @@ const $ = dom.$; // TODO: set maximum width // TODO: remove the double flickering that happens on double rendering, but is it possible to remove it really? // TODO: correct potential errors on sticky hover -// TODO: update the left position on the resize class ResizeState { constructor( From f0ccdf843be4b7dbb39baa3f1768fbb07a042009 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 18:51:17 +0100 Subject: [PATCH 58/95] Changing the left offset of the resizable element when the widget dom node is resized --- .../contrib/hover/browser/contentHover.ts | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d556c32c8a508..7d432e849b4c5 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -97,6 +97,10 @@ export class ContentHoverController extends Disposable { })); this._register(this._resizableWidget.onDidResize((e) => { this._widget.resize(e.dimension); + const offsetLeft = this._widget.getDomNode().offsetLeft; + if (offsetLeft) { + this._resizableWidget.getDomNode().style.left = offsetLeft - 1 + 'px'; + } })); } @@ -617,6 +621,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget private _initialHeight: number = -1; private _initialTop: number = -1; private _maxRenderingHeight: number | undefined; + private _maxRenderingWidth: number | undefined; private _tooltipPosition: IPosition | null = null; private _renderingPosition: IOverlayWidgetPosition | null = null; private _visible: boolean = false; @@ -687,12 +692,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); - // update the left position of the resizable overlay on resize - const offsetLeft = this._containingWidget?.getDomNode().offsetLeft; - if (offsetLeft) { - this._resizableElement.domNode.style.left = offsetLeft - 1 + 'px'; - } - if (!this._visible) { this._resizing = false; return; @@ -731,10 +730,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return; } - + // this._maxRenderingWidth = this._containingWidget.findMaxRenderingWidth(); this._maxRenderingHeight = this._containingWidget.findMaxRenderingHeight(this._renderingAbove); + console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { + if (!this._maxRenderingHeight || !this._maxRenderingWidth) { return; } this._resizableElement.minSize = new dom.Dimension(10, 24); @@ -1038,6 +1038,21 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return maxRenderingHeight; } + public findMaxRenderingWidth(): number | undefined { + console.log('Inside of findMaxRenderingWidth'); + if (!this._editor || !this._editor.hasModel()) { + return; + } + const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); + const widthOfEditor = editorBox.width; + const leftOfEditor = editorBox.left; + + const leftOfContainer = this._hover.containerDomNode.offsetLeft; + const margin = 20; + + return widthOfEditor + leftOfEditor - leftOfContainer; + } + public override dispose(): void { console.log('Inside of dispose of the ContentHoverWidget'); this._editor.removeContentWidget(this); From d4635cd82f4c45a6fd3d6939feb31918df1c20c6 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 19:36:17 +0100 Subject: [PATCH 59/95] Changed the contents sizes in order to take into account the horizontal scrollbar size --- .../browser/ui/scrollbar/scrollableElement.ts | 1 + .../contrib/hover/browser/contentHover.ts | 30 ++++++++++++++----- src/vs/editor/contrib/hover/browser/hover.ts | 12 ++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 87d4ed4d9fa38..b8172c5e4a937 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -637,6 +637,7 @@ export class DomScrollableElement extends AbstractScrollableElement { } public scanDomNode(): void { + console.log('Inside of scanDomNode()'); // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight this.setScrollDimensions({ width: this._element.clientWidth, diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 7d432e849b4c5..96e6873e57d61 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -116,6 +116,7 @@ export class ContentHoverController extends Disposable { if (this._resizableWidget.isResizing()) { return true; } + const anchorCandidates: HoverAnchor[] = []; for (const participant of this._participants) { @@ -357,6 +358,7 @@ export class ContentHoverController extends Disposable { console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); console.log('At the end of onContentsChanged of _renderMessages'); + this._widget._hover.scrollbar.scanDomNode(); }, hide: () => this.hide() }; @@ -495,6 +497,8 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + + this._widget._hover.scrollbar.scanDomNode(); } else { disposables.dispose(); } @@ -724,38 +728,43 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._onDidResize.fire({ dimension: this._size, done: false }); - console.log('this._containingWidget : ', this._containingWidget); + // console.log('this._containingWidget : ', this._containingWidget); if (!this._containingWidget) { return; } - // this._maxRenderingWidth = this._containingWidget.findMaxRenderingWidth(); + this._maxRenderingWidth = this._containingWidget.findMaxRenderingWidth(); this._maxRenderingHeight = this._containingWidget.findMaxRenderingHeight(this._renderingAbove); - console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight || !this._maxRenderingWidth) { + // console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); + if (!this._maxRenderingHeight) { return; } this._resizableElement.minSize = new dom.Dimension(10, 24); this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); if (state) { + // console.log('Inside of the case when state defined : ', state); state.persistHeight = state.persistHeight || !!e.north || !!e.south; state.persistWidth = state.persistWidth || !!e.east || !!e.west; if (!this._editor.hasModel()) { + // console.log('first if statement'); return; } const uri = this._editor.getModel().uri.toString(); if (!uri) { + // console.log('second if statement'); return; } const persistedSize = new dom.Dimension(width, height); if (!this._tooltipPosition) { + // console.log('third if statement'); return; } const wordPosition = this._editor.getModel().getWordAtPosition(this._tooltipPosition); if (!wordPosition) { + // console.log('third if statement'); return; } const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); @@ -766,16 +775,16 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget map.set(JSON.stringify([offset, length]), persistedSize); this._persistedHoverWidgetSizes.set(uri, map); } else { - console.log('saving the new persist size'); + // console.log('saving the new persist size'); const map = this._persistedHoverWidgetSizes.get(uri)!; map.set(JSON.stringify([offset, length]), persistedSize); } } if (e.done) { - console.log('Inside of the case when done'); + // console.log('Inside of the case when done'); this._resizing = false; } - console.log('Before layout overlay widget of the onDidResize listener'); + // console.log('Before layout overlay widget of the onDidResize listener'); this._editor.layoutOverlayWidget(this); this._editor.render(); @@ -992,13 +1001,16 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; console.log('Inside of the resize of the content hover widget'); + console.log('size : ', size); if (!size) { return; } this._hover.containerDomNode.style.width = size.width - 6 + 'px'; this._hover.containerDomNode.style.height = size.height - 6 + 'px'; + // TODO: Place back? + // Need this in order for the vertical scroll bar to appear this._hover.contentsDomNode.style.width = size.width - 6 + 'px'; - this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; + this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; this._editor.layoutContentWidget(this); this._editor.render(); this._hover.scrollbar.scanDomNode(); @@ -1347,6 +1359,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + + this._hover.scrollbar.scanDomNode(); } public clear(): void { diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 891dfdf6a8c7f..f3f95a470116e 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -143,18 +143,22 @@ export class ModesHoverController implements IEditorContribution { } private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { + // console.log('Inside of _onEditorMouseMove'); const target = mouseEvent.target; if (this._isMouseDown && this._hoverClicked) { + // console.log('If mouse down and hover clicked'); return; } if (this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID) { + // console.log('second if statement'); // mouse moved on top of content hover widget return; } if (this._isHoverSticky && !mouseEvent.event.browserEvent.view?.getSelection()?.isCollapsed) { + // console.log('third if statement'); // selected text within content hover widget return; } @@ -163,22 +167,26 @@ export class ModesHoverController implements IEditorContribution { !this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID && this._contentWidget?.isColorPickerVisible() ) { + // console.log('4th if statement'); // though the hover is not sticky, the color picker needs to. return; } if (this._isHoverSticky && target.type === MouseTargetType.OVERLAY_WIDGET && target.detail === MarginHoverWidget.ID) { + // console.log('5th if statement'); // mouse moved on top of overlay hover widget return; } if (this._isHoverSticky && this._contentWidget?.isVisibleFromKeyboard()) { + // console.log('6th if statement'); // Sticky mode is on and the hover has been shown via keyboard // so moving the mouse has no effect return; } if (!this._isHoverEnabled) { + // console.log('7th if statement'); this._hideWidgets(); return; } @@ -186,11 +194,13 @@ export class ModesHoverController implements IEditorContribution { const contentWidget = this._getOrCreateContentWidget(); if (contentWidget.maybeShowAt(mouseEvent)) { + // console.log('Inside of 8th if statement'); this._glyphWidget?.hide(); return; } if (target.type === MouseTargetType.GUTTER_GLYPH_MARGIN && target.position) { + // console.log('Inside of 9th if statement'); this._contentWidget?.hide(); if (!this._glyphWidget) { this._glyphWidget = new MarginHoverWidget(this._editor, this._languageService, this._openerService); @@ -219,12 +229,14 @@ export class ModesHoverController implements IEditorContribution { } private _hideWidgets(): void { + // console.log('Inside of _hideWidget'); if ((this._isMouseDown && this._hoverClicked && this._contentWidget?.isColorPickerVisible()) || InlineSuggestionHintsContentWidget.dropDownVisible) { return; } this._hoverClicked = false; this._glyphWidget?.hide(); + // console.log('this._contentWidget?.resizableWidget.isResizing() : ', this._contentWidget?.resizableWidget.isResizing()); if (!this._contentWidget?.resizableWidget.isResizing()) { this._contentWidget?.hide(); } From aed1565cc12a261470724b9e322733f5e91cc2b5 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 19:53:02 +0100 Subject: [PATCH 60/95] Changint the code so that the vertical and horizontal scrollbars appear in all cases --- src/vs/editor/contrib/hover/browser/contentHover.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 96e6873e57d61..18f78a2ea66b2 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -1045,7 +1045,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { actualMaxHeight += childHtmlElement.clientHeight; } console.log('actual max height : ', actualMaxHeight); - const maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 7); + // Adding 10 also in order to allow some space for the horizontal scrollbar + const maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 16); console.log('maxRenderingHeight : ', maxRenderingHeight); return maxRenderingHeight; } @@ -1290,8 +1291,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Added here but does not seem to have an effect if (persistedSize) { - containerDomNode.style.width = persistedSize.width - 8 + 'px'; - containerDomNode.style.height = persistedSize.height - 8 + 'px'; + containerDomNode.style.width = persistedSize.width - 8 + 'px'; // - 8 + containerDomNode.style.height = persistedSize.height - 8 + 'px'; // - 8 + contentsDomNode.style.width = persistedSize.width - 8 + 'px'; // - 8 + contentsDomNode.style.height = persistedSize.height - 18 + 'px'; + // this._editor.addContentWidget(this._widget); // this._editor.layoutContentWidget(this._widget); // this._editor.render(); From 8aa537a0f0c2cb7e300d614675b92704c357b61d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 20:00:28 +0100 Subject: [PATCH 61/95] Adding a maximum rendering width --- src/vs/editor/contrib/hover/browser/contentHover.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 18f78a2ea66b2..416b5bd2718ac 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -29,7 +29,6 @@ import { Emitter, Event } from 'vs/base/common/event'; const $ = dom.$; -// TODO: set maximum width // TODO: remove the double flickering that happens on double rendering, but is it possible to remove it really? // TODO: correct potential errors on sticky hover @@ -738,11 +737,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._maxRenderingHeight = this._containingWidget.findMaxRenderingHeight(this._renderingAbove); // console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); - if (!this._maxRenderingHeight) { + if (!this._maxRenderingHeight || !this._maxRenderingWidth) { return; } this._resizableElement.minSize = new dom.Dimension(10, 24); - this._resizableElement.maxSize = new dom.Dimension(maxWidth, this._maxRenderingHeight); + this._resizableElement.maxSize = new dom.Dimension(this._maxRenderingWidth, this._maxRenderingHeight); if (state) { // console.log('Inside of the case when state defined : ', state); @@ -1059,11 +1058,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); const widthOfEditor = editorBox.width; const leftOfEditor = editorBox.left; - + const glyphMarginWidth = this._editor.getLayoutInfo().glyphMarginWidth; const leftOfContainer = this._hover.containerDomNode.offsetLeft; - const margin = 20; - return widthOfEditor + leftOfEditor - leftOfContainer; + return widthOfEditor + leftOfEditor - leftOfContainer - glyphMarginWidth; } public override dispose(): void { From 21fd598a1bae98a666ae477df16b205d22bfe2c7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 20:43:48 +0100 Subject: [PATCH 62/95] Changed code so that when persisted size is used, the height and width of the view port are taken into account in order not to render a widget which is too big --- .../contrib/hover/browser/contentHover.ts | 47 ++++++++++++++++--- src/vs/editor/contrib/hover/browser/hover.css | 8 ++-- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 416b5bd2718ac..fb44e970df9f6 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -313,7 +313,7 @@ export class ContentHoverController extends Disposable { const persistedSize = this._resizableWidget.findPersistedSize(); console.log('persistedSize : ', persistedSize); - this._widget.onContentsChanged(persistedSize); + this._widget.onContentsChanged(persistedSize, this._widget.renderingType); this._editor.render(); console.log('After onContentsChanged'); @@ -423,6 +423,7 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosY, disposables ), persistedSize); + console.log('* After this._widget.showAt'); console.log('* Before layoutContentWidget and render'); // Before there wasn't any of this below @@ -971,6 +972,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return this._hoverVisibleKey.get() ?? false; } + public get renderingType(): ContentWidgetPositionPreference { + return this._renderingType; + } + constructor( private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService @@ -1182,6 +1187,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (persistedSize) { height = persistedSize.height; + this._hover.contentsDomNode.style.maxHeight = 'none'; + this._hover.contentsDomNode.style.maxWidth = 'none'; } else { height = containerDomNode.clientHeight; this._hover.contentsDomNode.style.maxHeight = `${Math.max(this._editor.getLayoutInfo().height / 4, 250)}px`; @@ -1268,7 +1275,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } - public onContentsChanged(persistedSize?: dom.Dimension | undefined): void { + public onContentsChanged(persistedSize?: dom.Dimension | undefined, renderingType?: ContentWidgetPositionPreference | undefined): void { console.log('* Inside of contents changed'); console.log('* Before changes'); @@ -1289,10 +1296,37 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Added here but does not seem to have an effect if (persistedSize) { - containerDomNode.style.width = persistedSize.width - 8 + 'px'; // - 8 - containerDomNode.style.height = persistedSize.height - 8 + 'px'; // - 8 - contentsDomNode.style.width = persistedSize.width - 8 + 'px'; // - 8 - contentsDomNode.style.height = persistedSize.height - 18 + 'px'; + + // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one + + let containerDomNodeWidth = persistedSize.width - 8; + let containerDomNodeHeight = persistedSize.height - 8; + let contentsDomNodeWidth = persistedSize.width - 8; + let contentsDomNodeHeight = persistedSize.height - 18; + + if (renderingType) { + const maxRenderingHeight = this.findMaxRenderingHeight(renderingType); + const maxRenderingWidth = this.findMaxRenderingWidth(); + console.log('maxRenderingHeight : ', maxRenderingHeight); + console.log('maxRenderingWidth : ', maxRenderingWidth); + + if (maxRenderingHeight && maxRenderingWidth) { + containerDomNodeWidth = Math.min(maxRenderingWidth, containerDomNodeWidth); + containerDomNodeHeight = Math.min(maxRenderingHeight, containerDomNodeHeight); + contentsDomNodeWidth = Math.min(maxRenderingWidth, contentsDomNodeWidth); + contentsDomNodeHeight = Math.min(maxRenderingHeight - 10, contentsDomNodeHeight); + } + + console.log('containerDomNodeWidth : ', containerDomNodeWidth); + console.log('containerDomNodeHeight : ', containerDomNodeHeight); + console.log('contentsDomNodeWidth : ', contentsDomNodeWidth); + console.log('contentsDomNodeHeight : ', contentsDomNodeHeight); + } + + containerDomNode.style.width = containerDomNodeWidth + 'px'; + containerDomNode.style.height = containerDomNodeHeight + 'px'; + contentsDomNode.style.width = contentsDomNodeWidth + 'px'; + contentsDomNode.style.height = contentsDomNodeHeight + 'px'; // this._editor.addContentWidget(this._widget); // this._editor.layoutContentWidget(this._widget); @@ -1305,6 +1339,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._editor.layoutContentWidget(this); + this._editor.render(); console.log('* After layout content widget'); containerDomNode = this.getDomNode(); diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index b667c09e174c0..58246c7bf3c1d 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ .monaco-editor .hoverHighlight { - background-color: transparent; + background-color: var(--vscode-editor-hoverHighlightBackground); } .monaco-editor .monaco-hover { color: var(--vscode-editorHoverWidget-foreground); - background-color: transparent; + background-color: var(--vscode-editorHoverWidget-background); border: 1px solid var(--vscode-editorHoverWidget-border); } @@ -22,11 +22,11 @@ } .monaco-editor .monaco-hover .hover-row .actions { - background-color: transparent; + background-color: var(--vscode-editorHoverWidget-statusBarBackground); } .monaco-editor .monaco-hover code { - background-color: transparent; + background-color: var(--vscode-textCodeBlock-background); } .monaco-editor .resizable-hover { From 47c42b12027c04d928c8ee1af045bcd3ff800c4d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 21:40:17 +0100 Subject: [PATCH 63/95] Added code in order to add the additional pixel padding only when the horizontal padding is supposed to be visible, not otherwise --- .../contrib/hover/browser/contentHover.ts | 61 +++++++++++++------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index fb44e970df9f6..030524f97ef74 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -1295,8 +1295,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('persisted size : ', persistedSize); // Added here but does not seem to have an effect - if (persistedSize) { + if (persistedSize && renderingType) { + console.log('When there is a persisted size'); // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one let containerDomNodeWidth = persistedSize.width - 8; @@ -1304,25 +1305,31 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let contentsDomNodeWidth = persistedSize.width - 8; let contentsDomNodeHeight = persistedSize.height - 18; - if (renderingType) { - const maxRenderingHeight = this.findMaxRenderingHeight(renderingType); - const maxRenderingWidth = this.findMaxRenderingWidth(); - console.log('maxRenderingHeight : ', maxRenderingHeight); - console.log('maxRenderingWidth : ', maxRenderingWidth); - - if (maxRenderingHeight && maxRenderingWidth) { - containerDomNodeWidth = Math.min(maxRenderingWidth, containerDomNodeWidth); - containerDomNodeHeight = Math.min(maxRenderingHeight, containerDomNodeHeight); - contentsDomNodeWidth = Math.min(maxRenderingWidth, contentsDomNodeWidth); - contentsDomNodeHeight = Math.min(maxRenderingHeight - 10, contentsDomNodeHeight); - } + const maxRenderingHeight = this.findMaxRenderingHeight(renderingType); + const maxRenderingWidth = this.findMaxRenderingWidth(); + console.log('maxRenderingHeight : ', maxRenderingHeight); + console.log('maxRenderingWidth : ', maxRenderingWidth); + + + let value; + let valueMinusTen; + + if (maxRenderingHeight && maxRenderingWidth) { + + value = Math.min(maxRenderingHeight, persistedSize.height - 8); + valueMinusTen = Math.min(maxRenderingHeight - 10, persistedSize.height - 18); - console.log('containerDomNodeWidth : ', containerDomNodeWidth); - console.log('containerDomNodeHeight : ', containerDomNodeHeight); - console.log('contentsDomNodeWidth : ', contentsDomNodeWidth); - console.log('contentsDomNodeHeight : ', contentsDomNodeHeight); + containerDomNodeWidth = Math.min(maxRenderingWidth, containerDomNodeWidth); + containerDomNodeHeight = Math.min(maxRenderingHeight, containerDomNodeHeight); + contentsDomNodeWidth = Math.min(maxRenderingWidth, contentsDomNodeWidth); + contentsDomNodeHeight = value; } + console.log('containerDomNodeWidth : ', containerDomNodeWidth); + console.log('containerDomNodeHeight : ', containerDomNodeHeight); + console.log('contentsDomNodeWidth : ', contentsDomNodeWidth); + console.log('contentsDomNodeHeight : ', contentsDomNodeHeight); + containerDomNode.style.width = containerDomNodeWidth + 'px'; containerDomNode.style.height = containerDomNodeHeight + 'px'; contentsDomNode.style.width = contentsDomNodeWidth + 'px'; @@ -1331,15 +1338,29 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // this._editor.addContentWidget(this._widget); // this._editor.layoutContentWidget(this._widget); // this._editor.render(); + this._editor.layoutContentWidget(this); + this._editor.render(); + + console.log('contentsDomNode.clientWidth ; ', contentsDomNode.clientWidth); + console.log('contentsDomNode.scrollWidth : ', contentsDomNode.scrollWidth); + + if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth && valueMinusTen) { + console.log('In the case when the horizontal scroll bar should be visible'); + // In that case the scrollbar is not visible, make the contents dom node height bigger + contentsDomNode.style.height = valueMinusTen + 'px'; + this._editor.layoutContentWidget(this); + this._editor.render(); + } + } else { containerDomNode.style.width = 'auto'; containerDomNode.style.height = 'auto'; contentsDomNode.style.width = 'auto'; contentsDomNode.style.height = 'auto'; - } - this._editor.layoutContentWidget(this); - this._editor.render(); + this._editor.layoutContentWidget(this); + this._editor.render(); + } console.log('* After layout content widget'); containerDomNode = this.getDomNode(); From ac4b896575e91bca530aaa60af2982735ab6836c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 22:24:28 +0100 Subject: [PATCH 64/95] changing the height of the contents dom node depending on whether the horizontal scrollbar is visible or not --- .../contrib/hover/browser/contentHover.ts | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 030524f97ef74..8fd8e8648e914 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -741,6 +741,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget if (!this._maxRenderingHeight || !this._maxRenderingWidth) { return; } + this._resizableElement.minSize = new dom.Dimension(10, 24); this._resizableElement.maxSize = new dom.Dimension(this._maxRenderingWidth, this._maxRenderingHeight); @@ -1014,10 +1015,23 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: Place back? // Need this in order for the vertical scroll bar to appear this._hover.contentsDomNode.style.width = size.width - 6 + 'px'; - this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; + this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; + this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); - this._hover.scrollbar.scanDomNode(); + + console.log('Before horizontal scorllbar check'); + console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + + if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { + console.log('In the case when the horizontal scroll bar should be visible'); + this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; + this._hover.scrollbar.scanDomNode(); + this._editor.layoutContentWidget(this); + this._editor.render(); + + console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + } } public getSize() { @@ -1050,7 +1064,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } console.log('actual max height : ', actualMaxHeight); // Adding 10 also in order to allow some space for the horizontal scrollbar - const maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 16); + let maxRenderingHeight; + if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { + // Scrollbar is visible, hence make the max rendering height bigger + maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 16); + } else { + maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 6); + } + console.log('maxRenderingHeight : ', maxRenderingHeight); return maxRenderingHeight; } @@ -1303,8 +1324,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let containerDomNodeWidth = persistedSize.width - 8; let containerDomNodeHeight = persistedSize.height - 8; let contentsDomNodeWidth = persistedSize.width - 8; - let contentsDomNodeHeight = persistedSize.height - 18; + let contentsDomNodeHeight = persistedSize.height - 8; // - 18 when scrollbar + // Already takes into account the horizontal scroll bar calculation const maxRenderingHeight = this.findMaxRenderingHeight(renderingType); const maxRenderingWidth = this.findMaxRenderingWidth(); console.log('maxRenderingHeight : ', maxRenderingHeight); @@ -1317,7 +1339,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (maxRenderingHeight && maxRenderingWidth) { value = Math.min(maxRenderingHeight, persistedSize.height - 8); - valueMinusTen = Math.min(maxRenderingHeight - 10, persistedSize.height - 18); + valueMinusTen = Math.min(maxRenderingHeight, persistedSize.height - 18); containerDomNodeWidth = Math.min(maxRenderingWidth, containerDomNodeWidth); containerDomNodeHeight = Math.min(maxRenderingHeight, containerDomNodeHeight); @@ -1346,8 +1368,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth && valueMinusTen) { console.log('In the case when the horizontal scroll bar should be visible'); + console.log('valueMinusTen : ', valueMinusTen); + console.log('value : ', value); // In that case the scrollbar is not visible, make the contents dom node height bigger contentsDomNode.style.height = valueMinusTen + 'px'; + this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); } From 90b6921a78bbd6dc43085e78e53df1922231f3e4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 23:17:48 +0100 Subject: [PATCH 65/95] Changes the pixels so that the height does not change --- .../contrib/hover/browser/contentHover.ts | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 8fd8e8648e914..288a4d1dca88d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -953,6 +953,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _renderingType: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + private _appearedWithHorizontalScrollbar: boolean | undefined = undefined; /** * Returns `null` if the hover is not visible. @@ -1025,11 +1026,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { console.log('In the case when the horizontal scroll bar should be visible'); - this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; - this._hover.scrollbar.scanDomNode(); - this._editor.layoutContentWidget(this); - this._editor.render(); - + console.log('appearedWithHorizontalScrollBar : ', this._appearedWithHorizontalScrollbar); + if (this._appearedWithHorizontalScrollbar) { + this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; + this._hover.scrollbar.scanDomNode(); + this._editor.layoutContentWidget(this); + this._editor.render(); + } else { + this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; + this._hover.scrollbar.scanDomNode(); + this._editor.layoutContentWidget(this); + this._editor.render(); + } console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); } } @@ -1286,6 +1294,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public hide(): void { console.log('Inside of hide of the content hover widget'); + this._appearedWithHorizontalScrollbar = undefined; if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); @@ -1296,7 +1305,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } - public onContentsChanged(persistedSize?: dom.Dimension | undefined, renderingType?: ContentWidgetPositionPreference | undefined): void { + public onContentsChanged( + persistedSize?: dom.Dimension | undefined, + renderingType?: ContentWidgetPositionPreference | undefined): void { console.log('* Inside of contents changed'); console.log('* Before changes'); @@ -1370,11 +1381,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('In the case when the horizontal scroll bar should be visible'); console.log('valueMinusTen : ', valueMinusTen); console.log('value : ', value); + if (this._appearedWithHorizontalScrollbar === undefined) { + this._appearedWithHorizontalScrollbar = true; + } // In that case the scrollbar is not visible, make the contents dom node height bigger contentsDomNode.style.height = valueMinusTen + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); + } else { + if (this._appearedWithHorizontalScrollbar === undefined) { + this._appearedWithHorizontalScrollbar = false; + } } } else { From 24a790fbb8722d05733859baab163fe72cc2b112 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Sun, 19 Mar 2023 23:52:23 +0100 Subject: [PATCH 66/95] pixel sizes changed when not using a persisted size, need to further clean the code --- .../editor/contrib/hover/browser/contentHover.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 288a4d1dca88d..ddd88769d3b54 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -31,6 +31,8 @@ const $ = dom.$; // TODO: remove the double flickering that happens on double rendering, but is it possible to remove it really? // TODO: correct potential errors on sticky hover +// TODO: test the case when there is a hover which without a persist size, has a horizontal scrollbar +// TODO: when hover appears with a horizontal scroll-bar, not persisted, and resized, make sure the scroll-bar is there class ResizeState { constructor( @@ -1013,8 +1015,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } this._hover.containerDomNode.style.width = size.width - 6 + 'px'; this._hover.containerDomNode.style.height = size.height - 6 + 'px'; - // TODO: Place back? - // Need this in order for the vertical scroll bar to appear this._hover.contentsDomNode.style.width = size.width - 6 + 'px'; this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; this._hover.scrollbar.scanDomNode(); @@ -1027,13 +1027,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { console.log('In the case when the horizontal scroll bar should be visible'); console.log('appearedWithHorizontalScrollBar : ', this._appearedWithHorizontalScrollbar); - if (this._appearedWithHorizontalScrollbar) { + // undefined meaning that not using persisted size + if (this._appearedWithHorizontalScrollbar === true || this._appearedWithHorizontalScrollbar === undefined) { this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); } else { this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; + // const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; + // if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { + // this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; + // } this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); @@ -1218,6 +1223,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = persistedSize.height; this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; + } else { height = containerDomNode.clientHeight; this._hover.contentsDomNode.style.maxHeight = `${Math.max(this._editor.getLayoutInfo().height / 4, 250)}px`; @@ -1368,9 +1374,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { contentsDomNode.style.width = contentsDomNodeWidth + 'px'; contentsDomNode.style.height = contentsDomNodeHeight + 'px'; - // this._editor.addContentWidget(this._widget); - // this._editor.layoutContentWidget(this._widget); - // this._editor.render(); this._editor.layoutContentWidget(this); this._editor.render(); @@ -1396,6 +1399,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } else { + containerDomNode.style.width = 'auto'; containerDomNode.style.height = 'auto'; contentsDomNode.style.width = 'auto'; From 1899e742e3f833a1e83f7d8c02dfb7c13e148379 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 00:18:04 +0100 Subject: [PATCH 67/95] added code in order to also know whether it is the first rendering or not --- .../contrib/hover/browser/contentHover.ts | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index ddd88769d3b54..63fece8cdf8f4 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -315,7 +315,8 @@ export class ContentHoverController extends Disposable { const persistedSize = this._resizableWidget.findPersistedSize(); console.log('persistedSize : ', persistedSize); - this._widget.onContentsChanged(persistedSize, this._widget.renderingType); + const firstRendering = true; + this._widget.onContentsChanged(firstRendering, persistedSize, this._widget.renderingType); this._editor.render(); console.log('After onContentsChanged'); @@ -943,6 +944,13 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } +enum States { + PERSIST_SIZE_HORIZONTALL_VISIBLE = 1, + PERSIST_SIZE_HORZONTAL_NOT_VISIBLE = 2, + NOT_PERSIST_SIZE_HORIZONTAL_VISIBLE = 3, + NOT_PERSIST_SIZE_HORIZONTAL_NOT_VISIBLE = 4 +} + export class ContentHoverWidget extends Disposable implements IContentWidget { static readonly ID = 'editor.contrib.contentHoverWidget'; @@ -955,7 +963,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _renderingType: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - private _appearedWithHorizontalScrollbar: boolean | undefined = undefined; + private _appearedWithHorizontalScrollbar: States | undefined = undefined; /** * Returns `null` if the hover is not visible. @@ -1028,12 +1036,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('In the case when the horizontal scroll bar should be visible'); console.log('appearedWithHorizontalScrollBar : ', this._appearedWithHorizontalScrollbar); // undefined meaning that not using persisted size - if (this._appearedWithHorizontalScrollbar === true || this._appearedWithHorizontalScrollbar === undefined) { + if (this._appearedWithHorizontalScrollbar === States.PERSIST_SIZE_HORIZONTALL_VISIBLE || this._appearedWithHorizontalScrollbar === States.NOT_PERSIST_SIZE_HORIZONTAL_VISIBLE) { + console.log('first if statement'); this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); - } else { + } else if (this._appearedWithHorizontalScrollbar === States.PERSIST_SIZE_HORZONTAL_NOT_VISIBLE || this._appearedWithHorizontalScrollbar === States.NOT_PERSIST_SIZE_HORIZONTAL_NOT_VISIBLE) { + console.log('second if statement'); this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; // const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; // if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { @@ -1312,6 +1322,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public onContentsChanged( + firstRendering: boolean = false, persistedSize?: dom.Dimension | undefined, renderingType?: ContentWidgetPositionPreference | undefined): void { @@ -1385,7 +1396,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('valueMinusTen : ', valueMinusTen); console.log('value : ', value); if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = true; + this._appearedWithHorizontalScrollbar = States.PERSIST_SIZE_HORIZONTALL_VISIBLE; } // In that case the scrollbar is not visible, make the contents dom node height bigger contentsDomNode.style.height = valueMinusTen + 'px'; @@ -1394,7 +1405,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.render(); } else { if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = false; + this._appearedWithHorizontalScrollbar = States.PERSIST_SIZE_HORZONTAL_NOT_VISIBLE; } } @@ -1466,6 +1477,22 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); this._hover.scrollbar.scanDomNode(); + + if (firstRendering && !persistedSize) { + console.log('When this._appearedWithHorizontalScrollbar set : ', this._appearedWithHorizontalScrollbar); + console.log('contentsDomNode.clientWidth : ', contentsDomNode.clientWidth); + console.log('contentsDomNode.scrollWidth : ', contentsDomNode.scrollWidth); + + if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth) { + if (this._appearedWithHorizontalScrollbar === undefined) { + this._appearedWithHorizontalScrollbar = States.NOT_PERSIST_SIZE_HORIZONTAL_VISIBLE; + } + } else { + if (this._appearedWithHorizontalScrollbar === undefined) { + this._appearedWithHorizontalScrollbar = States.NOT_PERSIST_SIZE_HORIZONTAL_NOT_VISIBLE; + } + } + } } public clear(): void { From 8114a1b2d74cd7b571d1f4b36ac51a1d7e5a625f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 13:02:52 +0100 Subject: [PATCH 68/95] cleaning the code --- src/vs/base/browser/ui/hover/hoverWidget.ts | 1 - .../browser/ui/scrollbar/scrollableElement.ts | 1 - .../contrib/hover/browser/contentHover.ts | 197 ++++++++++-------- src/vs/editor/contrib/hover/browser/hover.ts | 15 +- 4 files changed, 112 insertions(+), 102 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hoverWidget.ts b/src/vs/base/browser/ui/hover/hoverWidget.ts index eb40ee926a9a4..96e99cbec4a2f 100644 --- a/src/vs/base/browser/ui/hover/hoverWidget.ts +++ b/src/vs/base/browser/ui/hover/hoverWidget.ts @@ -28,7 +28,6 @@ export class HoverWidget extends Disposable { this.containerDomNode = document.createElement('div'); this.containerDomNode.className = 'monaco-hover'; this.containerDomNode.tabIndex = 0; - this.containerDomNode.style.zIndex = '10'; this.containerDomNode.setAttribute('role', 'tooltip'); this.contentsDomNode = document.createElement('div'); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index b8172c5e4a937..87d4ed4d9fa38 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -637,7 +637,6 @@ export class DomScrollableElement extends AbstractScrollableElement { } public scanDomNode(): void { - console.log('Inside of scanDomNode()'); // width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight this.setScrollDimensions({ width: this._element.clientWidth, diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 63fece8cdf8f4..caaa2306f4a43 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -29,11 +29,6 @@ import { Emitter, Event } from 'vs/base/common/event'; const $ = dom.$; -// TODO: remove the double flickering that happens on double rendering, but is it possible to remove it really? -// TODO: correct potential errors on sticky hover -// TODO: test the case when there is a hover which without a persist size, has a horizontal scrollbar -// TODO: when hover appears with a horizontal scroll-bar, not persisted, and resized, make sure the scroll-bar is there - class ResizeState { constructor( readonly persistedSize: dom.Dimension | undefined, @@ -46,7 +41,7 @@ class ResizeState { export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; - private readonly _resizableWidget = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); + private readonly _resizableOverlay = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; @@ -60,9 +55,7 @@ export class ContentHoverController extends Disposable { ) { super(); - this._resizableWidget.containingWidget = this._widget; - this._widget._hover.scrollbar.scanDomNode(); - + this._resizableOverlay.containingWidget = this._widget; // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -78,7 +71,6 @@ export class ContentHoverController extends Disposable { // invalid state, ignore result return; } - console.log('* Result of the hover operation is attained'); const messages = (result.hasLoadingMessage ? this._addLoadingMessage(result.value) : result.value); this._withResult(new HoverResult(this._computer.anchor, messages, result.isComplete)); })); @@ -93,20 +85,18 @@ export class ContentHoverController extends Disposable { this._setCurrentResult(this._currentResult); // render again } })); - this._register(this._editor.onDidChangeModel(() => { - this._resizableWidget.hide(); - })); - this._register(this._resizableWidget.onDidResize((e) => { + this._register(this._resizableOverlay.onDidResize((e) => { this._widget.resize(e.dimension); + // Update the left offset of the resizable element when the widget has been resized const offsetLeft = this._widget.getDomNode().offsetLeft; if (offsetLeft) { - this._resizableWidget.getDomNode().style.left = offsetLeft - 1 + 'px'; + this._resizableOverlay.getDomNode().style.left = offsetLeft - 1 + 'px'; } })); } - get resizableWidget() { - return this._resizableWidget; + get resizableOverlay() { + return this._resizableOverlay; } /** @@ -114,7 +104,8 @@ export class ContentHoverController extends Disposable { */ public maybeShowAt(mouseEvent: IEditorMouseEvent): boolean { - if (this._resizableWidget.isResizing()) { + // While the hover overlay is resizing, the hover is showing + if (this._resizableOverlay.isResizing()) { return true; } @@ -231,12 +222,11 @@ export class ContentHoverController extends Disposable { this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { this._widget.hide(); - this._resizableWidget.hide(); + this._resizableOverlay.hide(); } } public hide(): void { - console.log('Inside of hide of content hover controller'); this._computer.anchor = null; this._hoverOperation.cancel(); this._setCurrentResult(null); @@ -304,47 +294,64 @@ export class ContentHoverController extends Disposable { statusBar, setColorPicker: (widget) => colorPicker = widget, onContentsChanged: () => { + console.log('Inside of onContentsChanged of the context inside of _renderMessage'); console.log('Before onContentsChanged'); - let resizableWidgetDomNode = this._resizableWidget.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - - const persistedSize = this._resizableWidget.findPersistedSize(); + + // The dom node of the resizable overlay + // TODO: Remove after + const resizableOverlayDomNode = this._resizableOverlay.getDomNode(); + + console.log('resizableWidgetDomNode : ', resizableOverlayDomNode); + console.log('resizableWidgetDomNode client width : ', resizableOverlayDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableOverlayDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableOverlayDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableOverlayDomNode.offsetLeft); + + // Finding the resizable overlay should be outside of the on contents changed since it is a function which pertains to the resizable hover + const persistedSize = this._resizableOverlay.findPersistedSize(); + console.log('persistedSize : ', persistedSize); + + // Same goes for the boolean first rendering, since it should be defined outside of the function const firstRendering = true; - this._widget.onContentsChanged(firstRendering, persistedSize, this._widget.renderingType); + + // Do some actions when the contents of the hover changes, which appears to happen every single time after the showAt function is called + this._widget.onContentsChanged(firstRendering, persistedSize); + // TODO: do we need this forced render here? this._editor.render(); console.log('After onContentsChanged'); console.log('this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); - console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableWidget.getDomNode().offsetTop); + console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableOverlay.getDomNode().offsetTop); + // After the final rendering of the widget, retrieve its top and left offsets const widgetDomNode = this._widget.getDomNode(); - const top = widgetDomNode.offsetTop; - const left = widgetDomNode.offsetLeft; - - this._resizableWidget.resizableElement().domNode.style.top = top - 2 + 'px'; - this._resizableWidget.resizableElement().domNode.style.left = left - 2 + 'px'; - this._resizableWidget.resizableElement().domNode.style.zIndex = '5'; - this._resizableWidget.resizableElement().domNode.tabIndex = 0; - this._resizableWidget.resizableElement().domNode.style.position = 'fixed'; - const clientWidth = this._widget.getDomNode().clientWidth; - const clientHeight = this._widget.getDomNode().clientHeight; - this._resizableWidget.resizableElement().layout(clientHeight + 7, clientWidth + 7); - this._editor.layoutOverlayWidget(this._resizableWidget); + const offsetTop = widgetDomNode.offsetTop; + const offsetLeft = widgetDomNode.offsetLeft; + const clientWidth = widgetDomNode.clientWidth; + const clientHeight = widgetDomNode.clientHeight; + + // Values found by trial and error + // Update the left and top offset to match the widget dom node + const resizableElement = this._resizableOverlay.resizableElement(); + resizableElement.domNode.style.top = offsetTop - 2 + 'px'; + resizableElement.domNode.style.left = offsetLeft - 2 + 'px'; + // Set a different width and height to the resizable element + resizableElement.layout(clientHeight + 7, clientWidth + 7); + this._editor.layoutOverlayWidget(this._resizableOverlay); + // TODO: Do we need this forced rendering? this._editor.render(); - resizableWidgetDomNode = this._resizableWidget.getDomNode(); + // TODO: Do we need this scan dom node? + // this._widget._hover.scrollbar.scanDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + /** The following are for logging purposes can be removed */ + console.log('resizableWidgetDomNode : ', resizableOverlayDomNode); + console.log('resizableWidgetDomNode client width : ', resizableOverlayDomNode.clientWidth); + console.log('resizableWidgetDomNode client height : ', resizableOverlayDomNode.clientHeight); + console.log('resizableWidgetDomNode offset top : ', resizableOverlayDomNode.offsetTop); + console.log('resizableWidgetDomNode offset left : ', resizableOverlayDomNode.offsetLeft); const containerDomNode = this._widget.getDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -352,15 +359,14 @@ export class ContentHoverController extends Disposable { console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + const contentsDomNode = this._widget.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - console.log('At the end of onContentsChanged of _renderMessages'); - this._widget._hover.scrollbar.scanDomNode(); }, hide: () => this.hide() }; @@ -389,15 +395,16 @@ export class ContentHoverController extends Disposable { highlightDecoration.clear(); })); } - const preferAbove = this._editor.getOption(EditorOption.hover).above; + // Save the position of the tooltip, where the content hover should appear const tooltipPosition: IPosition = { lineNumber: showAtPosition.lineNumber, column: showAtPosition.column }; - this._resizableWidget.setToooltipPosition(tooltipPosition); - const persistedSize = this._resizableWidget.findPersistedSize(); + this._resizableOverlay.setToooltipPosition(tooltipPosition); + const persistedSize = this._resizableOverlay.findPersistedSize(); console.log('persisted size : ', persistedSize); - // Added here but does not seem to have an effect + // TODO: Added here but does not seem to have an effect + /* if (persistedSize) { this._widget.getDomNode().style.width = persistedSize.width + 'px'; this._widget.getDomNode().style.height = persistedSize.height + 'px'; @@ -405,9 +412,11 @@ export class ContentHoverController extends Disposable { this._editor.layoutContentWidget(this._widget); this._editor.render(); } + */ + // The following is added for logginh purposes console.log('* Before this._widget.showAt'); - let resizableWidgetDomNode = this._resizableWidget.getDomNode(); + let resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); @@ -418,7 +427,7 @@ export class ContentHoverController extends Disposable { colorPicker, showAtPosition, showAtSecondaryPosition, - preferAbove, + this._editor.getOption(EditorOption.hover).above, this._computer.shouldFocus, this._computer.source, isBeforeContent, @@ -429,18 +438,20 @@ export class ContentHoverController extends Disposable { console.log('* After this._widget.showAt'); console.log('* Before layoutContentWidget and render'); - // Before there wasn't any of this below + + // TODO: Do we actually need to layout the content widget here? this._editor.layoutContentWidget(this._widget); this._editor.render(); - console.log('* After layoutContentWidget and render'); const containerDomNode = this._widget.getDomNode(); + + console.log('* After layoutContentWidget and render'); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - resizableWidgetDomNode = this._resizableWidget.getDomNode(); + resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); @@ -453,28 +464,28 @@ export class ContentHoverController extends Disposable { console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - resizableWidgetDomNode = this._resizableWidget.getDomNode(); + resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - const size = new dom.Dimension(this._widget.getDomNode().clientWidth, this._widget.getDomNode().clientHeight); + // Saving the top, left offsets and the client widths and heights + const size = new dom.Dimension(containerDomNode.clientWidth, containerDomNode.clientHeight); + const position = { clientTop: containerDomNode.offsetTop, clientLeft: containerDomNode.offsetLeft }; console.log('size : ', size); - const position = { clientTop: this._widget.getDomNode().offsetTop, clientLeft: this._widget.getDomNode().offsetLeft }; console.log('position : ', position); + resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('* Before showAt of resizableWidget'); - resizableWidgetDomNode = this._resizableWidget.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // Find if rendered above or below - + // Find if rendered above or below in the container dom node const topLineNumber = anchor.initialMousePosY; console.log('topLineNumber : ', topLineNumber); console.log('position.clientTop : ', position.clientTop); @@ -491,17 +502,19 @@ export class ContentHoverController extends Disposable { console.log('Rendering above : ', renderingAbove); - this._resizableWidget.showAt(position, size, renderingAbove); + // Calling show at with the position, size and rendering above option + this._resizableOverlay.showAt(position, size, renderingAbove); console.log('* After showAt of resizableWidget'); - resizableWidgetDomNode = this._resizableWidget.getDomNode(); + resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - this._widget._hover.scrollbar.scanDomNode(); + // TODO: do we need to force scan the dom node? + // this._widget._hover.scrollbar.scanDomNode(); } else { disposables.dispose(); } @@ -621,25 +634,40 @@ class ContentHoverVisibleData { export class ResizableHoverOverlay extends Disposable implements IOverlayWidget { static readonly ID = 'editor.contrib.resizableHoverOverlay'; - private _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); - private _resizing: boolean = false; + // Creating a new resizable HTML element + private readonly _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); + // Map which maps from a text model URI, to a map from the stringified version of [offset, left] to the dom dimension private readonly _persistedHoverWidgetSizes = new Map>(); + // Boolean which is indicating whether we are currently resizing or not + private _resizing: boolean = false; + // The current size of the resizable element private _size: dom.Dimension | null = null; + // The initial height of the content hover when it first appears private _initialHeight: number = -1; + // The initial top of the content hover widget when it first appears private _initialTop: number = -1; - private _maxRenderingHeight: number | undefined; - private _maxRenderingWidth: number | undefined; + // The maximum rendering height + private _maxRenderingHeight: number | undefined = undefined; + // The maximum rendering width + private _maxRenderingWidth: number | undefined = undefined; + // The position where to render the hover private _tooltipPosition: IPosition | null = null; - private _renderingPosition: IOverlayWidgetPosition | null = null; + // Boolean indicating whether the hover is visible private _visible: boolean = false; + private _renderingAbove: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; - private _containingWidget: ContentHoverWidget | null = null; + // The hover widget which appears above the resizable overlay + private _hoverWidget: ContentHoverWidget | null = null; private readonly _onDidResize = new Emitter(); readonly onDidResize: Event = this._onDidResize.event; constructor(private readonly _editor: ICodeEditor) { super(); + this._resizableElement.domNode.style.zIndex = '5'; + this._resizableElement.domNode.tabIndex = 0; + this._resizableElement.domNode.style.position = 'fixed'; + this._maxRenderingHeight = this._editor.getLayoutInfo().height; console.log('Inside of constructor of ResizableHoverOverlay'); @@ -733,12 +761,12 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // console.log('this._containingWidget : ', this._containingWidget); - if (!this._containingWidget) { + if (!this._hoverWidget) { return; } - this._maxRenderingWidth = this._containingWidget.findMaxRenderingWidth(); - this._maxRenderingHeight = this._containingWidget.findMaxRenderingHeight(this._renderingAbove); + this._maxRenderingWidth = this._hoverWidget.findMaxRenderingWidth(); + this._maxRenderingHeight = this._hoverWidget.findMaxRenderingHeight(this._renderingAbove); // console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight || !this._maxRenderingWidth) { @@ -810,7 +838,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget public set containingWidget(containingWidget: ContentHoverWidget) { console.log('setting the containing widget'); - this._containingWidget = containingWidget; + this._hoverWidget = containingWidget; } public findPersistedSize(): dom.Dimension | undefined { @@ -867,14 +895,9 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._tooltipPosition = position; } - public setPosition(renderingPosition: IOverlayWidgetPosition): void { - this._renderingPosition = renderingPosition; - } - public getPosition(): IOverlayWidgetPosition | null { console.log('Inside of getPosition of ResizableHoverOverlay'); - console.log('this._renderingPosition : ', this._renderingPosition); - return this._renderingPosition; + return null; } public showAt(position: any, size: dom.Dimension, renderingAbove: boolean): void { @@ -1323,8 +1346,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public onContentsChanged( firstRendering: boolean = false, - persistedSize?: dom.Dimension | undefined, - renderingType?: ContentWidgetPositionPreference | undefined): void { + persistedSize?: dom.Dimension | undefined + ): void { console.log('* Inside of contents changed'); console.log('* Before changes'); @@ -1343,6 +1366,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('persisted size : ', persistedSize); + const renderingType = this._renderingType; + // Added here but does not seem to have an effect if (persistedSize && renderingType) { diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index f3f95a470116e..200ec24f72e77 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -125,7 +125,6 @@ export class ModesHoverController implements IEditorContribution { if (target.type !== MouseTargetType.OVERLAY_WIDGET) { this._hoverClicked = false; } - console.log('mouseEvent : ', mouseEvent); this._hideWidgets(); } @@ -143,22 +142,18 @@ export class ModesHoverController implements IEditorContribution { } private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { - // console.log('Inside of _onEditorMouseMove'); const target = mouseEvent.target; if (this._isMouseDown && this._hoverClicked) { - // console.log('If mouse down and hover clicked'); return; } if (this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID) { - // console.log('second if statement'); // mouse moved on top of content hover widget return; } if (this._isHoverSticky && !mouseEvent.event.browserEvent.view?.getSelection()?.isCollapsed) { - // console.log('third if statement'); // selected text within content hover widget return; } @@ -167,26 +162,22 @@ export class ModesHoverController implements IEditorContribution { !this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID && this._contentWidget?.isColorPickerVisible() ) { - // console.log('4th if statement'); // though the hover is not sticky, the color picker needs to. return; } if (this._isHoverSticky && target.type === MouseTargetType.OVERLAY_WIDGET && target.detail === MarginHoverWidget.ID) { - // console.log('5th if statement'); // mouse moved on top of overlay hover widget return; } if (this._isHoverSticky && this._contentWidget?.isVisibleFromKeyboard()) { - // console.log('6th if statement'); // Sticky mode is on and the hover has been shown via keyboard // so moving the mouse has no effect return; } if (!this._isHoverEnabled) { - // console.log('7th if statement'); this._hideWidgets(); return; } @@ -194,13 +185,11 @@ export class ModesHoverController implements IEditorContribution { const contentWidget = this._getOrCreateContentWidget(); if (contentWidget.maybeShowAt(mouseEvent)) { - // console.log('Inside of 8th if statement'); this._glyphWidget?.hide(); return; } if (target.type === MouseTargetType.GUTTER_GLYPH_MARGIN && target.position) { - // console.log('Inside of 9th if statement'); this._contentWidget?.hide(); if (!this._glyphWidget) { this._glyphWidget = new MarginHoverWidget(this._editor, this._languageService, this._openerService); @@ -229,15 +218,13 @@ export class ModesHoverController implements IEditorContribution { } private _hideWidgets(): void { - // console.log('Inside of _hideWidget'); if ((this._isMouseDown && this._hoverClicked && this._contentWidget?.isColorPickerVisible()) || InlineSuggestionHintsContentWidget.dropDownVisible) { return; } this._hoverClicked = false; this._glyphWidget?.hide(); - // console.log('this._contentWidget?.resizableWidget.isResizing() : ', this._contentWidget?.resizableWidget.isResizing()); - if (!this._contentWidget?.resizableWidget.isResizing()) { + if (!this._contentWidget?.resizableOverlay.isResizing()) { this._contentWidget?.hide(); } } From b57836d3e114ad907a556728a500a0a25843f9f7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 14:59:34 +0100 Subject: [PATCH 69/95] cleaned the code --- .../contrib/hover/browser/contentHover.ts | 344 +++++++----------- src/vs/editor/contrib/hover/browser/hover.css | 4 +- src/vs/editor/contrib/hover/browser/hover.ts | 2 + 3 files changed, 137 insertions(+), 213 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index caaa2306f4a43..ff45cacce7f60 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -29,15 +29,6 @@ import { Emitter, Event } from 'vs/base/common/event'; const $ = dom.$; -class ResizeState { - constructor( - readonly persistedSize: dom.Dimension | undefined, - readonly currentSize: dom.Dimension, - public persistHeight = false, - public persistWidth = false, - ) { } -} - export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; @@ -55,7 +46,7 @@ export class ContentHoverController extends Disposable { ) { super(); - this._resizableOverlay.containingWidget = this._widget; + this._resizableOverlay.hoverWidget = this._widget; // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; for (const participant of HoverParticipantRegistry.getAll()) { @@ -398,6 +389,7 @@ export class ContentHoverController extends Disposable { // Save the position of the tooltip, where the content hover should appear const tooltipPosition: IPosition = { lineNumber: showAtPosition.lineNumber, column: showAtPosition.column }; + // The tooltip position is saved in the resizable overlay this._resizableOverlay.setToooltipPosition(tooltipPosition); const persistedSize = this._resizableOverlay.findPersistedSize(); @@ -414,15 +406,16 @@ export class ContentHoverController extends Disposable { } */ - // The following is added for logginh purposes - console.log('* Before this._widget.showAt'); + // The following is added for logging purposes let resizableWidgetDomNode = this._resizableOverlay.getDomNode(); + console.log('* Before this._widget.showAt'); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + // The persisted size is used in the content hover widget this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, showAtPosition, @@ -474,9 +467,11 @@ export class ContentHoverController extends Disposable { // Saving the top, left offsets and the client widths and heights const size = new dom.Dimension(containerDomNode.clientWidth, containerDomNode.clientHeight); const position = { clientTop: containerDomNode.offsetTop, clientLeft: containerDomNode.offsetLeft }; + console.log('size : ', size); console.log('position : ', position); + // Added for logging purposes resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('* Before showAt of resizableWidget'); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -500,13 +495,14 @@ export class ContentHoverController extends Disposable { } } - console.log('Rendering above : ', renderingAbove); + console.log('rendering above : ', renderingAbove); // Calling show at with the position, size and rendering above option this._resizableOverlay.showAt(position, size, renderingAbove); - console.log('* After showAt of resizableWidget'); + // Added for logging purposes resizableWidgetDomNode = this._resizableOverlay.getDomNode(); + console.log('* After showAt of resizableWidget'); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); @@ -647,78 +643,58 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // The initial top of the content hover widget when it first appears private _initialTop: number = -1; // The maximum rendering height - private _maxRenderingHeight: number | undefined = undefined; + private _maxRenderingHeight: number | undefined = this._editor.getLayoutInfo().height; // The maximum rendering width - private _maxRenderingWidth: number | undefined = undefined; + private _maxRenderingWidth: number | undefined = this._editor.getLayoutInfo().width; // The position where to render the hover private _tooltipPosition: IPosition | null = null; - // Boolean indicating whether the hover is visible - private _visible: boolean = false; - - private _renderingAbove: ContentWidgetPositionPreference = ContentWidgetPositionPreference.ABOVE; + // Boolean indicating whether we are rendering above or below + private _renderingAbove: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; // The hover widget which appears above the resizable overlay private _hoverWidget: ContentHoverWidget | null = null; + // Event emitter which fires whenever the resizable hover is resized private readonly _onDidResize = new Emitter(); readonly onDidResize: Event = this._onDidResize.event; constructor(private readonly _editor: ICodeEditor) { super(); - this._resizableElement.domNode.style.zIndex = '5'; - this._resizableElement.domNode.tabIndex = 0; - this._resizableElement.domNode.style.position = 'fixed'; - - this._maxRenderingHeight = this._editor.getLayoutInfo().height; - console.log('Inside of constructor of ResizableHoverOverlay'); + // The minimum size is fixed + this._resizableElement.minSize = new dom.Dimension(10, 24); this._editor.onDidChangeModelContent((e) => { - console.log('onDidChangeModelContent'); - console.log('e : ', e); const uri = this._editor.getModel()?.uri.toString(); - console.log('uri : ', uri); - console.log('this._persistedHoverWidgetSizes : ', this._persistedHoverWidgetSizes); if (!uri || !this._persistedHoverWidgetSizes.has(uri)) { return; } - const mapToUpdate = this._persistedHoverWidgetSizes.get(uri)!; - const newMap = new Map(); - console.log('mapToUpdate : ', mapToUpdate); + const persistedSizesForUri = this._persistedHoverWidgetSizes.get(uri)!; + const updatedPersistedSizesForUri = new Map(); for (const change of e.changes) { const changeOffset = change.rangeOffset; const rangeLength = change.rangeLength; const endOffset = changeOffset + rangeLength; const textLength = change.text.length; - console.log('changeOffset : ', changeOffset); - console.log('rangeLength : ', rangeLength); - console.log('endOffset : ', endOffset); - console.log('textLength : ', textLength); - for (const stringifiedEntry of mapToUpdate.keys()) { - const entry = JSON.parse(stringifiedEntry); - console.log('entry : ', entry); - if (endOffset < entry[0]) { - console.log('first if statement'); - const oldSize = mapToUpdate.get(stringifiedEntry)!; - console.log('oldSize : ', oldSize); - console.log('entry[0] - rangeLength + textLength : ', entry[0] - rangeLength + textLength); - const newEntry: [number, number] = [entry[0] - rangeLength + textLength, entry[1]]; - console.log('newEntry : ', newEntry); - newMap.set(JSON.stringify(newEntry), oldSize); - } else if (changeOffset >= entry[0] + entry[1]) { - console.log('second if statement'); - newMap.set(stringifiedEntry, mapToUpdate.get(stringifiedEntry)!); + for (const key of persistedSizesForUri.keys()) { + const parsedKey = JSON.parse(key); + const tokenOffset = parsedKey[0]; + const tokenLength = parsedKey[1]; + if (endOffset < tokenOffset) { + const oldSize = persistedSizesForUri.get(key)!; + const newKey: [number, number] = [tokenOffset - rangeLength + textLength, tokenLength]; + updatedPersistedSizesForUri.set(JSON.stringify(newKey), oldSize); + } else if (changeOffset >= tokenOffset + tokenLength) { + updatedPersistedSizesForUri.set(key, persistedSizesForUri.get(key)!); } } } - this._persistedHoverWidgetSizes.set(uri, newMap); + this._persistedHoverWidgetSizes.set(uri, updatedPersistedSizesForUri); }); - let state: ResizeState | undefined; - this._register(this._resizableElement.onDidWillResize(() => { console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); - const persistedSize = this.findPersistedSize(); - state = new ResizeState(persistedSize, this._resizableElement.size); + this._resizing = true; + // Saving the intiial height and the initial top of the resizable element this._initialHeight = this._resizableElement.domNode.clientHeight; this._initialTop = this._resizableElement.domNode.offsetTop; })); @@ -727,138 +703,103 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('* Inside of onDidResize of ContentHoverWidget'); console.log('e : ', e); - if (!this._visible) { - this._resizing = false; - return; - } - let height = e.dimension.height; let width = e.dimension.width; const maxWidth = this._resizableElement.maxSize.width; const maxHeight = this._resizableElement.maxSize.height; + // Cap the width to the maximum width and the height to the current maximum height width = Math.min(maxWidth, width); height = Math.min(maxHeight, height); if (!this._maxRenderingHeight) { return; } + // Setting the new width and height parameters this._size = new dom.Dimension(width, height); + // Updating the height and width parameters of the resizable element this._resizableElement.layout(height, width); + console.log('this._initialTop : ', this._initialTop); console.log('this._intiialHeight : ', this._initialHeight); console.log('height : ', height); console.log('this._initialTop - (height - this._initialHeight) : ', this._initialTop - (height - this._initialHeight)); - // When resizing and then the size is smaller so that can be displayed above, display above - // if (height <= maxHeightAbove && this._renderingAbove === ContentWidgetPositionPreference.BELOW) { - // this._renderingAbove = ContentWidgetPositionPreference.ABOVE; - // } - + // Update the top parameters only when we decided to render above if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; } + // Fire the current dimension this._onDidResize.fire({ dimension: this._size, done: false }); - // console.log('this._containingWidget : ', this._containingWidget); - if (!this._hoverWidget) { return; } + // After the content hover widget has been resized, we find the new max rendering height and width + // Maybe should be waiting for the content hover widget to resize, it appears not though this._maxRenderingWidth = this._hoverWidget.findMaxRenderingWidth(); this._maxRenderingHeight = this._hoverWidget.findMaxRenderingHeight(this._renderingAbove); - // console.log('this._maxRenderingHeight : ', this._maxRenderingHeight); if (!this._maxRenderingHeight || !this._maxRenderingWidth) { return; } - this._resizableElement.minSize = new dom.Dimension(10, 24); this._resizableElement.maxSize = new dom.Dimension(this._maxRenderingWidth, this._maxRenderingHeight); - if (state) { - // console.log('Inside of the case when state defined : ', state); - state.persistHeight = state.persistHeight || !!e.north || !!e.south; - state.persistWidth = state.persistWidth || !!e.east || !!e.west; + // Persist the height only when the resizing is stopped + if (e.done) { if (!this._editor.hasModel()) { - // console.log('first if statement'); return; } const uri = this._editor.getModel().uri.toString(); - if (!uri) { - // console.log('second if statement'); + if (!uri || !this._tooltipPosition) { return; } const persistedSize = new dom.Dimension(width, height); - if (!this._tooltipPosition) { - // console.log('third if statement'); - return; - } const wordPosition = this._editor.getModel().getWordAtPosition(this._tooltipPosition); if (!wordPosition) { - // console.log('third if statement'); return; } const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; + // Suppose that the uri does not exist in the persisted widget hover sizes, then create a map if (!this._persistedHoverWidgetSizes.get(uri)) { - const map = new Map([]); - map.set(JSON.stringify([offset, length]), persistedSize); - this._persistedHoverWidgetSizes.set(uri, map); + const persistedWidgetSizesForUri = new Map([]); + persistedWidgetSizesForUri.set(JSON.stringify([offset, length]), persistedSize); + this._persistedHoverWidgetSizes.set(uri, persistedWidgetSizesForUri); } else { - // console.log('saving the new persist size'); - const map = this._persistedHoverWidgetSizes.get(uri)!; - map.set(JSON.stringify([offset, length]), persistedSize); + const persistedWidgetSizesForUri = this._persistedHoverWidgetSizes.get(uri)!; + persistedWidgetSizesForUri.set(JSON.stringify([offset, length]), persistedSize); } - } - if (e.done) { - // console.log('Inside of the case when done'); this._resizing = false; } - // console.log('Before layout overlay widget of the onDidResize listener'); this._editor.layoutOverlayWidget(this); this._editor.render(); })); - state = undefined; - } - - public get size(): dom.Dimension | null { - return this._size; } - public get initialTop(): number { - return this._initialTop; - } - - public get initialHeight(): number { - return this._initialTop; - } - - public set containingWidget(containingWidget: ContentHoverWidget) { - console.log('setting the containing widget'); - this._hoverWidget = containingWidget; + public set hoverWidget(hoverWidget: ContentHoverWidget) { + this._hoverWidget = hoverWidget; } public findPersistedSize(): dom.Dimension | undefined { - if (!this._tooltipPosition) { + if (!this._tooltipPosition || !this._editor.hasModel()) { return; } - const wordPosition = this._editor.getModel()?.getWordAtPosition(this._tooltipPosition); - if (!wordPosition || !this._editor.hasModel()) { + const wordPosition = this._editor.getModel().getWordAtPosition(this._tooltipPosition); + if (!wordPosition) { return; } const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; const uri = this._editor.getModel().uri.toString(); - const textModelMap = this._persistedHoverWidgetSizes.get(uri); - if (!textModelMap) { + const persistedSizesForUri = this._persistedHoverWidgetSizes.get(uri); + if (!persistedSizesForUri) { return; } - console.log('Inside of findPersistedSize'); - console.log('[offset, length] : ', [offset, length]); - return textModelMap.get(JSON.stringify([offset, length])); + return persistedSizesForUri.get(JSON.stringify([offset, length])); } public isResizing(): boolean { @@ -866,13 +807,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } public hide(): void { - console.log('hiding the resizable hover overlay'); - this._resizableElement.enableSashes(false, false, false, false); - this._resizableElement.clearSashHoverState(); - this._resizableElement.maxSize = new dom.Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); - this._visible = false; this._resizing = false; + this._resizableElement.maxSize = new dom.Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); + this._resizableElement.clearSashHoverState(); this._editor.removeOverlayWidget(this); + // TODO: do we need to force render the editor? this._editor.render(); } @@ -889,10 +828,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._resizableElement.domNode; } - public setToooltipPosition(position: IPosition): void { + public setToooltipPosition(tooltipPosition: IPosition): void { console.log('Inside of setTooltipPosition of ResizableHOverOverlay'); console.log('this._position : ', this._tooltipPosition); - this._tooltipPosition = position; + + this._tooltipPosition = tooltipPosition; } public getPosition(): IOverlayWidgetPosition | null { @@ -904,15 +844,18 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('Inside of showAt of ResizableHoverOverlay'); console.log('Before adding overlay widget'); + // Added for the purpose of logging let resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + // -- end of logging - this._visible = true; this._editor.addOverlayWidget(this); + + // -- beginning of logging console.log('After adding overlay widget'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -920,24 +863,26 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + // --- end of logging this._renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + // Enable sashes depending on what side the rendering is on if (renderingAbove) { this._resizableElement.enableSashes(true, true, false, false); } else { this._resizableElement.enableSashes(false, true, true, false); } + this._resizableElement.domNode.style.zIndex = '10'; + this._resizableElement.domNode.style.position = 'fixed'; this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; - this._resizableElement.domNode.style.zIndex = '5'; - this._resizableElement.domNode.tabIndex = 0; - this._resizableElement.domNode.style.position = 'fixed'; - this._resizableElement.domNode.style.height = size.height + 7 + 'px'; - this._resizableElement.domNode.style.width = size.width + 7 + 'px'; - this._resizableElement.layout(size.height, size.width); + // this._resizableElement.domNode.style.height = size.height + 7 + 'px'; + // this._resizableElement.domNode.style.width = size.width + 7 + 'px'; + this._resizableElement.layout(size.height + 7, size.width + 7); + // --- beginning of logging console.log('After style change of overlay widget'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -945,8 +890,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + // --- end of logging this._editor.layoutOverlayWidget(this); + + // --- beginning of logging console.log('After layout overlay widget'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -954,8 +902,12 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + // --- end of logging + // TODO: Do I need to force render this widget? this._editor.render(); + + // --- beginning of logging console.log('After render'); resizableWidgetDomNode = this.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -963,6 +915,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + // --- end of logging } } @@ -985,8 +938,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(this._contextKeyService); private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); - private _renderingType: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - private _appearedWithHorizontalScrollbar: States | undefined = undefined; + private _renderingAbove: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + private _appearedWithHorizontalScrollbar: boolean | undefined = undefined; /** * Returns `null` if the hover is not visible. @@ -1007,13 +960,13 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return this._hoverVisibleKey.get() ?? false; } - public get renderingType(): ContentWidgetPositionPreference { - return this._renderingType; + public get renderingAbove(): ContentWidgetPositionPreference { + return this._renderingAbove; } constructor( private readonly _editor: ICodeEditor, - @IContextKeyService private readonly _contextKeyService: IContextKeyService + @IContextKeyService private readonly _contextKeyService: IContextKeyService, ) { super(); @@ -1036,14 +989,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { })); } - public resize(size: dom.Dimension | null) { + public resize(size: dom.Dimension) { + // Removing the max height and max width here, the max resizing is controller by the resizable overlay this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; console.log('Inside of the resize of the content hover widget'); console.log('size : ', size); - if (!size) { - return; - } + + // Normal resizing but also possible to add space on the bottom when the horizontal scrollbar is visible this._hover.containerDomNode.style.width = size.width - 6 + 'px'; this._hover.containerDomNode.style.height = size.height - 6 + 'px'; this._hover.contentsDomNode.style.width = size.width - 6 + 'px'; @@ -1055,45 +1008,29 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('Before horizontal scorllbar check'); console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); + // The case when the horizontal scrollbar is visible if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { + console.log('In the case when the horizontal scroll bar should be visible'); console.log('appearedWithHorizontalScrollBar : ', this._appearedWithHorizontalScrollbar); - // undefined meaning that not using persisted size - if (this._appearedWithHorizontalScrollbar === States.PERSIST_SIZE_HORIZONTALL_VISIBLE || this._appearedWithHorizontalScrollbar === States.NOT_PERSIST_SIZE_HORIZONTAL_VISIBLE) { - console.log('first if statement'); + + if (this._appearedWithHorizontalScrollbar === true) { this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); - } else if (this._appearedWithHorizontalScrollbar === States.PERSIST_SIZE_HORZONTAL_NOT_VISIBLE || this._appearedWithHorizontalScrollbar === States.NOT_PERSIST_SIZE_HORIZONTAL_NOT_VISIBLE) { - console.log('second if statement'); - this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; - // const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; - // if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { - // this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; - // } - this._hover.scrollbar.scanDomNode(); - this._editor.layoutContentWidget(this); - this._editor.render(); } - console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); } } - public getSize() { - return new dom.Dimension(this._hover.containerDomNode.clientWidth, this._hover.containerDomNode.clientHeight); - } - public findMaxRenderingHeight(rendering: ContentWidgetPositionPreference): number | undefined { console.log('rendering : ', rendering); - if (!this._editor || !this._editor.hasModel()) { + + if (!this._editor || !this._editor.hasModel() || !this._visibleData?.showAtPosition) { return; } const editorBox = dom.getDomNodePagePosition(this._editor.getDomNode()); - if (!this._visibleData?.showAtPosition) { - return; - } - const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData?.showAtPosition); + const mouseBox = this._editor.getScrolledVisiblePosition(this._visibleData.showAtPosition); const bodyBox = dom.getClientArea(document.body); let availableSpace: number; @@ -1103,19 +1040,22 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const mouseBottom = editorBox.top + mouseBox!.top + mouseBox!.height; availableSpace = bodyBox.height - mouseBottom; } + console.log('availableSpace : ', availableSpace); - let actualMaxHeight = 0; + + let divMaxHeight = 0; for (const childHtmlElement of this._hover.contentsDomNode.children) { - actualMaxHeight += childHtmlElement.clientHeight; + divMaxHeight += childHtmlElement.clientHeight; } - console.log('actual max height : ', actualMaxHeight); - // Adding 10 also in order to allow some space for the horizontal scrollbar + + console.log('actual max height : ', divMaxHeight); + let maxRenderingHeight; if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { - // Scrollbar is visible, hence make the max rendering height bigger - maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 16); + // Adding 10 which is the width of the horizontal scrollbar + maxRenderingHeight = Math.min(availableSpace, divMaxHeight + 16); } else { - maxRenderingHeight = Math.min(availableSpace, actualMaxHeight + 6); + maxRenderingHeight = Math.min(availableSpace, divMaxHeight + 6); } console.log('maxRenderingHeight : ', maxRenderingHeight); @@ -1132,12 +1072,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const leftOfEditor = editorBox.left; const glyphMarginWidth = this._editor.getLayoutInfo().glyphMarginWidth; const leftOfContainer = this._hover.containerDomNode.offsetLeft; - return widthOfEditor + leftOfEditor - leftOfContainer - glyphMarginWidth; } public override dispose(): void { - console.log('Inside of dispose of the ContentHoverWidget'); this._editor.removeContentWidget(this); if (this._visibleData) { this._visibleData.disposables.dispose(); @@ -1158,9 +1096,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getPosition(): IContentWidgetPosition | null { - console.log('Inside of getPosition of ContentHoverWidget'); if (!this._visibleData) { - console.log('Early return'); return null; } let preferAbove = this._visibleData.preferAbove; @@ -1172,11 +1108,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // :before content can align left of the text content const affinity = this._visibleData.isBeforeContent ? PositionAffinity.LeftOfInjectedText : undefined; - // Instead use a specfic preference as to the rendering and do not have it dynamically change return { position: this._visibleData.showAtPosition, secondaryPosition: this._visibleData.showAtSecondaryPosition, - preference: ([this._renderingType]), + preference: ([this._renderingAbove]), positionAffinity: affinity }; } @@ -1252,6 +1187,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const containerDomNode = this.getDomNode(); let height; + // When there is a persisted size then do not use a maximum height or width if (persistedSize) { height = persistedSize.height; this._hover.contentsDomNode.style.maxHeight = 'none'; @@ -1268,16 +1204,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('* After render inside of showAt of ContentHoverWidget'); - // TODO: Should be added in the final rendering after the persisted size is used, because that is the one that should be applied - /** Specifying the side on which to render the content hover **/ - // Initial height is not used without persisting + // Deciding where th content should be displayed // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); - // Hard-coded in the hover.css file as 1.5em or 24px const minHeight = 24; // The full height is already passed in as a parameter @@ -1292,7 +1224,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const maxHeightBelow = Math.min(availableSpaceBelow, fullHeight); // The available space above the mouse position is the height of the top of the editor plus the top of the mouse box relative to the editor const availableSpaceAbove = editorBox.top + mouseBox.top - 30; - const maxHeightAbove = Math.min(availableSpaceAbove, fullHeight); // We find the maximum height of the widget possible on the top or on the bottom const maxHeight = Math.min(Math.max(maxHeightAbove, maxHeightBelow), fullHeight); @@ -1304,14 +1235,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = maxHeight; } if (this._editor.getOption(EditorOption.hover).above) { - this._renderingType = height <= maxHeightAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + this._renderingAbove = height <= maxHeightAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; } else { - this._renderingType = height <= maxHeightBelow ? ContentWidgetPositionPreference.BELOW : ContentWidgetPositionPreference.ABOVE; + this._renderingAbove = height <= maxHeightBelow ? ContentWidgetPositionPreference.BELOW : ContentWidgetPositionPreference.ABOVE; } - /** End of specifying the side on which to render **/ - // specify the rendering position here - const contentsDomNode = this.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); @@ -1332,7 +1260,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public hide(): void { - console.log('Inside of hide of the content hover widget'); this._appearedWithHorizontalScrollbar = undefined; if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; @@ -1366,10 +1293,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('persisted size : ', persistedSize); - const renderingType = this._renderingType; - - // Added here but does not seem to have an effect - if (persistedSize && renderingType) { + if (persistedSize) { console.log('When there is a persisted size'); // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one @@ -1377,27 +1301,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { let containerDomNodeWidth = persistedSize.width - 8; let containerDomNodeHeight = persistedSize.height - 8; let contentsDomNodeWidth = persistedSize.width - 8; - let contentsDomNodeHeight = persistedSize.height - 8; // - 18 when scrollbar + let contentsDomNodeHeight = persistedSize.height - 8; // Already takes into account the horizontal scroll bar calculation - const maxRenderingHeight = this.findMaxRenderingHeight(renderingType); + const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); const maxRenderingWidth = this.findMaxRenderingWidth(); + console.log('maxRenderingHeight : ', maxRenderingHeight); console.log('maxRenderingWidth : ', maxRenderingWidth); - - let value; - let valueMinusTen; - if (maxRenderingHeight && maxRenderingWidth) { - - value = Math.min(maxRenderingHeight, persistedSize.height - 8); - valueMinusTen = Math.min(maxRenderingHeight, persistedSize.height - 18); - containerDomNodeWidth = Math.min(maxRenderingWidth, containerDomNodeWidth); containerDomNodeHeight = Math.min(maxRenderingHeight, containerDomNodeHeight); contentsDomNodeWidth = Math.min(maxRenderingWidth, contentsDomNodeWidth); - contentsDomNodeHeight = value; + contentsDomNodeHeight = Math.min(maxRenderingHeight, contentsDomNodeHeight); } console.log('containerDomNodeWidth : ', containerDomNodeWidth); @@ -1416,21 +1333,21 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode.clientWidth ; ', contentsDomNode.clientWidth); console.log('contentsDomNode.scrollWidth : ', contentsDomNode.scrollWidth); - if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth && valueMinusTen) { + if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth && maxRenderingHeight) { + console.log('In the case when the horizontal scroll bar should be visible'); - console.log('valueMinusTen : ', valueMinusTen); - console.log('value : ', value); + if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = States.PERSIST_SIZE_HORIZONTALL_VISIBLE; + this._appearedWithHorizontalScrollbar = true; } // In that case the scrollbar is not visible, make the contents dom node height bigger - contentsDomNode.style.height = valueMinusTen + 'px'; + contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); } else { if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = States.PERSIST_SIZE_HORZONTAL_NOT_VISIBLE; + this._appearedWithHorizontalScrollbar = false; } } @@ -1445,6 +1362,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.render(); } + // --- Added for logging purposes console.log('* After layout content widget'); containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -1458,9 +1376,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // --- End of added for logging purposes this._hover.onContentsChanged(); + // --- Added for logging purposes console.log('* After hover on contents changed'); containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -1474,6 +1394,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // --- End of added for logging purposes const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); @@ -1487,6 +1408,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } + // --- Added for logging purposes console.log('* After changes'); containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -1500,9 +1422,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // --- End of added for logging purposes this._hover.scrollbar.scanDomNode(); + // Suppose it is the first rendering and the size was not previous persisted, then the horizontal scrollbar should be showed if (firstRendering && !persistedSize) { console.log('When this._appearedWithHorizontalScrollbar set : ', this._appearedWithHorizontalScrollbar); console.log('contentsDomNode.clientWidth : ', contentsDomNode.clientWidth); @@ -1510,11 +1434,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth) { if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = States.NOT_PERSIST_SIZE_HORIZONTAL_VISIBLE; + this._appearedWithHorizontalScrollbar = true; } } else { if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = States.NOT_PERSIST_SIZE_HORIZONTAL_NOT_VISIBLE; + this._appearedWithHorizontalScrollbar = false; } } } diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 58246c7bf3c1d..6a82748a59fff 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -29,6 +29,4 @@ background-color: var(--vscode-textCodeBlock-background); } -.monaco-editor .resizable-hover { - z-index: 5; -} + diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 200ec24f72e77..0bb03fae8236e 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -119,12 +119,14 @@ export class ModesHoverController implements IEditorContribution { } if (target.type === MouseTargetType.OVERLAY_WIDGET && target.detail === ResizableHoverOverlay.ID) { + // mouse down on top of the overlap hover widget return; } if (target.type !== MouseTargetType.OVERLAY_WIDGET) { this._hoverClicked = false; } + this._hideWidgets(); } From de68929240a32383b95ad04b1e6f412656208204 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 15:02:25 +0100 Subject: [PATCH 70/95] Reset the css to original values --- src/vs/base/browser/ui/hover/hover.css | 2 +- src/vs/base/browser/ui/sash/sash.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/hover/hover.css b/src/vs/base/browser/ui/hover/hover.css index 57a366d59e840..20c73b8332707 100644 --- a/src/vs/base/browser/ui/hover/hover.css +++ b/src/vs/base/browser/ui/hover/hover.css @@ -8,8 +8,8 @@ position: absolute; overflow: hidden; z-index: 50; - -webkit-user-select: text; user-select: text; + -webkit-user-select: text; box-sizing: initial; animation: fadein 100ms linear; line-height: 1.5em; diff --git a/src/vs/base/browser/ui/sash/sash.css b/src/vs/base/browser/ui/sash/sash.css index aae26390096fb..0026c3c3b1c35 100644 --- a/src/vs/base/browser/ui/sash/sash.css +++ b/src/vs/base/browser/ui/sash/sash.css @@ -108,7 +108,7 @@ width: 100%; height: 100%; transition: background-color 0.1s ease-out; - background: red; + background: transparent; } .monaco-sash.hover:before, From 4ca32f211b59eff4f96347572ed812591c029cf1 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 15:04:36 +0100 Subject: [PATCH 71/95] cleaning the code --- src/vs/editor/contrib/hover/browser/contentHover.ts | 7 ------- src/vs/editor/contrib/hover/browser/hover.ts | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index ff45cacce7f60..d6b14a2567861 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -920,13 +920,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } -enum States { - PERSIST_SIZE_HORIZONTALL_VISIBLE = 1, - PERSIST_SIZE_HORZONTAL_NOT_VISIBLE = 2, - NOT_PERSIST_SIZE_HORIZONTAL_VISIBLE = 3, - NOT_PERSIST_SIZE_HORIZONTAL_NOT_VISIBLE = 4 -} - export class ContentHoverWidget extends Disposable implements IContentWidget { static readonly ID = 'editor.contrib.contentHoverWidget'; diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 0bb03fae8236e..8cc65906e8b5f 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -114,12 +114,12 @@ export class ModesHoverController implements IEditorContribution { } if (target.type === MouseTargetType.OVERLAY_WIDGET && target.detail === MarginHoverWidget.ID) { - // mouse down on top of overlay hover widget + // mouse down on top of overlay margin hover widget return; } if (target.type === MouseTargetType.OVERLAY_WIDGET && target.detail === ResizableHoverOverlay.ID) { - // mouse down on top of the overlap hover widget + // mouse down on top of the overlay hover widget return; } From ea30718614d1543a48bea5d98a92bc99fd1d2991 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 15:36:28 +0100 Subject: [PATCH 72/95] Setting initial resizable element, also need to update the size on resize --- .../contrib/hover/browser/contentHover.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d6b14a2567861..c501f139966b0 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -36,6 +36,7 @@ export class ContentHoverController extends Disposable { private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; + private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _currentResult: HoverResult | null = null; @@ -81,7 +82,11 @@ export class ContentHoverController extends Disposable { // Update the left offset of the resizable element when the widget has been resized const offsetLeft = this._widget.getDomNode().offsetLeft; if (offsetLeft) { - this._resizableOverlay.getDomNode().style.left = offsetLeft - 1 + 'px'; + this._resizableOverlay.getDomNode().style.left = offsetLeft - 2 + 'px'; + } + const offsetTop = this._widget.getDomNode().offsetTop; + if (offsetTop) { + this._resizableOverlay.getDomNode().style.top = offsetTop - 2 + 'px'; } })); } @@ -326,10 +331,14 @@ export class ContentHoverController extends Disposable { // Values found by trial and error // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); - resizableElement.domNode.style.top = offsetTop - 2 + 'px'; - resizableElement.domNode.style.left = offsetLeft - 2 + 'px'; + if (this._renderingAbove) { + resizableElement.domNode.style.top = offsetTop - 2 + 'px'; + } else { + resizableElement.domNode.style.top = offsetTop + 'px'; + } + resizableElement.domNode.style.left = offsetLeft + 'px'; // Set a different width and height to the resizable element - resizableElement.layout(clientHeight + 7, clientWidth + 7); + resizableElement.layout(clientHeight + 4, clientWidth + 4); // Used to be 7 and 6 this._editor.layoutOverlayWidget(this._resizableOverlay); // TODO: Do we need this forced rendering? this._editor.render(); @@ -495,10 +504,12 @@ export class ContentHoverController extends Disposable { } } + this._renderingAbove = renderingAbove; + console.log('rendering above : ', renderingAbove); // Calling show at with the position, size and rendering above option - this._resizableOverlay.showAt(position, size, renderingAbove); + this._resizableOverlay.showAt(position, size, this._renderingAbove); // Added for logging purposes resizableWidgetDomNode = this._resizableOverlay.getDomNode(); From 2ae9ed2ee52e3cbddb7f19756d5ab455388ec665 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 15:50:34 +0100 Subject: [PATCH 73/95] Changed the pixel positions of the resizable element --- .../editor/contrib/hover/browser/contentHover.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index c501f139966b0..1a5aadf8f274e 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -82,10 +82,10 @@ export class ContentHoverController extends Disposable { // Update the left offset of the resizable element when the widget has been resized const offsetLeft = this._widget.getDomNode().offsetLeft; if (offsetLeft) { - this._resizableOverlay.getDomNode().style.left = offsetLeft - 2 + 'px'; + this._resizableOverlay.getDomNode().style.left = offsetLeft + 'px'; } const offsetTop = this._widget.getDomNode().offsetTop; - if (offsetTop) { + if (offsetTop && this._renderingAbove) { this._resizableOverlay.getDomNode().style.top = offsetTop - 2 + 'px'; } })); @@ -1001,10 +1001,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('size : ', size); // Normal resizing but also possible to add space on the bottom when the horizontal scrollbar is visible - this._hover.containerDomNode.style.width = size.width - 6 + 'px'; - this._hover.containerDomNode.style.height = size.height - 6 + 'px'; - this._hover.contentsDomNode.style.width = size.width - 6 + 'px'; - this._hover.contentsDomNode.style.height = size.height - 6 + 'px'; + this._hover.containerDomNode.style.width = size.width - 4 + 'px'; + this._hover.containerDomNode.style.height = size.height - 4 + 'px'; + this._hover.contentsDomNode.style.width = size.width - 4 + 'px'; + this._hover.contentsDomNode.style.height = size.height - 4 + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); @@ -1019,7 +1019,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('appearedWithHorizontalScrollBar : ', this._appearedWithHorizontalScrollbar); if (this._appearedWithHorizontalScrollbar === true) { - this._hover.contentsDomNode.style.height = size.height - 16 + 'px'; + this._hover.contentsDomNode.style.height = size.height - 14 + 'px'; this._hover.scrollbar.scanDomNode(); this._editor.layoutContentWidget(this); this._editor.render(); From e7cc2180f8f233d60c6b4ed42a13fcc2e659da66 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 16:17:00 +0100 Subject: [PATCH 74/95] Added some console logs to better understand the code --- .../contrib/hover/browser/contentHover.ts | 91 +++++++++---------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 1a5aadf8f274e..d93cf9c386886 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -79,7 +79,7 @@ export class ContentHoverController extends Disposable { })); this._register(this._resizableOverlay.onDidResize((e) => { this._widget.resize(e.dimension); - // Update the left offset of the resizable element when the widget has been resized + // Update the left offset of the resizable element because the content widget may change left offset as it is resized const offsetLeft = this._widget.getDomNode().offsetLeft; if (offsetLeft) { this._resizableOverlay.getDomNode().style.left = offsetLeft + 'px'; @@ -277,7 +277,9 @@ export class ContentHoverController extends Disposable { } private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { + console.log('Inside of _renderMessage'); + const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); @@ -397,6 +399,7 @@ export class ContentHoverController extends Disposable { } // Save the position of the tooltip, where the content hover should appear + // It would appear that the first time the render message is called, the tool tip position is undefined, then when called again, it gives the correct answer const tooltipPosition: IPosition = { lineNumber: showAtPosition.lineNumber, column: showAtPosition.column }; // The tooltip position is saved in the resizable overlay this._resizableOverlay.setToooltipPosition(tooltipPosition); @@ -404,18 +407,8 @@ export class ContentHoverController extends Disposable { console.log('persisted size : ', persistedSize); - // TODO: Added here but does not seem to have an effect - /* - if (persistedSize) { - this._widget.getDomNode().style.width = persistedSize.width + 'px'; - this._widget.getDomNode().style.height = persistedSize.height + 'px'; - this._editor.addContentWidget(this._widget); - this._editor.layoutContentWidget(this._widget); - this._editor.render(); - } - */ - // The following is added for logging purposes + // All the values are zero initially when rendered let resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('* Before this._widget.showAt'); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); @@ -424,6 +417,21 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); + const containerDomNode = this._widget.getDomNode(); + console.log('* After layoutContentWidget and render'); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + + const contentsDomNode = this._widget.getContentsDomNode(); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // The persisted size is used in the content hover widget this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, @@ -445,27 +453,19 @@ export class ContentHoverController extends Disposable { this._editor.layoutContentWidget(this._widget); this._editor.render(); - const containerDomNode = this._widget.getDomNode(); - console.log('* After layoutContentWidget and render'); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - resizableWidgetDomNode = this._resizableOverlay.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - const contentsDomNode = this._widget.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); @@ -480,15 +480,6 @@ export class ContentHoverController extends Disposable { console.log('size : ', size); console.log('position : ', position); - // Added for logging purposes - resizableWidgetDomNode = this._resizableOverlay.getDomNode(); - console.log('* Before showAt of resizableWidget'); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // Find if rendered above or below in the container dom node const topLineNumber = anchor.initialMousePosY; console.log('topLineNumber : ', topLineNumber); @@ -514,6 +505,19 @@ export class ContentHoverController extends Disposable { // Added for logging purposes resizableWidgetDomNode = this._resizableOverlay.getDomNode(); console.log('* After showAt of resizableWidget'); + + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); @@ -1173,7 +1177,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return; } - console.log(' * Entered into showAt of ContentHoverWidget'); + console.log('* Entered into showAt of ContentHoverWidget'); this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -1282,6 +1286,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('* Inside of contents changed'); console.log('* Before changes'); + + // On the very first time, the hover is shown, all these values are zero below let containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); @@ -1363,11 +1369,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { contentsDomNode.style.height = 'auto'; this._editor.layoutContentWidget(this); + // TODO: not here initially, so maybe not needed? this._editor.render(); } // --- Added for logging purposes console.log('* After layout content widget'); + // After the initial rendering, we have non zero width, height, left and top offset for the container dom node + containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); @@ -1385,6 +1394,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.onContentsChanged(); // --- Added for logging purposes + // Does not appear to changed the values on first render console.log('* After hover on contents changed'); containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -1411,26 +1421,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.onContentsChanged(); } } - - // --- Added for logging purposes - console.log('* After changes'); - containerDomNode = this.getDomNode(); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - contentsDomNode = this.getContentsDomNode(); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // --- End of added for logging purposes - + // TODO: Should this be here? this._hover.scrollbar.scanDomNode(); // Suppose it is the first rendering and the size was not previous persisted, then the horizontal scrollbar should be showed + // TODO: Added after the initial rendering, probably can be placed into another part if (firstRendering && !persistedSize) { console.log('When this._appearedWithHorizontalScrollbar set : ', this._appearedWithHorizontalScrollbar); console.log('contentsDomNode.clientWidth : ', contentsDomNode.clientWidth); From 12be922af47bb90d6f3ea452cfc68683da0f72ff Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 17:08:59 +0100 Subject: [PATCH 75/95] Cleaning the code --- .../contrib/hover/browser/contentHover.ts | 85 ++++++------------- 1 file changed, 27 insertions(+), 58 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d93cf9c386886..1326debcc7c96 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -311,11 +311,8 @@ export class ContentHoverController extends Disposable { console.log('persistedSize : ', persistedSize); - // Same goes for the boolean first rendering, since it should be defined outside of the function - const firstRendering = true; - // Do some actions when the contents of the hover changes, which appears to happen every single time after the showAt function is called - this._widget.onContentsChanged(firstRendering, persistedSize); + this._widget.onContentsChanged(persistedSize); // TODO: do we need this forced render here? this._editor.render(); @@ -947,7 +944,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { private readonly _hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(this._contextKeyService); private readonly _focusTracker = this._register(dom.trackFocus(this.getDomNode())); private _renderingAbove: ContentWidgetPositionPreference = this._editor.getOption(EditorOption.hover).above ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - private _appearedWithHorizontalScrollbar: boolean | undefined = undefined; /** * Returns `null` if the hover is not visible. @@ -1009,26 +1005,20 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.containerDomNode.style.height = size.height - 4 + 'px'; this._hover.contentsDomNode.style.width = size.width - 4 + 'px'; this._hover.contentsDomNode.style.height = size.height - 4 + 'px'; - this._hover.scrollbar.scanDomNode(); - this._editor.layoutContentWidget(this); - this._editor.render(); - - console.log('Before horizontal scorllbar check'); - console.log('this._hover.contentsDomNode.clientHeight : ', this._hover.contentsDomNode.clientHeight); - - // The case when the horizontal scrollbar is visible - if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { - - console.log('In the case when the horizontal scroll bar should be visible'); - console.log('appearedWithHorizontalScrollBar : ', this._appearedWithHorizontalScrollbar); - if (this._appearedWithHorizontalScrollbar === true) { - this._hover.contentsDomNode.style.height = size.height - 14 + 'px'; - this._hover.scrollbar.scanDomNode(); - this._editor.layoutContentWidget(this); - this._editor.render(); + const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); + const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); + if (hasHorizontalScrollbar) { + const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; + if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { + this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; } + this._hover.contentsDomNode.style.height = size.height - 14 + 'px'; } + + this._hover.scrollbar.scanDomNode(); + this._editor.layoutContentWidget(this); + this._editor.render(); } public findMaxRenderingHeight(rendering: ContentWidgetPositionPreference): number | undefined { @@ -1268,7 +1258,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public hide(): void { - this._appearedWithHorizontalScrollbar = undefined; if (this._visibleData) { const stoleFocus = this._visibleData.stoleFocus; this._setVisibleData(null); @@ -1280,7 +1269,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public onContentsChanged( - firstRendering: boolean = false, persistedSize?: dom.Dimension | undefined ): void { @@ -1343,23 +1331,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode.clientWidth ; ', contentsDomNode.clientWidth); console.log('contentsDomNode.scrollWidth : ', contentsDomNode.scrollWidth); - if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth && maxRenderingHeight) { - - console.log('In the case when the horizontal scroll bar should be visible'); - - if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = true; - } - // In that case the scrollbar is not visible, make the contents dom node height bigger - contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; - this._hover.scrollbar.scanDomNode(); - this._editor.layoutContentWidget(this); - this._editor.render(); - } else { - if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = false; - } - } } else { @@ -1415,32 +1386,30 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (hasHorizontalScrollbar) { // There is just a horizontal scrollbar const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; + let rerender = false; + if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { + console.log('Changing the bottom padding'); this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; + rerender = true; + } + const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); + if (persistedSize && maxRenderingHeight) { + console.log('In the case when the horizontal scroll bar should be visible'); + // In that case the scrollbar is not visible, make the contents dom node height bigger + contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; + rerender = true; + } + if (rerender) { this._editor.layoutContentWidget(this); this._hover.onContentsChanged(); + this._editor.render(); } } + // TODO: Should this be here? this._hover.scrollbar.scanDomNode(); - // Suppose it is the first rendering and the size was not previous persisted, then the horizontal scrollbar should be showed - // TODO: Added after the initial rendering, probably can be placed into another part - if (firstRendering && !persistedSize) { - console.log('When this._appearedWithHorizontalScrollbar set : ', this._appearedWithHorizontalScrollbar); - console.log('contentsDomNode.clientWidth : ', contentsDomNode.clientWidth); - console.log('contentsDomNode.scrollWidth : ', contentsDomNode.scrollWidth); - - if (contentsDomNode.clientWidth < contentsDomNode.scrollWidth) { - if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = true; - } - } else { - if (this._appearedWithHorizontalScrollbar === undefined) { - this._appearedWithHorizontalScrollbar = false; - } - } - } } public clear(): void { From 6b1a25b45e6b7b4a790668ff2a2c99dd53a14232 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 17:29:44 +0100 Subject: [PATCH 76/95] cleaning the code --- .../contrib/hover/browser/contentHover.ts | 85 +++++++------------ 1 file changed, 33 insertions(+), 52 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 1326debcc7c96..dd399ad550657 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -1276,30 +1276,28 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('* Before changes'); // On the very first time, the hover is shown, all these values are zero below - let containerDomNode = this.getDomNode(); + const containerDomNode = this.getDomNode(); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - let contentsDomNode = this.getContentsDomNode(); + + const contentsDomNode = this.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - console.log('persisted size : ', persistedSize); if (persistedSize) { - console.log('When there is a persisted size'); + console.log('* When there is a persisted size'); // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one - let containerDomNodeWidth = persistedSize.width - 8; - let containerDomNodeHeight = persistedSize.height - 8; - let contentsDomNodeWidth = persistedSize.width - 8; - let contentsDomNodeHeight = persistedSize.height - 8; + let widthMinusSashes = persistedSize.width - 8; + let heightMinusSashes = persistedSize.height - 8; // Already takes into account the horizontal scroll bar calculation const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); @@ -1309,28 +1307,17 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('maxRenderingWidth : ', maxRenderingWidth); if (maxRenderingHeight && maxRenderingWidth) { - containerDomNodeWidth = Math.min(maxRenderingWidth, containerDomNodeWidth); - containerDomNodeHeight = Math.min(maxRenderingHeight, containerDomNodeHeight); - contentsDomNodeWidth = Math.min(maxRenderingWidth, contentsDomNodeWidth); - contentsDomNodeHeight = Math.min(maxRenderingHeight, contentsDomNodeHeight); + widthMinusSashes = Math.min(maxRenderingWidth, widthMinusSashes); + heightMinusSashes = Math.min(maxRenderingHeight, heightMinusSashes); } - console.log('containerDomNodeWidth : ', containerDomNodeWidth); - console.log('containerDomNodeHeight : ', containerDomNodeHeight); - console.log('contentsDomNodeWidth : ', contentsDomNodeWidth); - console.log('contentsDomNodeHeight : ', contentsDomNodeHeight); - - containerDomNode.style.width = containerDomNodeWidth + 'px'; - containerDomNode.style.height = containerDomNodeHeight + 'px'; - contentsDomNode.style.width = contentsDomNodeWidth + 'px'; - contentsDomNode.style.height = contentsDomNodeHeight + 'px'; - - this._editor.layoutContentWidget(this); - this._editor.render(); - - console.log('contentsDomNode.clientWidth ; ', contentsDomNode.clientWidth); - console.log('contentsDomNode.scrollWidth : ', contentsDomNode.scrollWidth); + console.log('widthMinusSashes : ', widthMinusSashes); + console.log('heightMinusSashes : ', heightMinusSashes); + containerDomNode.style.width = widthMinusSashes + 'px'; + containerDomNode.style.height = heightMinusSashes + 'px'; + contentsDomNode.style.width = widthMinusSashes + 'px'; + contentsDomNode.style.height = heightMinusSashes + 'px'; } else { @@ -1338,48 +1325,47 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { containerDomNode.style.height = 'auto'; contentsDomNode.style.width = 'auto'; contentsDomNode.style.height = 'auto'; - - this._editor.layoutContentWidget(this); - // TODO: not here initially, so maybe not needed? - this._editor.render(); } - // --- Added for logging purposes - console.log('* After layout content widget'); - // After the initial rendering, we have non zero width, height, left and top offset for the container dom node - - containerDomNode = this.getDomNode(); + console.log('* Before layout content widget'); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - contentsDomNode = this.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // --- End of added for logging purposes - - this._hover.onContentsChanged(); - // --- Added for logging purposes - // Does not appear to changed the values on first render - console.log('* After hover on contents changed'); - containerDomNode = this.getDomNode(); + this._editor.layoutContentWidget(this); + console.log('* After layout content widget'); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - contentsDomNode = this.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // --- End of added for logging purposes + + /* this._editor.render(); + console.log('* After render'); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); */ + + this._hover.onContentsChanged(); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); @@ -1387,7 +1373,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // There is just a horizontal scrollbar const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; let rerender = false; - if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { console.log('Changing the bottom padding'); this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; @@ -1395,7 +1380,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); if (persistedSize && maxRenderingHeight) { - console.log('In the case when the horizontal scroll bar should be visible'); + console.log('There is a persisted size so remove pixels from height'); // In that case the scrollbar is not visible, make the contents dom node height bigger contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; rerender = true; @@ -1406,10 +1391,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._editor.render(); } } - - // TODO: Should this be here? - this._hover.scrollbar.scanDomNode(); - } public clear(): void { From 445f1a67449f5669a45e977597b3b456a0a4283a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 18:21:28 +0100 Subject: [PATCH 77/95] Adding changes --- .../contrib/hover/browser/contentHover.ts | 70 +++++++++++++++---- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index dd399ad550657..d568737bd1e26 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -293,6 +293,9 @@ export class ContentHoverController extends Disposable { setColorPicker: (widget) => colorPicker = widget, onContentsChanged: () => { + const containerDomNode = this._widget.getDomNode(); + const contentsDomNode = this._widget.getContentsDomNode(); + console.log('Inside of onContentsChanged of the context inside of _renderMessage'); console.log('Before onContentsChanged'); @@ -313,12 +316,28 @@ export class ContentHoverController extends Disposable { // Do some actions when the contents of the hover changes, which appears to happen every single time after the showAt function is called this._widget.onContentsChanged(persistedSize); + console.log('After onContentsChanged'); // TODO: do we need this forced render here? - this._editor.render(); + + /* this._editor.render(); console.log('After onContentsChanged'); + console.log('* After render'); + + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + + console.log('this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); - console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableOverlay.getDomNode().offsetTop); + console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableOverlay.getDomNode().offsetTop); */ // After the final rendering of the widget, retrieve its top and left offsets const widgetDomNode = this._widget.getDomNode(); @@ -352,14 +371,13 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode offset top : ', resizableOverlayDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableOverlayDomNode.offsetLeft); - const containerDomNode = this._widget.getDomNode(); + console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); console.log('containerDomNode offset top : ', containerDomNode.offsetTop); console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - const contentsDomNode = this._widget.getContentsDomNode(); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); @@ -448,7 +466,7 @@ export class ContentHoverController extends Disposable { // TODO: Do we actually need to layout the content widget here? this._editor.layoutContentWidget(this._widget); - this._editor.render(); + // this._editor.render(); console.log('* After layoutContentWidget and render'); console.log('containerDomNode : ', containerDomNode); @@ -1197,11 +1215,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; } - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); console.log('* After render inside of showAt of ContentHoverWidget'); // Deciding where th content should be displayed @@ -1239,16 +1252,21 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } const contentsDomNode = this.getContentsDomNode(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); console.log('contentsDomNode : ', contentsDomNode); console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor console.log('* Before the second onContentsChanged of showAt of ContentHoverWidget'); + this.onContentsChanged(); if (visibleData.stoleFocus) { @@ -1273,6 +1291,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { ): void { console.log('* Inside of contents changed'); + console.log('persistedSize : ', persistedSize); + console.log('* Before changes'); // On the very first time, the hover is shown, all these values are zero below @@ -1374,21 +1394,41 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; let rerender = false; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { - console.log('Changing the bottom padding'); this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; rerender = true; } const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); + // Need the following code in the case when using a persisted size, and setting explicitly a size, need to set a smaller height so that the horizontal scrollbar can show if (persistedSize && maxRenderingHeight) { - console.log('There is a persisted size so remove pixels from height'); - // In that case the scrollbar is not visible, make the contents dom node height bigger contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; rerender = true; } if (rerender) { + console.log('rerender : ', rerender); this._editor.layoutContentWidget(this); this._hover.onContentsChanged(); - this._editor.render(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + + /* this._editor.render(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); */ } } } From 1fd67c5df5b5c4fdf2a5a5674676ef20fb4fccc1 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 18:43:31 +0100 Subject: [PATCH 78/95] Removed some useless code --- .../contrib/hover/browser/contentHover.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index d568737bd1e26..3780c66398235 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -339,6 +339,19 @@ export class ContentHoverController extends Disposable { console.log('this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableOverlay.getDomNode().offsetTop); */ + this._editor.render(); + console.log('containerDomNode : ', containerDomNode); + console.log('containerDomNode client width : ', containerDomNode.clientWidth); + console.log('containerDomNode client height : ', containerDomNode.clientHeight); + console.log('containerDomNode offset top : ', containerDomNode.offsetTop); + console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); + + console.log('contentsDomNode : ', contentsDomNode); + console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); + console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); + console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); + console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // After the final rendering of the widget, retrieve its top and left offsets const widgetDomNode = this._widget.getDomNode(); const offsetTop = widgetDomNode.offsetTop; @@ -365,6 +378,8 @@ export class ContentHoverController extends Disposable { // this._widget._hover.scrollbar.scanDomNode(); /** The following are for logging purposes can be removed */ + console.log('After render'); + console.log('resizableWidgetDomNode : ', resizableOverlayDomNode); console.log('resizableWidgetDomNode client width : ', resizableOverlayDomNode.clientWidth); console.log('resizableWidgetDomNode client height : ', resizableOverlayDomNode.clientHeight); @@ -904,8 +919,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.enableSashes(false, true, true, false); } + // this._editor.layoutOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '10'; this._resizableElement.domNode.style.position = 'fixed'; + + /* this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; // this._resizableElement.domNode.style.height = size.height + 7 + 'px'; @@ -921,9 +939,10 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); // --- end of logging + */ this._editor.layoutOverlayWidget(this); - + /* // --- beginning of logging console.log('After layout overlay widget'); resizableWidgetDomNode = this.getDomNode(); @@ -946,6 +965,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); // --- end of logging + */ } } From 791d2e3af4cc30170d40d8cb946ae8d806065cc9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 19:14:32 +0100 Subject: [PATCH 79/95] Removing certain comments --- .../contrib/hover/browser/contentHover.ts | 94 +------------------ 1 file changed, 4 insertions(+), 90 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 3780c66398235..44983b86afe75 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -300,7 +300,6 @@ export class ContentHoverController extends Disposable { console.log('Before onContentsChanged'); // The dom node of the resizable overlay - // TODO: Remove after const resizableOverlayDomNode = this._resizableOverlay.getDomNode(); console.log('resizableWidgetDomNode : ', resizableOverlayDomNode); @@ -311,7 +310,6 @@ export class ContentHoverController extends Disposable { // Finding the resizable overlay should be outside of the on contents changed since it is a function which pertains to the resizable hover const persistedSize = this._resizableOverlay.findPersistedSize(); - console.log('persistedSize : ', persistedSize); // Do some actions when the contents of the hover changes, which appears to happen every single time after the showAt function is called @@ -319,26 +317,6 @@ export class ContentHoverController extends Disposable { console.log('After onContentsChanged'); // TODO: do we need this forced render here? - /* this._editor.render(); - - console.log('After onContentsChanged'); - console.log('* After render'); - - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - - - console.log('this._widget.getDomNode().offsetTop : ', this._widget.getDomNode().offsetTop); - console.log('this._resizableWidget.getDomNode().offsetTop : ', this._resizableOverlay.getDomNode().offsetTop); */ - this._editor.render(); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); @@ -919,53 +897,10 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.enableSashes(false, true, true, false); } - // this._editor.layoutOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '10'; this._resizableElement.domNode.style.position = 'fixed'; - /* - this._resizableElement.domNode.style.top = position.clientTop - 2 + 'px'; - this._resizableElement.domNode.style.left = position.clientLeft - 2 + 'px'; - // this._resizableElement.domNode.style.height = size.height + 7 + 'px'; - // this._resizableElement.domNode.style.width = size.width + 7 + 'px'; - this._resizableElement.layout(size.height + 7, size.width + 7); - - // --- beginning of logging - console.log('After style change of overlay widget'); - resizableWidgetDomNode = this.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // --- end of logging - */ - this._editor.layoutOverlayWidget(this); - /* - // --- beginning of logging - console.log('After layout overlay widget'); - resizableWidgetDomNode = this.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // --- end of logging - - // TODO: Do I need to force render this widget? - this._editor.render(); - - // --- beginning of logging - console.log('After render'); - resizableWidgetDomNode = this.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // --- end of logging - */ } } @@ -1214,6 +1149,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._updateFont(); console.log('* Before the first onContentsChanged of showAt of ContentHoverWidget'); + console.log('persistedSize : ', persistedSize); this.onContentsChanged(); // Simply force a synchronous render on the editor @@ -1306,6 +1242,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } + // TODO: When persisted size is used, use the EXACT persisted size, not smaller by some pixels public onContentsChanged( persistedSize?: dom.Dimension | undefined ): void { @@ -1380,6 +1317,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); this._editor.layoutContentWidget(this); + console.log('* After layout content widget'); console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); @@ -1392,19 +1330,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - /* this._editor.render(); - console.log('* After render'); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); */ - this._hover.onContentsChanged(); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); @@ -1420,6 +1345,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); // Need the following code in the case when using a persisted size, and setting explicitly a size, need to set a smaller height so that the horizontal scrollbar can show if (persistedSize && maxRenderingHeight) { + containerDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 8) + 'px'; contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; rerender = true; } @@ -1437,18 +1363,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - - /* this._editor.render(); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); */ } } } From 6d962ac3c186e3e108762b8709fa949e614e3211 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 19:21:22 +0100 Subject: [PATCH 80/95] Msking the exact persist size be used by chanigng the pixel size used from the persist size --- src/vs/editor/contrib/hover/browser/contentHover.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 44983b86afe75..652e7af275558 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -1273,8 +1273,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('* When there is a persisted size'); // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one - let widthMinusSashes = persistedSize.width - 8; - let heightMinusSashes = persistedSize.height - 8; + let widthMinusSashes = persistedSize.width - 4; + let heightMinusSashes = persistedSize.height - 4; // Already takes into account the horizontal scroll bar calculation const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); @@ -1345,8 +1345,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); // Need the following code in the case when using a persisted size, and setting explicitly a size, need to set a smaller height so that the horizontal scrollbar can show if (persistedSize && maxRenderingHeight) { - containerDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 8) + 'px'; - contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 18) + 'px'; + containerDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 4) + 'px'; + contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 14) + 'px'; rerender = true; } if (rerender) { From f1a546ca5bad617b59902eb3adefc674128ab129 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 20 Mar 2023 20:18:59 +0100 Subject: [PATCH 81/95] fixing an error with the maximum height rendering --- src/vs/editor/browser/editorBrowser.ts | 6 +- .../contrib/hover/browser/contentHover.ts | 84 ++++++++++++------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index fa8ae37f759a1..75751d2db561d 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -112,15 +112,15 @@ export const enum ContentWidgetPositionPreference { /** * Place the content widget exactly at a position */ - EXACT, + EXACT = 0, /** * Place the content widget above a position */ - ABOVE, + ABOVE = 1, /** * Place the content widget below a position */ - BELOW + BELOW = 2 } /** * A position for rendering content widgets. diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 652e7af275558..b9230d0d64cac 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -318,6 +318,7 @@ export class ContentHoverController extends Disposable { // TODO: do we need this forced render here? this._editor.render(); + console.log('containerDomNode : ', containerDomNode); console.log('containerDomNode client width : ', containerDomNode.clientWidth); console.log('containerDomNode client height : ', containerDomNode.clientHeight); @@ -348,6 +349,41 @@ export class ContentHoverController extends Disposable { resizableElement.domNode.style.left = offsetLeft + 'px'; // Set a different width and height to the resizable element resizableElement.layout(clientHeight + 4, clientWidth + 4); // Used to be 7 and 6 + + // Find if rendered above or below in the container dom node + const topLineNumber = anchor.initialMousePosY; + let renderingAbove: boolean = true; + + if (topLineNumber) { + if (offsetTop <= topLineNumber) { + renderingAbove = true; + } else { + renderingAbove = false; + } + } + + this._renderingAbove = renderingAbove; + this._widget.renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + this._resizableOverlay.renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + + // Enable sashes depending on what side the rendering is on + if (renderingAbove) { + this._resizableOverlay.resizableElement().enableSashes(true, true, false, false); + } else { + this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); + } + + const maxRenderingWidth = this._widget.findMaxRenderingWidth(); + const maxRenderingHeight = this._widget.findMaxRenderingHeight(this._widget.renderingAbove); + + if (!maxRenderingWidth || !maxRenderingHeight) { + return; + } + + this._resizableOverlay.resizableElement().maxSize = new dom.Dimension(maxRenderingWidth, maxRenderingHeight); + + console.log('rendering above : ', renderingAbove); + this._editor.layoutOverlayWidget(this._resizableOverlay); // TODO: Do we need this forced rendering? this._editor.render(); @@ -481,34 +517,8 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // Saving the top, left offsets and the client widths and heights - const size = new dom.Dimension(containerDomNode.clientWidth, containerDomNode.clientHeight); - const position = { clientTop: containerDomNode.offsetTop, clientLeft: containerDomNode.offsetLeft }; - - console.log('size : ', size); - console.log('position : ', position); - - // Find if rendered above or below in the container dom node - const topLineNumber = anchor.initialMousePosY; - console.log('topLineNumber : ', topLineNumber); - console.log('position.clientTop : ', position.clientTop); - - let renderingAbove: boolean = true; - - if (topLineNumber) { - if (position.clientTop <= topLineNumber) { - renderingAbove = true; - } else { - renderingAbove = false; - } - } - - this._renderingAbove = renderingAbove; - - console.log('rendering above : ', renderingAbove); - // Calling show at with the position, size and rendering above option - this._resizableOverlay.showAt(position, size, this._renderingAbove); + this._resizableOverlay.showAt(this._renderingAbove); // Added for logging purposes resizableWidgetDomNode = this._resizableOverlay.getDomNode(); @@ -761,6 +771,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // After the content hover widget has been resized, we find the new max rendering height and width // Maybe should be waiting for the content hover widget to resize, it appears not though this._maxRenderingWidth = this._hoverWidget.findMaxRenderingWidth(); + console.log('this._renderingAbove inside of on did resize : ', this._renderingAbove); this._maxRenderingHeight = this._hoverWidget.findMaxRenderingHeight(this._renderingAbove); if (!this._maxRenderingHeight || !this._maxRenderingWidth) { @@ -803,6 +814,14 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget })); } + public get renderingAbove(): ContentWidgetPositionPreference { + return this._renderingAbove; + } + + public set renderingAbove(renderingAbove: ContentWidgetPositionPreference) { + this._renderingAbove = renderingAbove; + } + public set hoverWidget(hoverWidget: ContentHoverWidget) { this._hoverWidget = hoverWidget; } @@ -852,9 +871,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } public setToooltipPosition(tooltipPosition: IPosition): void { - console.log('Inside of setTooltipPosition of ResizableHOverOverlay'); - console.log('this._position : ', this._tooltipPosition); - this._tooltipPosition = tooltipPosition; } @@ -863,7 +879,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return null; } - public showAt(position: any, size: dom.Dimension, renderingAbove: boolean): void { + public showAt(renderingAbove: boolean): void { console.log('Inside of showAt of ResizableHoverOverlay'); console.log('Before adding overlay widget'); @@ -888,6 +904,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); // --- end of logging + /* this._renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; // Enable sashes depending on what side the rendering is on @@ -896,6 +913,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } else { this._resizableElement.enableSashes(false, true, true, false); } + */ this._resizableElement.domNode.style.zIndex = '10'; this._resizableElement.domNode.style.position = 'fixed'; @@ -941,6 +959,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return this._renderingAbove; } + public set renderingAbove(renderingAbove: ContentWidgetPositionPreference) { + this._renderingAbove = renderingAbove; + } + constructor( private readonly _editor: ICodeEditor, @IContextKeyService private readonly _contextKeyService: IContextKeyService, From b30063934b449396d472af53bdc753ca62b88455 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 22 Mar 2023 17:44:20 +0100 Subject: [PATCH 82/95] updating the top and left values at the very end --- src/vs/base/browser/ui/sash/sash.css | 2 +- src/vs/editor/browser/editorBrowser.ts | 6 +++--- src/vs/editor/contrib/hover/browser/contentHover.ts | 8 ++++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/sash/sash.css b/src/vs/base/browser/ui/sash/sash.css index 0026c3c3b1c35..aae26390096fb 100644 --- a/src/vs/base/browser/ui/sash/sash.css +++ b/src/vs/base/browser/ui/sash/sash.css @@ -108,7 +108,7 @@ width: 100%; height: 100%; transition: background-color 0.1s ease-out; - background: transparent; + background: red; } .monaco-sash.hover:before, diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 75751d2db561d..fa8ae37f759a1 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -112,15 +112,15 @@ export const enum ContentWidgetPositionPreference { /** * Place the content widget exactly at a position */ - EXACT = 0, + EXACT, /** * Place the content widget above a position */ - ABOVE = 1, + ABOVE, /** * Place the content widget below a position */ - BELOW = 2 + BELOW } /** * A position for rendering content widgets. diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index b9230d0d64cac..158a2dc280ac3 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -341,6 +341,7 @@ export class ContentHoverController extends Disposable { // Values found by trial and error // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); + console.log('this._renderingAbove : ', this._renderingAbove); if (this._renderingAbove) { resizableElement.domNode.style.top = offsetTop - 2 + 'px'; } else { @@ -373,6 +374,13 @@ export class ContentHoverController extends Disposable { this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); } + if (renderingAbove) { + resizableElement.domNode.style.top = offsetTop - 2 + 'px'; + } else { + resizableElement.domNode.style.top = offsetTop + 'px'; + } + resizableElement.domNode.style.left = offsetLeft + 'px'; + const maxRenderingWidth = this._widget.findMaxRenderingWidth(); const maxRenderingHeight = this._widget.findMaxRenderingHeight(this._widget.renderingAbove); From 02e0e71e2ee526d5cdfd790b5895387664c87d0a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 Mar 2023 11:59:50 +0100 Subject: [PATCH 83/95] cleaning the code --- .../contrib/hover/browser/contentHover.ts | 86 ++++++++++--------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 158a2dc280ac3..a20ea2b45cbb9 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -27,6 +27,10 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IResizeEvent, ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { Emitter, Event } from 'vs/base/common/event'; + +// QUESTIONS TO ASK +// 1. How to make the overlay have higher index, appear on top and have the layer below still detect the on mouse events + const $ = dom.$; export class ContentHoverController extends Disposable { @@ -78,8 +82,9 @@ export class ContentHoverController extends Disposable { } })); this._register(this._resizableOverlay.onDidResize((e) => { + // When the resizable hover overlay changed. resize the widget this._widget.resize(e.dimension); - // Update the left offset of the resizable element because the content widget may change left offset as it is resized + // Update the left and top offset of the resizable element because the content widget may change its left and top offset as it is resized const offsetLeft = this._widget.getDomNode().offsetLeft; if (offsetLeft) { this._resizableOverlay.getDomNode().style.left = offsetLeft + 'px'; @@ -317,6 +322,7 @@ export class ContentHoverController extends Disposable { console.log('After onContentsChanged'); // TODO: do we need this forced render here? + // Needed in order to render correctly the content hover widget this._editor.render(); console.log('containerDomNode : ', containerDomNode); @@ -331,7 +337,7 @@ export class ContentHoverController extends Disposable { console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // After the final rendering of the widget, retrieve its top and left offsets + // After the final rendering of the widget, retrieve its top and left offsets in order to set the size of the resizable element const widgetDomNode = this._widget.getDomNode(); const offsetTop = widgetDomNode.offsetTop; const offsetLeft = widgetDomNode.offsetLeft; @@ -341,13 +347,7 @@ export class ContentHoverController extends Disposable { // Values found by trial and error // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); - console.log('this._renderingAbove : ', this._renderingAbove); - if (this._renderingAbove) { - resizableElement.domNode.style.top = offsetTop - 2 + 'px'; - } else { - resizableElement.domNode.style.top = offsetTop + 'px'; - } - resizableElement.domNode.style.left = offsetLeft + 'px'; + // Set a different width and height to the resizable element resizableElement.layout(clientHeight + 4, clientWidth + 4); // Used to be 7 and 6 @@ -394,7 +394,7 @@ export class ContentHoverController extends Disposable { this._editor.layoutOverlayWidget(this._resizableOverlay); // TODO: Do we need this forced rendering? - this._editor.render(); + // this._editor.render(); // TODO: Do we need this scan dom node? // this._widget._hover.scrollbar.scanDomNode(); @@ -454,7 +454,7 @@ export class ContentHoverController extends Disposable { // It would appear that the first time the render message is called, the tool tip position is undefined, then when called again, it gives the correct answer const tooltipPosition: IPosition = { lineNumber: showAtPosition.lineNumber, column: showAtPosition.column }; // The tooltip position is saved in the resizable overlay - this._resizableOverlay.setToooltipPosition(tooltipPosition); + this._resizableOverlay.tooltipPosition = tooltipPosition; const persistedSize = this._resizableOverlay.findPersistedSize(); console.log('persisted size : ', persistedSize); @@ -502,7 +502,7 @@ export class ContentHoverController extends Disposable { console.log('* Before layoutContentWidget and render'); // TODO: Do we actually need to layout the content widget here? - this._editor.layoutContentWidget(this._widget); + // this._editor.layoutContentWidget(this._widget); // this._editor.render(); console.log('* After layoutContentWidget and render'); @@ -526,7 +526,7 @@ export class ContentHoverController extends Disposable { console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); // Calling show at with the position, size and rendering above option - this._resizableOverlay.showAt(this._renderingAbove); + this._resizableOverlay.showAt(); // Added for logging purposes resizableWidgetDomNode = this._resizableOverlay.getDomNode(); @@ -878,7 +878,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return this._resizableElement.domNode; } - public setToooltipPosition(tooltipPosition: IPosition): void { + public set tooltipPosition(tooltipPosition: IPosition) { this._tooltipPosition = tooltipPosition; } @@ -887,7 +887,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return null; } - public showAt(renderingAbove: boolean): void { + public showAt(): void { console.log('Inside of showAt of ResizableHoverOverlay'); console.log('Before adding overlay widget'); @@ -900,6 +900,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); // -- end of logging + // Adding the overlay widget this._editor.addOverlayWidget(this); // -- beginning of logging @@ -912,20 +913,11 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); // --- end of logging - /* - this._renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - - // Enable sashes depending on what side the rendering is on - if (renderingAbove) { - this._resizableElement.enableSashes(true, true, false, false); - } else { - this._resizableElement.enableSashes(false, true, true, false); - } - */ - + // Setting the appropriate CSS this._resizableElement.domNode.style.zIndex = '10'; this._resizableElement.domNode.style.position = 'fixed'; + // Laying out the overlay widget this._editor.layoutOverlayWidget(this); } @@ -1097,6 +1089,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getPosition(): IContentWidgetPosition | null { + console.log('inside of get position'); if (!this._visibleData) { return null; } @@ -1180,25 +1173,26 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('* Before the first onContentsChanged of showAt of ContentHoverWidget'); console.log('persistedSize : ', persistedSize); - this.onContentsChanged(); - - // Simply force a synchronous render on the editor - // such that the widget does not really render with left = '0px' - this._editor.render(); const containerDomNode = this.getDomNode(); let height; - // When there is a persisted size then do not use a maximum height or width - if (persistedSize) { + // If the persisted size has already been found + if (!persistedSize) { + this._hover.contentsDomNode.style.maxHeight = `${Math.max(this._editor.getLayoutInfo().height / 4, 250)}px`; + this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; + this.onContentsChanged(); + + // Simply force a synchronous render on the editor + // such that the widget does not really render with left = '0px' + this._editor.render(); + height = containerDomNode.clientHeight; + } else { + // When there is a persisted size then do not use a maximum height or width + // Set the height to the persisted size height, set no maximum height and width height = persistedSize.height; this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; - - } else { - height = containerDomNode.clientHeight; - this._hover.contentsDomNode.style.maxHeight = `${Math.max(this._editor.getLayoutInfo().height / 4, 250)}px`; - this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; } console.log('* After render inside of showAt of ContentHoverWidget'); @@ -1231,11 +1225,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (height > maxHeight) { height = maxHeight; } + + // point of the code was to update the maximum height and width and then update the rendering above variable + // Do we need to calculcate it here? Yes becuse needs to be defined before getting the dom node if (this._editor.getOption(EditorOption.hover).above) { this._renderingAbove = height <= maxHeightAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; } else { this._renderingAbove = height <= maxHeightBelow ? ContentWidgetPositionPreference.BELOW : ContentWidgetPositionPreference.ABOVE; } + console.log('this._renderingAbove : ', this._renderingAbove); const contentsDomNode = this.getContentsDomNode(); console.log('containerDomNode : ', containerDomNode); @@ -1253,7 +1251,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // TODO: Doing a second layout of the hover after force rendering the editor console.log('* Before the second onContentsChanged of showAt of ContentHoverWidget'); - this.onContentsChanged(); + if (!persistedSize) { + this.onContentsChanged(); + } if (visibleData.stoleFocus) { this._hover.containerDomNode.focus(); @@ -1277,6 +1277,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { persistedSize?: dom.Dimension | undefined ): void { + // When the contents are changed, update the width and the height variables + console.log('* Inside of contents changed'); console.log('persistedSize : ', persistedSize); @@ -1298,15 +1300,18 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); console.log('persisted size : ', persistedSize); + // Suppose a persisted size is defined if (persistedSize) { console.log('* When there is a persisted size'); // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one + // REmove some pixels since one sash is 4 pixels wide let widthMinusSashes = persistedSize.width - 4; let heightMinusSashes = persistedSize.height - 4; // Already takes into account the horizontal scroll bar calculation + // In this case, need to decide before if rendering should be above or below so move the code before const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); const maxRenderingWidth = this.findMaxRenderingWidth(); @@ -1321,6 +1326,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('widthMinusSashes : ', widthMinusSashes); console.log('heightMinusSashes : ', heightMinusSashes); + // Already setting directly the height and width parameters containerDomNode.style.width = widthMinusSashes + 'px'; containerDomNode.style.height = heightMinusSashes + 'px'; contentsDomNode.style.width = widthMinusSashes + 'px'; @@ -1328,6 +1334,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } else { + // Otherwise the height and width are set to auto containerDomNode.style.width = 'auto'; containerDomNode.style.height = 'auto'; contentsDomNode.style.width = 'auto'; @@ -1346,6 +1353,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); + // layout the content widget this._editor.layoutContentWidget(this); console.log('* After layout content widget'); From 4103ea9b05171adaa7888cef715027d441dcb4b9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 Mar 2023 14:52:26 +0100 Subject: [PATCH 84/95] added code to change the z index and resize the hover overlay when the editor is resized --- .../contrib/hover/browser/contentHover.ts | 161 +++--------------- 1 file changed, 21 insertions(+), 140 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a20ea2b45cbb9..cc8881e6a1e7c 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -94,6 +94,18 @@ export class ContentHoverController extends Disposable { this._resizableOverlay.getDomNode().style.top = offsetTop - 2 + 'px'; } })); + + this._editor.onDidLayoutChange(() => { + const renderingAbove = this._widget.renderingAbove; + const offsetTop = this._widget.getDomNode().offsetTop; + const offsetLeft = this._widget.getDomNode().offsetLeft; + if (renderingAbove === ContentWidgetPositionPreference.ABOVE) { + this._resizableOverlay.getDomNode().style.top = offsetTop - 2 + 'px'; + } else { + this._resizableOverlay.getDomNode().style.top = offsetTop + 'px'; + } + this._resizableOverlay.getDomNode().style.left = offsetLeft + 'px'; + }); } get resizableOverlay() { @@ -451,39 +463,11 @@ export class ContentHoverController extends Disposable { } // Save the position of the tooltip, where the content hover should appear - // It would appear that the first time the render message is called, the tool tip position is undefined, then when called again, it gives the correct answer const tooltipPosition: IPosition = { lineNumber: showAtPosition.lineNumber, column: showAtPosition.column }; // The tooltip position is saved in the resizable overlay this._resizableOverlay.tooltipPosition = tooltipPosition; const persistedSize = this._resizableOverlay.findPersistedSize(); - console.log('persisted size : ', persistedSize); - - // The following is added for logging purposes - // All the values are zero initially when rendered - let resizableWidgetDomNode = this._resizableOverlay.getDomNode(); - console.log('* Before this._widget.showAt'); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - - const containerDomNode = this._widget.getDomNode(); - console.log('* After layoutContentWidget and render'); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - - const contentsDomNode = this._widget.getContentsDomNode(); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // The persisted size is used in the content hover widget this._widget.showAt(fragment, new ContentHoverVisibleData( colorPicker, @@ -498,60 +482,7 @@ export class ContentHoverController extends Disposable { disposables ), persistedSize); - console.log('* After this._widget.showAt'); - console.log('* Before layoutContentWidget and render'); - - // TODO: Do we actually need to layout the content widget here? - // this._editor.layoutContentWidget(this._widget); - // this._editor.render(); - - console.log('* After layoutContentWidget and render'); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - - resizableWidgetDomNode = this._resizableOverlay.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - - // Calling show at with the position, size and rendering above option this._resizableOverlay.showAt(); - - // Added for logging purposes - resizableWidgetDomNode = this._resizableOverlay.getDomNode(); - console.log('* After showAt of resizableWidget'); - - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - - // TODO: do we need to force scan the dom node? - // this._widget._hover.scrollbar.scanDomNode(); } else { disposables.dispose(); } @@ -742,6 +673,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._register(this._resizableElement.onDidResize(e => { console.log('* Inside of onDidResize of ContentHoverWidget'); + console.log('this._resizableElement.maxSize : ', this._resizableElement.maxSize); console.log('e : ', e); let height = e.dimension.height; @@ -888,33 +820,12 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } public showAt(): void { - console.log('Inside of showAt of ResizableHoverOverlay'); - console.log('Before adding overlay widget'); - - // Added for the purpose of logging - let resizableWidgetDomNode = this.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // -- end of logging // Adding the overlay widget this._editor.addOverlayWidget(this); - // -- beginning of logging - console.log('After adding overlay widget'); - resizableWidgetDomNode = this.getDomNode(); - console.log('resizableWidgetDomNode : ', resizableWidgetDomNode); - console.log('resizableWidgetDomNode client width : ', resizableWidgetDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableWidgetDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableWidgetDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableWidgetDomNode.offsetLeft); - // --- end of logging - // Setting the appropriate CSS - this._resizableElement.domNode.style.zIndex = '10'; + this._resizableElement.domNode.style.zIndex = '49'; this._resizableElement.domNode.style.position = 'fixed'; // Laying out the overlay widget @@ -992,8 +903,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Removing the max height and max width here, the max resizing is controller by the resizable overlay this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; - console.log('Inside of the resize of the content hover widget'); - console.log('size : ', size); // Normal resizing but also possible to add space on the bottom when the horizontal scrollbar is visible this._hover.containerDomNode.style.width = size.width - 4 + 'px'; @@ -1017,8 +926,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public findMaxRenderingHeight(rendering: ContentWidgetPositionPreference): number | undefined { - console.log('rendering : ', rendering); + console.log('findMaxRenderingHeight'); + console.log('rendering : ', rendering); if (!this._editor || !this._editor.hasModel() || !this._visibleData?.showAtPosition) { return; } @@ -1034,15 +944,11 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { availableSpace = bodyBox.height - mouseBottom; } - console.log('availableSpace : ', availableSpace); - let divMaxHeight = 0; for (const childHtmlElement of this._hover.contentsDomNode.children) { divMaxHeight += childHtmlElement.clientHeight; } - console.log('actual max height : ', divMaxHeight); - let maxRenderingHeight; if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { // Adding 10 which is the width of the horizontal scrollbar @@ -1056,7 +962,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public findMaxRenderingWidth(): number | undefined { - console.log('Inside of findMaxRenderingWidth'); if (!this._editor || !this._editor.hasModel()) { return; } @@ -1163,7 +1068,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { return; } - console.log('* Entered into showAt of ContentHoverWidget'); this._setVisibleData(visibleData); this._hover.contentsDomNode.textContent = ''; @@ -1171,13 +1075,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.paddingBottom = ''; this._updateFont(); - console.log('* Before the first onContentsChanged of showAt of ContentHoverWidget'); - console.log('persistedSize : ', persistedSize); - const containerDomNode = this.getDomNode(); let height; - // If the persisted size has already been found + // If the persisted size has already been found then set a maximum height and width if (!persistedSize) { this._hover.contentsDomNode.style.maxHeight = `${Math.max(this._editor.getLayoutInfo().height / 4, 250)}px`; this._hover.contentsDomNode.style.maxWidth = `${Math.max(this._editor.getLayoutInfo().width * 0.66, 500)}px`; @@ -1187,18 +1088,14 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // such that the widget does not really render with left = '0px' this._editor.render(); height = containerDomNode.clientHeight; - } else { - // When there is a persisted size then do not use a maximum height or width - // Set the height to the persisted size height, set no maximum height and width + } + // When there is a persisted size then do not use a maximum height or width + else { height = persistedSize.height; this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; } - console.log('* After render inside of showAt of ContentHoverWidget'); - - // Deciding where th content should be displayed - // The dimensions of the document in which we are displaying the hover const bodyBox = dom.getClientArea(document.body); // Hard-coded in the hover.css file as 1.5em or 24px @@ -1226,31 +1123,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { height = maxHeight; } - // point of the code was to update the maximum height and width and then update the rendering above variable - // Do we need to calculcate it here? Yes becuse needs to be defined before getting the dom node + // Determining whether we should render above or not ideally if (this._editor.getOption(EditorOption.hover).above) { this._renderingAbove = height <= maxHeightAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; } else { this._renderingAbove = height <= maxHeightBelow ? ContentWidgetPositionPreference.BELOW : ContentWidgetPositionPreference.ABOVE; } - console.log('this._renderingAbove : ', this._renderingAbove); - - const contentsDomNode = this.getContentsDomNode(); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); // See https://github.com/microsoft/vscode/issues/140339 // TODO: Doing a second layout of the hover after force rendering the editor - console.log('* Before the second onContentsChanged of showAt of ContentHoverWidget'); - if (!persistedSize) { this.onContentsChanged(); } From b9a962962d0c7333b83a83a59a2769cd6abb2c17 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 Mar 2023 15:20:22 +0100 Subject: [PATCH 85/95] cleaning the code --- .../contrib/hover/browser/contentHover.ts | 260 +++--------------- 1 file changed, 39 insertions(+), 221 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index cc8881e6a1e7c..5499c7f5b4a03 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -82,30 +82,33 @@ export class ContentHoverController extends Disposable { } })); this._register(this._resizableOverlay.onDidResize((e) => { - // When the resizable hover overlay changed. resize the widget + // When the resizable hover overlay changes, resize the widget this._widget.resize(e.dimension); // Update the left and top offset of the resizable element because the content widget may change its left and top offset as it is resized - const offsetLeft = this._widget.getDomNode().offsetLeft; - if (offsetLeft) { - this._resizableOverlay.getDomNode().style.left = offsetLeft + 'px'; - } - const offsetTop = this._widget.getDomNode().offsetTop; - if (offsetTop && this._renderingAbove) { - this._resizableOverlay.getDomNode().style.top = offsetTop - 2 + 'px'; - } + this._repositionResizableOverlay(); })); + this._register(this._editor.onDidLayoutChange(() => { + // Sometimes the hover does not disappear on changing the layout of the editor, in that case reposition the resizable hover + this._repositionResizableOverlay(); + })); + } - this._editor.onDidLayoutChange(() => { - const renderingAbove = this._widget.renderingAbove; - const offsetTop = this._widget.getDomNode().offsetTop; - const offsetLeft = this._widget.getDomNode().offsetLeft; - if (renderingAbove === ContentWidgetPositionPreference.ABOVE) { - this._resizableOverlay.getDomNode().style.top = offsetTop - 2 + 'px'; + private _repositionResizableOverlay(): void { + const resizableOverlayDomNode = this._resizableOverlay.getDomNode(); + const widgetDomNode = this._widget.getDomNode(); + const offsetTop = widgetDomNode.offsetTop; + const offsetLeft = widgetDomNode.offsetLeft; + + if (offsetLeft) { + resizableOverlayDomNode.style.left = offsetLeft + 'px'; + } + if (offsetTop) { + if (this._renderingAbove) { + resizableOverlayDomNode.style.top = offsetTop - 2 + 'px'; } else { - this._resizableOverlay.getDomNode().style.top = offsetTop + 'px'; + resizableOverlayDomNode.style.top = offsetTop + 'px'; } - this._resizableOverlay.getDomNode().style.left = offsetLeft + 'px'; - }); + } } get resizableOverlay() { @@ -294,9 +297,6 @@ export class ContentHoverController extends Disposable { } private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { - - console.log('Inside of _renderMessage'); - const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); @@ -310,45 +310,11 @@ export class ContentHoverController extends Disposable { setColorPicker: (widget) => colorPicker = widget, onContentsChanged: () => { - const containerDomNode = this._widget.getDomNode(); - const contentsDomNode = this._widget.getContentsDomNode(); - - console.log('Inside of onContentsChanged of the context inside of _renderMessage'); - console.log('Before onContentsChanged'); - - // The dom node of the resizable overlay - const resizableOverlayDomNode = this._resizableOverlay.getDomNode(); - - console.log('resizableWidgetDomNode : ', resizableOverlayDomNode); - console.log('resizableWidgetDomNode client width : ', resizableOverlayDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableOverlayDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableOverlayDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableOverlayDomNode.offsetLeft); - - // Finding the resizable overlay should be outside of the on contents changed since it is a function which pertains to the resizable hover const persistedSize = this._resizableOverlay.findPersistedSize(); - console.log('persistedSize : ', persistedSize); - - // Do some actions when the contents of the hover changes, which appears to happen every single time after the showAt function is called this._widget.onContentsChanged(persistedSize); - console.log('After onContentsChanged'); - // TODO: do we need this forced render here? - // Needed in order to render correctly the content hover widget this._editor.render(); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - // After the final rendering of the widget, retrieve its top and left offsets in order to set the size of the resizable element const widgetDomNode = this._widget.getDomNode(); const offsetTop = widgetDomNode.offsetTop; @@ -356,12 +322,9 @@ export class ContentHoverController extends Disposable { const clientWidth = widgetDomNode.clientWidth; const clientHeight = widgetDomNode.clientHeight; - // Values found by trial and error // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); - - // Set a different width and height to the resizable element - resizableElement.layout(clientHeight + 4, clientWidth + 4); // Used to be 7 and 6 + resizableElement.layout(clientHeight + 4, clientWidth + 4); // Find if rendered above or below in the container dom node const topLineNumber = anchor.initialMousePosY; @@ -382,15 +345,12 @@ export class ContentHoverController extends Disposable { // Enable sashes depending on what side the rendering is on if (renderingAbove) { this._resizableOverlay.resizableElement().enableSashes(true, true, false, false); - } else { - this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); - } - - if (renderingAbove) { resizableElement.domNode.style.top = offsetTop - 2 + 'px'; } else { + this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); resizableElement.domNode.style.top = offsetTop + 'px'; } + resizableElement.domNode.style.left = offsetLeft + 'px'; const maxRenderingWidth = this._widget.findMaxRenderingWidth(); @@ -401,38 +361,7 @@ export class ContentHoverController extends Disposable { } this._resizableOverlay.resizableElement().maxSize = new dom.Dimension(maxRenderingWidth, maxRenderingHeight); - - console.log('rendering above : ', renderingAbove); - this._editor.layoutOverlayWidget(this._resizableOverlay); - // TODO: Do we need this forced rendering? - // this._editor.render(); - - // TODO: Do we need this scan dom node? - // this._widget._hover.scrollbar.scanDomNode(); - - /** The following are for logging purposes can be removed */ - console.log('After render'); - - console.log('resizableWidgetDomNode : ', resizableOverlayDomNode); - console.log('resizableWidgetDomNode client width : ', resizableOverlayDomNode.clientWidth); - console.log('resizableWidgetDomNode client height : ', resizableOverlayDomNode.clientHeight); - console.log('resizableWidgetDomNode offset top : ', resizableOverlayDomNode.offsetTop); - console.log('resizableWidgetDomNode offset left : ', resizableOverlayDomNode.offsetLeft); - - - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - console.log('At the end of onContentsChanged of _renderMessages'); }, hide: () => this.hide() }; @@ -631,9 +560,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget constructor(private readonly _editor: ICodeEditor) { super(); - // The minimum size is fixed this._resizableElement.minSize = new dom.Dimension(10, 24); - this._editor.onDidChangeModelContent((e) => { const uri = this._editor.getModel()?.uri.toString(); if (!uri || !this._persistedHoverWidgetSizes.has(uri)) { @@ -663,39 +590,25 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget }); this._register(this._resizableElement.onDidWillResize(() => { - console.log('this._persistedHoverWidgetSizes ; ', this._persistedHoverWidgetSizes); - this._resizing = true; - // Saving the intiial height and the initial top of the resizable element this._initialHeight = this._resizableElement.domNode.clientHeight; this._initialTop = this._resizableElement.domNode.offsetTop; })); this._register(this._resizableElement.onDidResize(e => { - console.log('* Inside of onDidResize of ContentHoverWidget'); - console.log('this._resizableElement.maxSize : ', this._resizableElement.maxSize); - console.log('e : ', e); - let height = e.dimension.height; let width = e.dimension.width; const maxWidth = this._resizableElement.maxSize.width; const maxHeight = this._resizableElement.maxSize.height; - // Cap the width to the maximum width and the height to the current maximum height + width = Math.min(maxWidth, width); height = Math.min(maxHeight, height); if (!this._maxRenderingHeight) { return; } - // Setting the new width and height parameters this._size = new dom.Dimension(width, height); - // Updating the height and width parameters of the resizable element this._resizableElement.layout(height, width); - console.log('this._initialTop : ', this._initialTop); - console.log('this._intiialHeight : ', this._initialHeight); - console.log('height : ', height); - console.log('this._initialTop - (height - this._initialHeight) : ', this._initialTop - (height - this._initialHeight)); - // Update the top parameters only when we decided to render above if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; @@ -704,15 +617,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // Fire the current dimension this._onDidResize.fire({ dimension: this._size, done: false }); - if (!this._hoverWidget) { - return; - } - - // After the content hover widget has been resized, we find the new max rendering height and width - // Maybe should be waiting for the content hover widget to resize, it appears not though - this._maxRenderingWidth = this._hoverWidget.findMaxRenderingWidth(); - console.log('this._renderingAbove inside of on did resize : ', this._renderingAbove); - this._maxRenderingHeight = this._hoverWidget.findMaxRenderingHeight(this._renderingAbove); + this._maxRenderingWidth = this._hoverWidget!.findMaxRenderingWidth(); + this._maxRenderingHeight = this._hoverWidget!.findMaxRenderingHeight(this._renderingAbove); if (!this._maxRenderingHeight || !this._maxRenderingWidth) { return; @@ -720,7 +626,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.maxSize = new dom.Dimension(this._maxRenderingWidth, this._maxRenderingHeight); - // Persist the height only when the resizing is stopped + // Persist the height only when the resizing has stopped if (e.done) { if (!this._editor.hasModel()) { return; @@ -748,9 +654,9 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } this._resizing = false; } + this._editor.layoutOverlayWidget(this); this._editor.render(); - })); } @@ -823,12 +729,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // Adding the overlay widget this._editor.addOverlayWidget(this); - - // Setting the appropriate CSS this._resizableElement.domNode.style.zIndex = '49'; this._resizableElement.domNode.style.position = 'fixed'; - - // Laying out the overlay widget this._editor.layoutOverlayWidget(this); } @@ -904,7 +806,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; - // Normal resizing but also possible to add space on the bottom when the horizontal scrollbar is visible this._hover.containerDomNode.style.width = size.width - 4 + 'px'; this._hover.containerDomNode.style.height = size.height - 4 + 'px'; this._hover.contentsDomNode.style.width = size.width - 4 + 'px'; @@ -913,6 +814,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); if (hasHorizontalScrollbar) { + // When there is a horizontal scroll-bar use a different height const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; @@ -927,8 +829,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { public findMaxRenderingHeight(rendering: ContentWidgetPositionPreference): number | undefined { - console.log('findMaxRenderingHeight'); - console.log('rendering : ', rendering); if (!this._editor || !this._editor.hasModel() || !this._visibleData?.showAtPosition) { return; } @@ -957,7 +857,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { maxRenderingHeight = Math.min(availableSpace, divMaxHeight + 6); } - console.log('maxRenderingHeight : ', maxRenderingHeight); return maxRenderingHeight; } @@ -994,7 +893,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public getPosition(): IContentWidgetPosition | null { - console.log('inside of get position'); if (!this._visibleData) { return null; } @@ -1091,9 +989,9 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } // When there is a persisted size then do not use a maximum height or width else { - height = persistedSize.height; this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; + height = persistedSize.height; } // The dimensions of the document in which we are displaying the hover @@ -1153,65 +1051,22 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } } - // TODO: When persisted size is used, use the EXACT persisted size, not smaller by some pixels - public onContentsChanged( - persistedSize?: dom.Dimension | undefined - ): void { + public onContentsChanged(persistedSize?: dom.Dimension | undefined): void { - // When the contents are changed, update the width and the height variables - - console.log('* Inside of contents changed'); - console.log('persistedSize : ', persistedSize); - - console.log('* Before changes'); - - // On the very first time, the hover is shown, all these values are zero below const containerDomNode = this.getDomNode(); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - const contentsDomNode = this.getContentsDomNode(); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - console.log('persisted size : ', persistedSize); // Suppose a persisted size is defined if (persistedSize) { - console.log('* When there is a persisted size'); - // If persisted size does not fit in the editor for example on editor resize, use a different size, smaller one - - // REmove some pixels since one sash is 4 pixels wide - let widthMinusSashes = persistedSize.width - 4; - let heightMinusSashes = persistedSize.height - 4; - - // Already takes into account the horizontal scroll bar calculation - // In this case, need to decide before if rendering should be above or below so move the code before - const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); - const maxRenderingWidth = this.findMaxRenderingWidth(); - - console.log('maxRenderingHeight : ', maxRenderingHeight); - console.log('maxRenderingWidth : ', maxRenderingWidth); - - if (maxRenderingHeight && maxRenderingWidth) { - widthMinusSashes = Math.min(maxRenderingWidth, widthMinusSashes); - heightMinusSashes = Math.min(maxRenderingHeight, heightMinusSashes); - } - - console.log('widthMinusSashes : ', widthMinusSashes); - console.log('heightMinusSashes : ', heightMinusSashes); + const widthMinusSash = Math.min(this.findMaxRenderingWidth() ?? Infinity, persistedSize.width - 4); + const heightMinusSash = Math.min(this.findMaxRenderingHeight(this._renderingAbove) ?? Infinity, persistedSize.height - 4); // Already setting directly the height and width parameters - containerDomNode.style.width = widthMinusSashes + 'px'; - containerDomNode.style.height = heightMinusSashes + 'px'; - contentsDomNode.style.width = widthMinusSashes + 'px'; - contentsDomNode.style.height = heightMinusSashes + 'px'; + containerDomNode.style.width = widthMinusSash + 'px'; + containerDomNode.style.height = heightMinusSash + 'px'; + contentsDomNode.style.width = widthMinusSash + 'px'; + contentsDomNode.style.height = heightMinusSash + 'px'; } else { @@ -1222,33 +1077,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { contentsDomNode.style.height = 'auto'; } - console.log('* Before layout content widget'); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - - // layout the content widget this._editor.layoutContentWidget(this); - - console.log('* After layout content widget'); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); - this._hover.onContentsChanged(); const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); @@ -1262,26 +1091,15 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { rerender = true; } const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); - // Need the following code in the case when using a persisted size, and setting explicitly a size, need to set a smaller height so that the horizontal scrollbar can show + // Need the following code since we are using an exact height when using the persisted size. If not used the horizontal scrollbar would just not be visible. if (persistedSize && maxRenderingHeight) { containerDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 4) + 'px'; contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 14) + 'px'; rerender = true; } if (rerender) { - console.log('rerender : ', rerender); this._editor.layoutContentWidget(this); this._hover.onContentsChanged(); - console.log('containerDomNode : ', containerDomNode); - console.log('containerDomNode client width : ', containerDomNode.clientWidth); - console.log('containerDomNode client height : ', containerDomNode.clientHeight); - console.log('containerDomNode offset top : ', containerDomNode.offsetTop); - console.log('containerDomNode offset left : ', containerDomNode.offsetLeft); - console.log('contentsDomNode : ', contentsDomNode); - console.log('contentsDomNode client width : ', contentsDomNode.clientWidth); - console.log('contentsDomNode client height : ', contentsDomNode.clientHeight); - console.log('contentsDomNode offset top : ', contentsDomNode.offsetTop); - console.log('contentsDomNode offset left : ', contentsDomNode.offsetLeft); } } } From 0714b6ce7a031b0b149b077f5c3775a1d161d304 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 Mar 2023 16:51:44 +0100 Subject: [PATCH 86/95] cleaning the code --- src/vs/editor/contrib/hover/browser/contentHover.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 73de3654ac47c..a0931c0451de5 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -719,8 +719,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget this._resizableElement.maxSize = new dom.Dimension(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); this._resizableElement.clearSashHoverState(); this._editor.removeOverlayWidget(this); - // TODO: do we need to force render the editor? - this._editor.render(); } public resizableElement(): ResizableHTMLElement { @@ -732,7 +730,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } public getDomNode(): HTMLElement { - console.log('Inside of getDomNode() of ResizableHoverOverlay'); return this._resizableElement.domNode; } @@ -741,17 +738,14 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } public getPosition(): IOverlayWidgetPosition | null { - console.log('Inside of getPosition of ResizableHoverOverlay'); return null; } public showAt(): void { - // Adding the overlay widget this._editor.addOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '49'; this._resizableElement.domNode.style.position = 'fixed'; - this._editor.layoutOverlayWidget(this); } } From 933a6c6570d121b83dfd27ca1401fe88ea0d1963 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 Mar 2023 17:10:38 +0100 Subject: [PATCH 87/95] extracting the hard-coded values --- .../contrib/hover/browser/contentHover.ts | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a0931c0451de5..40049c5539156 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -32,6 +32,8 @@ import { Emitter, Event } from 'vs/base/common/event'; // 1. How to make the overlay have higher index, appear on top and have the layer below still detect the on mouse events const $ = dom.$; +const SCROLLBAR_WIDTH = 10; +const SASH_WIDTH = 4; export class ContentHoverController extends Disposable { @@ -324,7 +326,7 @@ export class ContentHoverController extends Disposable { // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); - resizableElement.layout(clientHeight + 4, clientWidth + 4); + resizableElement.layout(clientHeight + SASH_WIDTH, clientWidth + SASH_WIDTH); // Find if rendered above or below in the container dom node const topLineNumber = anchor.initialMousePosY; @@ -821,10 +823,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; - this._hover.containerDomNode.style.width = size.width - 4 + 'px'; - this._hover.containerDomNode.style.height = size.height - 4 + 'px'; - this._hover.contentsDomNode.style.width = size.width - 4 + 'px'; - this._hover.contentsDomNode.style.height = size.height - 4 + 'px'; + this._hover.containerDomNode.style.width = size.width - SASH_WIDTH + 'px'; + this._hover.containerDomNode.style.height = size.height - SASH_WIDTH + 'px'; + this._hover.contentsDomNode.style.width = size.width - SASH_WIDTH + 'px'; + this._hover.contentsDomNode.style.height = size.height - SASH_WIDTH + 'px'; const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); @@ -834,7 +836,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; } - this._hover.contentsDomNode.style.height = size.height - 14 + 'px'; + this._hover.contentsDomNode.style.height = size.height - SASH_WIDTH - SCROLLBAR_WIDTH + 'px'; } this._hover.scrollbar.scanDomNode(); @@ -859,20 +861,17 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { availableSpace = bodyBox.height - mouseBottom; } - let divMaxHeight = 0; + let divMaxHeight = SASH_WIDTH; for (const childHtmlElement of this._hover.contentsDomNode.children) { divMaxHeight += childHtmlElement.clientHeight; } - let maxRenderingHeight; if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { // Adding 10 which is the width of the horizontal scrollbar - maxRenderingHeight = Math.min(availableSpace, divMaxHeight + 16); - } else { - maxRenderingHeight = Math.min(availableSpace, divMaxHeight + 6); + divMaxHeight += SCROLLBAR_WIDTH; } - return maxRenderingHeight; + return Math.min(availableSpace, divMaxHeight); } public findMaxRenderingWidth(): number | undefined { @@ -1074,8 +1073,8 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { // Suppose a persisted size is defined if (persistedSize) { - const widthMinusSash = Math.min(this.findMaxRenderingWidth() ?? Infinity, persistedSize.width - 4); - const heightMinusSash = Math.min(this.findMaxRenderingHeight(this._renderingAbove) ?? Infinity, persistedSize.height - 4); + const widthMinusSash = Math.min(this.findMaxRenderingWidth() ?? Infinity, persistedSize.width - SASH_WIDTH); + const heightMinusSash = Math.min(this.findMaxRenderingHeight(this._renderingAbove) ?? Infinity, persistedSize.height - SASH_WIDTH); // Already setting directly the height and width parameters containerDomNode.style.width = widthMinusSash + 'px'; @@ -1100,19 +1099,19 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (hasHorizontalScrollbar) { // There is just a horizontal scrollbar const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; - let rerender = false; + let reposition = false; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; - rerender = true; + reposition = true; } const maxRenderingHeight = this.findMaxRenderingHeight(this._renderingAbove); // Need the following code since we are using an exact height when using the persisted size. If not used the horizontal scrollbar would just not be visible. if (persistedSize && maxRenderingHeight) { - containerDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 4) + 'px'; - contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - 14) + 'px'; - rerender = true; + containerDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - SASH_WIDTH) + 'px'; + contentsDomNode.style.height = Math.min(maxRenderingHeight, persistedSize.height - SASH_WIDTH - SCROLLBAR_WIDTH) + 'px'; + reposition = true; } - if (rerender) { + if (reposition) { this._editor.layoutContentWidget(this); this._hover.onContentsChanged(); } From df2efc4bcdda96d7b2dba70e4a9b4a473ffcc3af Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 Mar 2023 17:55:44 +0100 Subject: [PATCH 88/95] work in progress which aims to add an underlay below the hover content for better rendering --- src/vs/base/browser/ui/sash/sash.css | 2 +- .../contrib/hover/browser/contentHover.ts | 58 ++++++++++++++++++- src/vs/editor/contrib/hover/browser/hover.css | 3 + 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/sash/sash.css b/src/vs/base/browser/ui/sash/sash.css index 40bd11fe8017d..fdcbc26609e07 100644 --- a/src/vs/base/browser/ui/sash/sash.css +++ b/src/vs/base/browser/ui/sash/sash.css @@ -107,7 +107,7 @@ position: absolute; width: 100%; height: 100%; - background: red; + background: transparent; } .monaco-workbench:not(.reduce-motion) .monaco-sash:before { diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 40049c5539156..a84e03f895a53 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -40,6 +40,7 @@ export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; private readonly _resizableOverlay = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + private readonly _widgetUnderlay = this._register(this._instantiationService.createInstance(ContentHoverWidgetUnderlay, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; @@ -86,6 +87,7 @@ export class ContentHoverController extends Disposable { this._register(this._resizableOverlay.onDidResize((e) => { // When the resizable hover overlay changes, resize the widget this._widget.resize(e.dimension); + this._widgetUnderlay.resize(e.dimension); // Update the left and top offset of the resizable element because the content widget may change its left and top offset as it is resized this._repositionResizableOverlay(); })); @@ -240,6 +242,7 @@ export class ContentHoverController extends Disposable { this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { this._widget.hide(); + this._widgetUnderlay.hide(); this._resizableOverlay.hide(); } } @@ -314,16 +317,23 @@ export class ContentHoverController extends Disposable { const persistedSize = this._resizableOverlay.findPersistedSize(); this._widget.onContentsChanged(persistedSize); + // Needed in order to render correctly the content hover widget this._editor.render(); // After the final rendering of the widget, retrieve its top and left offsets in order to set the size of the resizable element const widgetDomNode = this._widget.getDomNode(); + const widgetUnderlayDomNode = this._widgetUnderlay.getDomNode(); const offsetTop = widgetDomNode.offsetTop; const offsetLeft = widgetDomNode.offsetLeft; const clientWidth = widgetDomNode.clientWidth; const clientHeight = widgetDomNode.clientHeight; + widgetUnderlayDomNode.style.width = clientWidth + 6 + 'px'; + widgetUnderlayDomNode.style.height = clientHeight + 6 + 'px'; + widgetUnderlayDomNode.style.left = offsetLeft + 'px'; + widgetUnderlayDomNode.style.top = offsetTop - 4 + 'px'; + // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); resizableElement.layout(clientHeight + SASH_WIDTH, clientWidth + SASH_WIDTH); @@ -412,8 +422,8 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosY, disposables ), persistedSize); - - this._resizableOverlay.showAt(); + this._widgetUnderlay.show(); + this._resizableOverlay.show(); } else { disposables.dispose(); } @@ -743,7 +753,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget return null; } - public showAt(): void { + public show(): void { // Adding the overlay widget this._editor.addOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '49'; @@ -752,6 +762,48 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } +class ContentHoverWidgetUnderlay extends Disposable implements IOverlayWidget { + + static readonly ID = 'editor.contrib.contentHoverWidgetUnderlay'; + public readonly containerDomNode: HTMLElement; + + constructor( + private readonly _editor: ICodeEditor, + ) { + super(); + this.containerDomNode = document.createElement('div'); + this.containerDomNode.className = 'monaco-hover-underlay'; + } + + public getId(): string { + return ContentHoverWidgetUnderlay.ID; + } + + public getDomNode(): HTMLElement { + return this.containerDomNode; + } + + public getPosition(): IOverlayWidgetPosition | null { + return null; + } + + public resize(size: dom.Dimension) { + this.containerDomNode.style.width = size.width + 'px'; + this.containerDomNode.style.height = size.height + 'px'; + this._editor.layoutOverlayWidget(this); + } + + public show(): void { + this._editor.addOverlayWidget(this); + this.containerDomNode.style.zIndex = '49'; + this.containerDomNode.style.position = 'fixed'; + } + + public hide(): void { + this._editor.removeOverlayWidget(this); + } +} + export class ContentHoverWidget extends Disposable implements IContentWidget { static readonly ID = 'editor.contrib.contentHoverWidget'; diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 6a82748a59fff..4dc3a24eccd5c 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -29,4 +29,7 @@ background-color: var(--vscode-textCodeBlock-background); } +.monaco-editor .monaco-hover-underlay { + background-color: var(--vscode-editorHoverWidget-background); +} From c18dc25670aa92a6f749001beefc033dc5218be6 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 Mar 2023 09:55:17 +0100 Subject: [PATCH 89/95] reverting to previous work without underlay --- src/vs/editor/contrib/hover/browser/contentHover.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a84e03f895a53..b80c1635f5048 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -422,7 +422,7 @@ export class ContentHoverController extends Disposable { anchor.initialMousePosY, disposables ), persistedSize); - this._widgetUnderlay.show(); + this._resizableOverlay.show(); } else { disposables.dispose(); From dbe2baa374b6c99538e989f64f57dfe77f6f4f18 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 Mar 2023 09:59:00 +0100 Subject: [PATCH 90/95] cleaning the code --- src/vs/editor/contrib/hover/browser/contentHover.ts | 7 +++---- src/vs/editor/contrib/hover/browser/hover.css | 3 --- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index b80c1635f5048..a9d5d09f03872 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -27,7 +27,6 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IResizeEvent, ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { Emitter, Event } from 'vs/base/common/event'; - // QUESTIONS TO ASK // 1. How to make the overlay have higher index, appear on top and have the layer below still detect the on mouse events @@ -329,10 +328,10 @@ export class ContentHoverController extends Disposable { const clientWidth = widgetDomNode.clientWidth; const clientHeight = widgetDomNode.clientHeight; - widgetUnderlayDomNode.style.width = clientWidth + 6 + 'px'; - widgetUnderlayDomNode.style.height = clientHeight + 6 + 'px'; + widgetUnderlayDomNode.style.width = clientWidth + SASH_WIDTH + 2 + 'px'; + widgetUnderlayDomNode.style.height = clientHeight + SASH_WIDTH + 2 + 'px'; widgetUnderlayDomNode.style.left = offsetLeft + 'px'; - widgetUnderlayDomNode.style.top = offsetTop - 4 + 'px'; + widgetUnderlayDomNode.style.top = offsetTop - SASH_WIDTH + 'px'; // Update the left and top offset to match the widget dom node const resizableElement = this._resizableOverlay.resizableElement(); diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 4dc3a24eccd5c..6a82748a59fff 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -29,7 +29,4 @@ background-color: var(--vscode-textCodeBlock-background); } -.monaco-editor .monaco-hover-underlay { - background-color: var(--vscode-editorHoverWidget-background); -} From 842ec612fa2bbbf90ec9e1943bcd42c390a4465a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 Mar 2023 11:36:53 +0100 Subject: [PATCH 91/95] changing the size of the sashes so looks better --- src/vs/base/browser/ui/resizable/resizable.ts | 16 ++++ src/vs/base/browser/ui/sash/sash.ts | 79 ++++++++++--------- .../contrib/hover/browser/contentHover.ts | 77 +++++------------- 3 files changed, 77 insertions(+), 95 deletions(-) diff --git a/src/vs/base/browser/ui/resizable/resizable.ts b/src/vs/base/browser/ui/resizable/resizable.ts index 95dfb06b8d007..9bd5f4ff54219 100644 --- a/src/vs/base/browser/ui/resizable/resizable.ts +++ b/src/vs/base/browser/ui/resizable/resizable.ts @@ -187,4 +187,20 @@ export class ResizableHTMLElement { get preferredSize() { return this._preferredSize; } + + get northSash() { + return this._northSash; + } + + get eastSash() { + return this._eastSash; + } + + get westSash() { + return this._westSash; + } + + get southSash() { + return this._southSash; + } } diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index b20c218516917..f0e87bb1f558b 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -247,7 +247,7 @@ const PointerEventsDisabledCssClass = 'pointer-events-disabled'; */ export class Sash extends Disposable { - private el: HTMLElement; + private _el: HTMLElement; private layoutProvider: ISashLayoutProvider; private orientation: Orientation; private size: number; @@ -269,6 +269,7 @@ export class Sash extends Disposable { private readonly orthogonalEndDragHandleDisposables = this._register(new DisposableStore()); private _orthogonalEndDragHandle: HTMLElement | undefined; + get el(): HTMLElement { return this._el; } get state(): SashState { return this._state; } get orthogonalStartSash(): Sash | undefined { return this._orthogonalStartSash; } get orthogonalEndSash(): Sash | undefined { return this._orthogonalEndSash; } @@ -282,9 +283,9 @@ export class Sash extends Disposable { return; } - this.el.classList.toggle('disabled', state === SashState.Disabled); - this.el.classList.toggle('minimum', state === SashState.AtMinimum); - this.el.classList.toggle('maximum', state === SashState.AtMaximum); + this._el.classList.toggle('disabled', state === SashState.Disabled); + this._el.classList.toggle('minimum', state === SashState.AtMinimum); + this._el.classList.toggle('maximum', state === SashState.AtMaximum); this._state = state; this.onDidEnablementChange.fire(state); @@ -336,7 +337,7 @@ export class Sash extends Disposable { this.orthogonalStartDragHandleDisposables.clear(); if (state !== SashState.Disabled) { - this._orthogonalStartDragHandle = append(this.el, $('.orthogonal-drag-handle.start')); + this._orthogonalStartDragHandle = append(this._el, $('.orthogonal-drag-handle.start')); this.orthogonalStartDragHandleDisposables.add(toDisposable(() => this._orthogonalStartDragHandle!.remove())); this.orthogonalStartDragHandleDisposables.add(new DomEmitter(this._orthogonalStartDragHandle, 'mouseenter')).event (() => Sash.onMouseEnter(sash), undefined, this.orthogonalStartDragHandleDisposables); @@ -370,7 +371,7 @@ export class Sash extends Disposable { this.orthogonalEndDragHandleDisposables.clear(); if (state !== SashState.Disabled) { - this._orthogonalEndDragHandle = append(this.el, $('.orthogonal-drag-handle.end')); + this._orthogonalEndDragHandle = append(this._el, $('.orthogonal-drag-handle.end')); this.orthogonalEndDragHandleDisposables.add(toDisposable(() => this._orthogonalEndDragHandle!.remove())); this.orthogonalEndDragHandleDisposables.add(new DomEmitter(this._orthogonalEndDragHandle, 'mouseenter')).event (() => Sash.onMouseEnter(sash), undefined, this.orthogonalEndDragHandleDisposables); @@ -406,30 +407,30 @@ export class Sash extends Disposable { constructor(container: HTMLElement, layoutProvider: ISashLayoutProvider, options: ISashOptions) { super(); - this.el = append(container, $('.monaco-sash')); + this._el = append(container, $('.monaco-sash')); if (options.orthogonalEdge) { - this.el.classList.add(`orthogonal-edge-${options.orthogonalEdge}`); + this._el.classList.add(`orthogonal-edge-${options.orthogonalEdge}`); } if (isMacintosh) { - this.el.classList.add('mac'); + this._el.classList.add('mac'); } - const onMouseDown = this._register(new DomEmitter(this.el, 'mousedown')).event; + const onMouseDown = this._register(new DomEmitter(this._el, 'mousedown')).event; this._register(onMouseDown(e => this.onPointerStart(e, new MouseEventFactory()), this)); - const onMouseDoubleClick = this._register(new DomEmitter(this.el, 'dblclick')).event; + const onMouseDoubleClick = this._register(new DomEmitter(this._el, 'dblclick')).event; this._register(onMouseDoubleClick(this.onPointerDoublePress, this)); - const onMouseEnter = this._register(new DomEmitter(this.el, 'mouseenter')).event; + const onMouseEnter = this._register(new DomEmitter(this._el, 'mouseenter')).event; this._register(onMouseEnter(() => Sash.onMouseEnter(this))); - const onMouseLeave = this._register(new DomEmitter(this.el, 'mouseleave')).event; + const onMouseLeave = this._register(new DomEmitter(this._el, 'mouseleave')).event; this._register(onMouseLeave(() => Sash.onMouseLeave(this))); - this._register(Gesture.addTarget(this.el)); + this._register(Gesture.addTarget(this._el)); - const onTouchStart = this._register(new DomEmitter(this.el, EventType.Start)).event; - this._register(onTouchStart(e => this.onPointerStart(e, new GestureEventFactory(this.el)), this)); - const onTap = this._register(new DomEmitter(this.el, EventType.Tap)).event; + const onTouchStart = this._register(new DomEmitter(this._el, EventType.Start)).event; + this._register(onTouchStart(e => this.onPointerStart(e, new GestureEventFactory(this._el)), this)); + const onTap = this._register(new DomEmitter(this._el, EventType.Tap)).event; let doubleTapTimeout: any = undefined; this._register(onTap(event => { @@ -448,9 +449,9 @@ export class Sash extends Disposable { this.size = options.size; if (options.orientation === Orientation.VERTICAL) { - this.el.style.width = `${this.size}px`; + this._el.style.width = `${this.size - 2}px`; } else { - this.el.style.height = `${this.size}px`; + this._el.style.height = `${this.size - 2}px`; } } else { this.size = globalSize; @@ -470,14 +471,14 @@ export class Sash extends Disposable { this.orientation = options.orientation || Orientation.VERTICAL; if (this.orientation === Orientation.HORIZONTAL) { - this.el.classList.add('horizontal'); - this.el.classList.remove('vertical'); + this._el.classList.add('horizontal'); + this._el.classList.remove('vertical'); } else { - this.el.classList.remove('horizontal'); - this.el.classList.add('vertical'); + this._el.classList.remove('horizontal'); + this._el.classList.add('vertical'); } - this.el.classList.toggle('debug', DEBUG); + this._el.classList.toggle('debug', DEBUG); this.layout(); } @@ -516,11 +517,11 @@ export class Sash extends Disposable { const altKey = event.altKey; const startEvent: ISashEvent = { startX, currentX: startX, startY, currentY: startY, altKey }; - this.el.classList.add('active'); + this._el.classList.add('active'); this._onDidStart.fire(startEvent); // fix https://github.com/microsoft/vscode/issues/21675 - const style = createStyleSheet(this.el); + const style = createStyleSheet(this._el); const updateStyle = () => { let cursor = ''; @@ -565,9 +566,9 @@ export class Sash extends Disposable { const onPointerUp = (e: PointerEvent) => { EventHelper.stop(e, false); - this.el.removeChild(style); + this._el.removeChild(style); - this.el.classList.remove('active'); + this._el.classList.remove('active'); this._onDidEnd.fire(); disposables.dispose(); @@ -597,11 +598,11 @@ export class Sash extends Disposable { } private static onMouseEnter(sash: Sash, fromLinkedSash: boolean = false): void { - if (sash.el.classList.contains('active')) { + if (sash._el.classList.contains('active')) { sash.hoverDelayer.cancel(); - sash.el.classList.add('hover'); + sash._el.classList.add('hover'); } else { - sash.hoverDelayer.trigger(() => sash.el.classList.add('hover'), sash.hoverDelay).then(undefined, () => { }); + sash.hoverDelayer.trigger(() => sash._el.classList.add('hover'), sash.hoverDelay).then(undefined, () => { }); } if (!fromLinkedSash && sash.linkedSash) { @@ -611,7 +612,7 @@ export class Sash extends Disposable { private static onMouseLeave(sash: Sash, fromLinkedSash: boolean = false): void { sash.hoverDelayer.cancel(); - sash.el.classList.remove('hover'); + sash._el.classList.remove('hover'); if (!fromLinkedSash && sash.linkedSash) { Sash.onMouseLeave(sash.linkedSash, true); @@ -634,25 +635,25 @@ export class Sash extends Disposable { layout(): void { if (this.orientation === Orientation.VERTICAL) { const verticalProvider = (this.layoutProvider); - this.el.style.left = verticalProvider.getVerticalSashLeft(this) - (this.size / 2) + 'px'; + this._el.style.left = verticalProvider.getVerticalSashLeft(this) - (this.size / 2) + 'px'; if (verticalProvider.getVerticalSashTop) { - this.el.style.top = verticalProvider.getVerticalSashTop(this) + 'px'; + this._el.style.top = verticalProvider.getVerticalSashTop(this) + 'px'; } if (verticalProvider.getVerticalSashHeight) { - this.el.style.height = verticalProvider.getVerticalSashHeight(this) + 'px'; + this._el.style.height = verticalProvider.getVerticalSashHeight(this) + 'px'; } } else { const horizontalProvider = (this.layoutProvider); - this.el.style.top = horizontalProvider.getHorizontalSashTop(this) - (this.size / 2) + 'px'; + this._el.style.top = horizontalProvider.getHorizontalSashTop(this) - (this.size / 2) + 'px'; if (horizontalProvider.getHorizontalSashLeft) { - this.el.style.left = horizontalProvider.getHorizontalSashLeft(this) + 'px'; + this._el.style.left = horizontalProvider.getHorizontalSashLeft(this) + 'px'; } if (horizontalProvider.getHorizontalSashWidth) { - this.el.style.width = horizontalProvider.getHorizontalSashWidth(this) + 'px'; + this._el.style.width = horizontalProvider.getHorizontalSashWidth(this) + 'px'; } } } @@ -673,6 +674,6 @@ export class Sash extends Disposable { override dispose(): void { super.dispose(); - this.el.remove(); + this._el.remove(); } } diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a9d5d09f03872..938877cfd9725 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -39,7 +39,6 @@ export class ContentHoverController extends Disposable { private readonly _participants: IEditorHoverParticipant[]; private readonly _resizableOverlay = this._register(this._instantiationService.createInstance(ResizableHoverOverlay, this._editor)); private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); - private readonly _widgetUnderlay = this._register(this._instantiationService.createInstance(ContentHoverWidgetUnderlay, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; @@ -86,7 +85,6 @@ export class ContentHoverController extends Disposable { this._register(this._resizableOverlay.onDidResize((e) => { // When the resizable hover overlay changes, resize the widget this._widget.resize(e.dimension); - this._widgetUnderlay.resize(e.dimension); // Update the left and top offset of the resizable element because the content widget may change its left and top offset as it is resized this._repositionResizableOverlay(); })); @@ -241,7 +239,6 @@ export class ContentHoverController extends Disposable { this._renderMessages(this._currentResult.anchor, this._currentResult.messages); } else { this._widget.hide(); - this._widgetUnderlay.hide(); this._resizableOverlay.hide(); } } @@ -322,20 +319,11 @@ export class ContentHoverController extends Disposable { // After the final rendering of the widget, retrieve its top and left offsets in order to set the size of the resizable element const widgetDomNode = this._widget.getDomNode(); - const widgetUnderlayDomNode = this._widgetUnderlay.getDomNode(); const offsetTop = widgetDomNode.offsetTop; const offsetLeft = widgetDomNode.offsetLeft; const clientWidth = widgetDomNode.clientWidth; const clientHeight = widgetDomNode.clientHeight; - widgetUnderlayDomNode.style.width = clientWidth + SASH_WIDTH + 2 + 'px'; - widgetUnderlayDomNode.style.height = clientHeight + SASH_WIDTH + 2 + 'px'; - widgetUnderlayDomNode.style.left = offsetLeft + 'px'; - widgetUnderlayDomNode.style.top = offsetTop - SASH_WIDTH + 'px'; - - // Update the left and top offset to match the widget dom node - const resizableElement = this._resizableOverlay.resizableElement(); - resizableElement.layout(clientHeight + SASH_WIDTH, clientWidth + SASH_WIDTH); // Find if rendered above or below in the container dom node const topLineNumber = anchor.initialMousePosY; @@ -350,16 +338,28 @@ export class ContentHoverController extends Disposable { } this._renderingAbove = renderingAbove; - this._widget.renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; - this._resizableOverlay.renderingAbove = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + const contentWidgetPositionPreference = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; + this._widget.renderingAbove = contentWidgetPositionPreference; + this._resizableOverlay.renderingAbove = contentWidgetPositionPreference; + + const resizableElement = this._resizableOverlay.resizableElement(); + resizableElement.layout(clientHeight + SASH_WIDTH, clientWidth + SASH_WIDTH); // Enable sashes depending on what side the rendering is on if (renderingAbove) { + console.log('rendering above'); this._resizableOverlay.resizableElement().enableSashes(true, true, false, false); + resizableElement.northSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; + resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; resizableElement.domNode.style.top = offsetTop - 2 + 'px'; + resizableElement.eastSash.el.style.top = 2 + 'px'; } else { + console.log('rendering below'); this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); + resizableElement.southSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; + resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; resizableElement.domNode.style.top = offsetTop + 'px'; + resizableElement.eastSash.el.style.top = 0 + 'px'; } resizableElement.domNode.style.left = offsetLeft + 'px'; @@ -643,6 +643,13 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // Update the top parameters only when we decided to render above if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; + this._resizableElement.northSash.el.style.width = width - 2 + 'px'; + this._resizableElement.eastSash.el.style.height = height - 2 + 'px'; + this._resizableElement.eastSash.el.style.top = 2 + 'px'; + } else { + this._resizableElement.southSash.el.style.width = width - 2 + 'px'; + this._resizableElement.eastSash.el.style.height = height - 2 + 'px'; + this._resizableElement.eastSash.el.style.top = 0 + 'px'; } // Fire the current dimension @@ -761,48 +768,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } -class ContentHoverWidgetUnderlay extends Disposable implements IOverlayWidget { - - static readonly ID = 'editor.contrib.contentHoverWidgetUnderlay'; - public readonly containerDomNode: HTMLElement; - - constructor( - private readonly _editor: ICodeEditor, - ) { - super(); - this.containerDomNode = document.createElement('div'); - this.containerDomNode.className = 'monaco-hover-underlay'; - } - - public getId(): string { - return ContentHoverWidgetUnderlay.ID; - } - - public getDomNode(): HTMLElement { - return this.containerDomNode; - } - - public getPosition(): IOverlayWidgetPosition | null { - return null; - } - - public resize(size: dom.Dimension) { - this.containerDomNode.style.width = size.width + 'px'; - this.containerDomNode.style.height = size.height + 'px'; - this._editor.layoutOverlayWidget(this); - } - - public show(): void { - this._editor.addOverlayWidget(this); - this.containerDomNode.style.zIndex = '49'; - this.containerDomNode.style.position = 'fixed'; - } - - public hide(): void { - this._editor.removeOverlayWidget(this); - } -} - export class ContentHoverWidget extends Disposable implements IContentWidget { static readonly ID = 'editor.contrib.contentHoverWidget'; From e1e47d78e9fbaecb736272ae84f8751823938c95 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 Mar 2023 11:37:25 +0100 Subject: [PATCH 92/95] removing the console logs --- src/vs/editor/contrib/hover/browser/contentHover.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 938877cfd9725..fb4803f367634 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -347,14 +347,12 @@ export class ContentHoverController extends Disposable { // Enable sashes depending on what side the rendering is on if (renderingAbove) { - console.log('rendering above'); this._resizableOverlay.resizableElement().enableSashes(true, true, false, false); resizableElement.northSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; resizableElement.domNode.style.top = offsetTop - 2 + 'px'; resizableElement.eastSash.el.style.top = 2 + 'px'; } else { - console.log('rendering below'); this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); resizableElement.southSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; From b110bc5388a587da3aa4d2f5a44d3244f63612f4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 Mar 2023 11:44:32 +0100 Subject: [PATCH 93/95] cleaning the code --- .../contrib/hover/browser/contentHover.ts | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index fb4803f367634..4a8b1c63b2f67 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -27,9 +27,6 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IResizeEvent, ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { Emitter, Event } from 'vs/base/common/event'; -// QUESTIONS TO ASK -// 1. How to make the overlay have higher index, appear on top and have the layer below still detect the on mouse events - const $ = dom.$; const SCROLLBAR_WIDTH = 10; const SASH_WIDTH = 4; @@ -324,7 +321,6 @@ export class ContentHoverController extends Disposable { const clientWidth = widgetDomNode.clientWidth; const clientHeight = widgetDomNode.clientHeight; - // Find if rendered above or below in the container dom node const topLineNumber = anchor.initialMousePosY; let renderingAbove: boolean = true; @@ -349,17 +345,16 @@ export class ContentHoverController extends Disposable { if (renderingAbove) { this._resizableOverlay.resizableElement().enableSashes(true, true, false, false); resizableElement.northSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; - resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; resizableElement.domNode.style.top = offsetTop - 2 + 'px'; resizableElement.eastSash.el.style.top = 2 + 'px'; } else { this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); resizableElement.southSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; - resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; resizableElement.domNode.style.top = offsetTop + 'px'; resizableElement.eastSash.el.style.top = 0 + 'px'; } + resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; resizableElement.domNode.style.left = offsetLeft + 'px'; const maxRenderingWidth = this._widget.findMaxRenderingWidth(); @@ -617,7 +612,6 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } this._persistedHoverWidgetSizes.set(uri, updatedPersistedSizesForUri); }); - this._register(this._resizableElement.onDidWillResize(() => { this._resizing = true; this._initialHeight = this._resizableElement.domNode.clientHeight; @@ -642,13 +636,12 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; this._resizableElement.northSash.el.style.width = width - 2 + 'px'; - this._resizableElement.eastSash.el.style.height = height - 2 + 'px'; this._resizableElement.eastSash.el.style.top = 2 + 'px'; } else { this._resizableElement.southSash.el.style.width = width - 2 + 'px'; - this._resizableElement.eastSash.el.style.height = height - 2 + 'px'; this._resizableElement.eastSash.el.style.top = 0 + 'px'; } + this._resizableElement.eastSash.el.style.height = height - 2 + 'px'; // Fire the current dimension this._onDidResize.fire({ dimension: this._size, done: false }); @@ -758,12 +751,10 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } public show(): void { - // Adding the overlay widget this._editor.addOverlayWidget(this); this._resizableElement.domNode.style.zIndex = '49'; this._resizableElement.domNode.style.position = 'fixed'; } - } export class ContentHoverWidget extends Disposable implements IContentWidget { @@ -833,7 +824,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } public resize(size: dom.Dimension) { - // Removing the max height and max width here, the max resizing is controller by the resizable overlay + // Removing the max height and max width here - the max size is controlled by the resizable overlay this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; @@ -845,7 +836,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); if (hasHorizontalScrollbar) { - // When there is a horizontal scroll-bar use a different height + // When there is a horizontal scroll-bar use a different height to make the scroll-bar visible const extraBottomPadding = `${this._hover.scrollbar.options.horizontalScrollbarSize}px`; if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; @@ -881,7 +872,6 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { } if (this._hover.contentsDomNode.clientWidth < this._hover.contentsDomNode.scrollWidth) { - // Adding 10 which is the width of the horizontal scrollbar divMaxHeight += SCROLLBAR_WIDTH; } From 5f9bec064d09f50979b134317f17a9232a54be88 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 27 Mar 2023 13:13:07 +0200 Subject: [PATCH 94/95] Cleaning the CSS widths and heights --- .../contrib/hover/browser/contentHover.ts | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 4a8b1c63b2f67..113382b73041d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -30,6 +30,7 @@ import { Emitter, Event } from 'vs/base/common/event'; const $ = dom.$; const SCROLLBAR_WIDTH = 10; const SASH_WIDTH = 4; +const TOTAL_BORDER_WIDTH = 2; export class ContentHoverController extends Disposable { @@ -38,7 +39,6 @@ export class ContentHoverController extends Disposable { private readonly _widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); private readonly _computer: ContentHoverComputer; private readonly _hoverOperation: HoverOperation; - private _renderingAbove: boolean = this._editor.getOption(EditorOption.hover).above; private _currentResult: HoverResult | null = null; @@ -98,14 +98,10 @@ export class ContentHoverController extends Disposable { const offsetLeft = widgetDomNode.offsetLeft; if (offsetLeft) { - resizableOverlayDomNode.style.left = offsetLeft + 'px'; + resizableOverlayDomNode.style.left = offsetLeft - SASH_WIDTH + TOTAL_BORDER_WIDTH + 'px'; } if (offsetTop) { - if (this._renderingAbove) { - resizableOverlayDomNode.style.top = offsetTop - 2 + 'px'; - } else { - resizableOverlayDomNode.style.top = offsetTop + 'px'; - } + resizableOverlayDomNode.style.top = offsetTop - SASH_WIDTH + TOTAL_BORDER_WIDTH + 'px'; } } @@ -333,29 +329,37 @@ export class ContentHoverController extends Disposable { } } - this._renderingAbove = renderingAbove; const contentWidgetPositionPreference = renderingAbove ? ContentWidgetPositionPreference.ABOVE : ContentWidgetPositionPreference.BELOW; this._widget.renderingAbove = contentWidgetPositionPreference; this._resizableOverlay.renderingAbove = contentWidgetPositionPreference; const resizableElement = this._resizableOverlay.resizableElement(); - resizableElement.layout(clientHeight + SASH_WIDTH, clientWidth + SASH_WIDTH); + resizableElement.layout(clientHeight + 2 * SASH_WIDTH - TOTAL_BORDER_WIDTH, clientWidth + 2 * SASH_WIDTH - TOTAL_BORDER_WIDTH); + + resizableElement.domNode.style.top = offsetTop - TOTAL_BORDER_WIDTH + 'px'; + resizableElement.domNode.style.left = offsetLeft - SASH_WIDTH + TOTAL_BORDER_WIDTH + 'px'; + const horizontalSashLeft = TOTAL_BORDER_WIDTH + 'px'; + resizableElement.northSash.el.style.left = horizontalSashLeft; + resizableElement.southSash.el.style.left = horizontalSashLeft; + const horizontalSashWidth = clientWidth + TOTAL_BORDER_WIDTH + 'px'; + resizableElement.northSash.el.style.width = horizontalSashWidth; + resizableElement.southSash.el.style.width = horizontalSashWidth; + const verticalSashHeight = clientHeight + TOTAL_BORDER_WIDTH + 'px'; + resizableElement.eastSash.el.style.height = verticalSashHeight; + resizableElement.westSash.el.style.height = verticalSashHeight; - // Enable sashes depending on what side the rendering is on if (renderingAbove) { this._resizableOverlay.resizableElement().enableSashes(true, true, false, false); - resizableElement.northSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; - resizableElement.domNode.style.top = offsetTop - 2 + 'px'; - resizableElement.eastSash.el.style.top = 2 + 'px'; + const verticalSashTop = SASH_WIDTH - TOTAL_BORDER_WIDTH + 'px'; + resizableElement.eastSash.el.style.top = verticalSashTop; + resizableElement.westSash.el.style.top = verticalSashTop; } else { this._resizableOverlay.resizableElement().enableSashes(false, true, true, false); - resizableElement.southSash.el.style.width = clientWidth + SASH_WIDTH - 2 + 'px'; - resizableElement.domNode.style.top = offsetTop + 'px'; - resizableElement.eastSash.el.style.top = 0 + 'px'; + const verticalSashTop = TOTAL_BORDER_WIDTH + 'px'; + resizableElement.eastSash.el.style.top = verticalSashTop; + resizableElement.westSash.el.style.top = verticalSashTop; } - resizableElement.eastSash.el.style.height = clientHeight + SASH_WIDTH - 2 + 'px'; - resizableElement.domNode.style.left = offsetLeft + 'px'; const maxRenderingWidth = this._widget.findMaxRenderingWidth(); const maxRenderingHeight = this._widget.findMaxRenderingHeight(this._widget.renderingAbove); @@ -635,13 +639,14 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // Update the top parameters only when we decided to render above if (this._renderingAbove === ContentWidgetPositionPreference.ABOVE) { this._resizableElement.domNode.style.top = this._initialTop - (height - this._initialHeight) + 'px'; - this._resizableElement.northSash.el.style.width = width - 2 + 'px'; - this._resizableElement.eastSash.el.style.top = 2 + 'px'; - } else { - this._resizableElement.southSash.el.style.width = width - 2 + 'px'; - this._resizableElement.eastSash.el.style.top = 0 + 'px'; } - this._resizableElement.eastSash.el.style.height = height - 2 + 'px'; + const horizontalSashWidth = width - 2 * SASH_WIDTH + 2 * TOTAL_BORDER_WIDTH + 'px'; + this._resizableElement.northSash.el.style.width = horizontalSashWidth; + this._resizableElement.southSash.el.style.width = horizontalSashWidth; + const verticalSashWidth = height - 2 * SASH_WIDTH + 2 * TOTAL_BORDER_WIDTH + 'px'; + this._resizableElement.eastSash.el.style.height = verticalSashWidth; + this._resizableElement.westSash.el.style.height = verticalSashWidth; + this._resizableElement.eastSash.el.style.top = TOTAL_BORDER_WIDTH + 'px'; // Fire the current dimension this._onDidResize.fire({ dimension: this._size, done: false }); @@ -828,10 +833,12 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { this._hover.contentsDomNode.style.maxHeight = 'none'; this._hover.contentsDomNode.style.maxWidth = 'none'; - this._hover.containerDomNode.style.width = size.width - SASH_WIDTH + 'px'; - this._hover.containerDomNode.style.height = size.height - SASH_WIDTH + 'px'; - this._hover.contentsDomNode.style.width = size.width - SASH_WIDTH + 'px'; - this._hover.contentsDomNode.style.height = size.height - SASH_WIDTH + 'px'; + const width = size.width - 2 * SASH_WIDTH + TOTAL_BORDER_WIDTH + 'px'; + this._hover.containerDomNode.style.width = width; + this._hover.contentsDomNode.style.width = width; + const height = size.height - 2 * SASH_WIDTH + TOTAL_BORDER_WIDTH + 'px'; + this._hover.containerDomNode.style.height = height; + this._hover.contentsDomNode.style.height = height; const scrollDimensions = this._hover.scrollbar.getScrollDimensions(); const hasHorizontalScrollbar = (scrollDimensions.scrollWidth > scrollDimensions.width); @@ -841,7 +848,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget { if (this._hover.contentsDomNode.style.paddingBottom !== extraBottomPadding) { this._hover.contentsDomNode.style.paddingBottom = extraBottomPadding; } - this._hover.contentsDomNode.style.height = size.height - SASH_WIDTH - SCROLLBAR_WIDTH + 'px'; + this._hover.contentsDomNode.style.height = size.height - 2 * SASH_WIDTH + TOTAL_BORDER_WIDTH - SCROLLBAR_WIDTH + 'px'; } this._hover.scrollbar.scanDomNode(); From 558793c5d42158d60fa1a107cfbc00df2985af7c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 31 Mar 2023 11:53:55 +0200 Subject: [PATCH 95/95] using a resource map instead of a generic map --- src/vs/editor/contrib/hover/browser/contentHover.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index 113382b73041d..b88e2d04c60ff 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -26,6 +26,7 @@ import { AsyncIterableObject } from 'vs/base/common/async'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { IResizeEvent, ResizableHTMLElement } from 'vs/base/browser/ui/resizable/resizable'; import { Emitter, Event } from 'vs/base/common/event'; +import { ResourceMap } from 'vs/base/common/map'; const $ = dom.$; const SCROLLBAR_WIDTH = 10; @@ -562,7 +563,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget // Creating a new resizable HTML element private readonly _resizableElement: ResizableHTMLElement = this._register(new ResizableHTMLElement()); // Map which maps from a text model URI, to a map from the stringified version of [offset, left] to the dom dimension - private readonly _persistedHoverWidgetSizes = new Map>(); + private readonly _persistedHoverWidgetSizes = new ResourceMap>(); // Boolean which is indicating whether we are currently resizing or not private _resizing: boolean = false; // The current size of the resizable element @@ -589,8 +590,8 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget constructor(private readonly _editor: ICodeEditor) { super(); this._resizableElement.minSize = new dom.Dimension(10, 24); - this._editor.onDidChangeModelContent((e) => { - const uri = this._editor.getModel()?.uri.toString(); + this._register(this._editor.onDidChangeModelContent((e) => { + const uri = this._editor.getModel()?.uri; if (!uri || !this._persistedHoverWidgetSizes.has(uri)) { return; } @@ -615,7 +616,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } } this._persistedHoverWidgetSizes.set(uri, updatedPersistedSizesForUri); - }); + })); this._register(this._resizableElement.onDidWillResize(() => { this._resizing = true; this._initialHeight = this._resizableElement.domNode.clientHeight; @@ -665,7 +666,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget if (!this._editor.hasModel()) { return; } - const uri = this._editor.getModel().uri.toString(); + const uri = this._editor.getModel().uri; if (!uri || !this._tooltipPosition) { return; } @@ -716,7 +717,7 @@ export class ResizableHoverOverlay extends Disposable implements IOverlayWidget } const offset = this._editor.getModel().getOffsetAt({ lineNumber: this._tooltipPosition.lineNumber, column: wordPosition.startColumn }); const length = wordPosition.word.length; - const uri = this._editor.getModel().uri.toString(); + const uri = this._editor.getModel().uri; const persistedSizesForUri = this._persistedHoverWidgetSizes.get(uri); if (!persistedSizesForUri) { return;