Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 34 additions & 39 deletions src/vs/editor/contrib/find/browser/findWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,12 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
}

this._register(this._codeEditor.onDidChangeModel(() => {
if (!this._isVisible) {
// Model swaps destroy zones; clear the stale id and reattach while Find is open (#316054).
this._viewZoneId = undefined;
if (!this._isVisible || !this._codeEditor.hasModel()) {
return;
}
this._viewZoneId = undefined;
this._showViewZone(false);
}));


Expand Down Expand Up @@ -583,6 +585,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
this._domNode.classList.add('visible');
this._domNode.setAttribute('aria-hidden', 'false');
this._updateFindInputAriaLabel();
this._showViewZone(false); // refresh zone height after the widget is laid out (#316054)
}, 0));

// validate query again as it's being dismissed when we hide the find widget.
Expand All @@ -592,33 +595,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL

this._codeEditor.layoutOverlayWidget(this);

let adjustEditorScrollTop = true;
if (this._codeEditor.getOption(EditorOption.find).seedSearchStringFromSelection && selection) {
const domNode = this._codeEditor.getDomNode();
if (domNode) {
const editorCoords = dom.getDomNodePagePosition(domNode);
const startCoords = this._codeEditor.getScrolledVisiblePosition(selection.getStartPosition());
const startLeft = editorCoords.left + (startCoords ? startCoords.left : 0);
const startTop = startCoords ? startCoords.top : 0;

if (this._viewZone && startTop < this._viewZone.heightInPx) {
if (selection.endLineNumber > selection.startLineNumber) {
adjustEditorScrollTop = false;
}

const leftOfFindWidget = dom.getTopLeftOffset(this._domNode).left;
if (startLeft > leftOfFindWidget) {
adjustEditorScrollTop = false;
}
const endCoords = this._codeEditor.getScrolledVisiblePosition(selection.getEndPosition());
const endLeft = editorCoords.left + (endCoords ? endCoords.left : 0);
if (endLeft > leftOfFindWidget) {
adjustEditorScrollTop = false;
}
}
}
}
this._showViewZone(adjustEditorScrollTop);
// Keep the zone in-viewport so Find does not cover the first lines (#316054).
this._showViewZone(false);
}
}

Expand Down Expand Up @@ -657,16 +635,27 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
if (!this._isVisible) {
return;
}

if (!this._viewZone) {
this._viewZone = new FindWidgetViewZone(0);
}

const viewZone = this._viewZone;
if (this._viewZoneId !== undefined || !viewZone) {
if (this._viewZoneId !== undefined) {
// Zone already attached; still honor an explicit scroll restore from view-state.
if (typeof targetScrollTop === 'number') {
this._codeEditor.setScrollTop(targetScrollTop);
}
return;
}

this._codeEditor.changeViewZones((accessor) => {
viewZone.heightInPx = this._getHeight();
viewZone.heightInPx = this._getViewZoneHeight();
this._viewZoneId = accessor.addZone(viewZone);
// scroll top adjust to make sure the editor doesn't scroll when adding viewzone at the beginning.
this._codeEditor.setScrollTop(targetScrollTop || this._codeEditor.getScrollTop() + viewZone.heightInPx);
// Restore explicit scroll only; otherwise leave scroll so the zone stays visible (#316054).
if (typeof targetScrollTop === 'number') {
this._codeEditor.setScrollTop(targetScrollTop);
}
});
}

Expand All @@ -688,15 +677,15 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
const viewZone = this._viewZone;

this._codeEditor.changeViewZones((accessor) => {
const measured = this._getViewZoneHeight();
if (this._viewZoneId !== undefined) {
// the view zone already exists, we need to update the height
const newHeight = this._getHeight();
if (newHeight === viewZone.heightInPx) {
if (measured === viewZone.heightInPx) {
return;
}

const scrollAdjustment = newHeight - viewZone.heightInPx;
viewZone.heightInPx = newHeight;
const scrollAdjustment = measured - viewZone.heightInPx;
viewZone.heightInPx = measured;
accessor.layoutZone(this._viewZoneId);

if (adjustScroll) {
Expand All @@ -705,7 +694,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL

return;
} else {
let scrollAdjustment = this._getHeight();
let scrollAdjustment = measured;

// if the editor has top padding, factor that into the zone height
scrollAdjustment -= this._codeEditor.getOption(EditorOption.padding).top;
Expand All @@ -723,6 +712,12 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
});
}

private _getViewZoneHeight(): number {
// Use laid-out height with a minimum, plus margin-top, so the zone clears Find (#316054).
const marginTop = 4;
return Math.max(this._getHeight(), this._domNode.offsetHeight || 0, FIND_INPUT_AREA_HEIGHT) + marginTop;
}

private _removeViewZone() {
this._codeEditor.changeViewZones((accessor) => {
if (this._viewZoneId !== undefined) {
Expand Down Expand Up @@ -1379,7 +1374,7 @@ export class FindWidget extends Widget implements IOverlayWidget, IVerticalSashL
}

if (state.widgetViewZoneVisible) {
// we should add the view zone
this._showViewZone(false);
this._layoutViewZone(state.scrollTop);
}
}
Expand Down