Skip to content

Commit f4bf1f3

Browse files
authored
Skip ul and ol when highlighting selected markdown element (microsoft#161139)
Fixes microsoft#155552 For lists, the outer ul/ol always has the same source line as the first element in the list. We should prefer using the first element in the list when highlighting the active line This also fixes a bug where scroll sync would stop working if you added lines to the doc. This was caused by `lineCount` getting out of sync as the document is being updated. I've removed this state and made the reveal logic more robust instead
1 parent bd782eb commit f4bf1f3

File tree

7 files changed

+42
-37
lines changed

7 files changed

+42
-37
lines changed

extensions/markdown-language-features/media/markdown.css

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ body.showEditorSelection .code-line {
5555
position: relative;
5656
}
5757

58-
body.showEditorSelection :not(tr).code-active-line:before,
59-
body.showEditorSelection :not(tr).code-line:hover:before {
58+
body.showEditorSelection :not(tr,ul,ol).code-active-line:before,
59+
body.showEditorSelection :not(tr,ul,ol).code-line:hover:before {
6060
content: "";
6161
display: block;
6262
position: absolute;
@@ -65,6 +65,10 @@ body.showEditorSelection :not(tr).code-line:hover:before {
6565
height: 100%;
6666
}
6767

68+
.vscode-high-contrast.showEditorSelection :not(tr,ul,ol).code-line .code-line:hover:before {
69+
border-left: none;
70+
}
71+
6872
body.showEditorSelection li.code-active-line:before,
6973
body.showEditorSelection li.code-line:hover:before {
7074
left: -30px;
@@ -78,10 +82,6 @@ body.showEditorSelection li.code-line:hover:before {
7882
border-left: 3px solid rgba(0, 0, 0, 0.40);
7983
}
8084

81-
.vscode-light.showEditorSelection .code-line .code-line:hover:before {
82-
border-left: none;
83-
}
84-
8585
.vscode-dark.showEditorSelection .code-active-line:before {
8686
border-left: 3px solid rgba(255, 255, 255, 0.4);
8787
}
@@ -90,10 +90,6 @@ body.showEditorSelection li.code-line:hover:before {
9090
border-left: 3px solid rgba(255, 255, 255, 0.60);
9191
}
9292

93-
.vscode-dark.showEditorSelection .code-line .code-line:hover:before {
94-
border-left: none;
95-
}
96-
9793
.vscode-high-contrast.showEditorSelection .code-active-line:before {
9894
border-left: 3px solid rgba(255, 160, 0, 0.7);
9995
}
@@ -102,9 +98,6 @@ body.showEditorSelection li.code-line:hover:before {
10298
border-left: 3px solid rgba(255, 160, 0, 1);
10399
}
104100

105-
.vscode-high-contrast.showEditorSelection .code-line .code-line:hover:before {
106-
border-left: none;
107-
}
108101

109102
ul ul,
110103
ul ol,

extensions/markdown-language-features/preview-src/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ onceDocumentLoaded(() => {
8787
}
8888
});
8989
}
90+
91+
if (typeof settings.settings.selectedLine === 'number') {
92+
marker.onDidChangeTextEditorSelection(settings.settings.selectedLine, documentVersion);
93+
}
9094
});
9195

9296
const onUpdateView = (() => {
@@ -110,7 +114,6 @@ window.addEventListener('resize', () => {
110114
}, true);
111115

112116
window.addEventListener('message', async event => {
113-
114117
switch (event.data.type) {
115118
case 'onDidChangeTextEditorSelection':
116119
if (event.data.source === documentResource) {
@@ -235,7 +238,7 @@ document.addEventListener('dblclick', event => {
235238
}
236239

237240
const offset = event.pageY;
238-
const line = getEditorLineNumberForPageOffset(offset, documentVersion, settings);
241+
const line = getEditorLineNumberForPageOffset(offset, documentVersion);
239242
if (typeof line === 'number' && !isNaN(line)) {
240243
messaging.postMessage('didClick', { line: Math.floor(line) });
241244
}
@@ -284,7 +287,7 @@ window.addEventListener('scroll', throttle(() => {
284287
if (scrollDisabledCount > 0) {
285288
scrollDisabledCount -= 1;
286289
} else {
287-
const line = getEditorLineNumberForPageOffset(window.scrollY, documentVersion, settings);
290+
const line = getEditorLineNumberForPageOffset(window.scrollY, documentVersion);
288291
if (typeof line === 'number' && !isNaN(line)) {
289292
messaging.postMessage('revealLine', { line });
290293
}

extensions/markdown-language-features/preview-src/scroll-sync.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ import { SettingsManager } from './settings';
77

88
const codeLineClass = 'code-line';
99

10-
function clamp(min: number, max: number, value: number) {
11-
return Math.min(max, Math.max(min, value));
12-
}
13-
14-
function clampLine(line: number, lineCount: number) {
15-
return clamp(0, lineCount - 1, line);
16-
}
17-
1810

1911
export interface CodeLineElement {
2012
element: HTMLElement;
@@ -38,10 +30,13 @@ const getCodeLineElements = (() => {
3830
// Fenched code blocks are a special case since the `code-line` can only be marked on
3931
// the `<code>` element and not the parent `<pre>` element.
4032
cachedElements.push({ element: element.parentElement as HTMLElement, line });
33+
} else if (element.tagName === 'UL' || element.tagName === 'OL') {
34+
// Skip adding list elements since the first child has the same code line (and should be preferred)
4135
} else {
4236
cachedElements.push({ element: element as HTMLElement, line });
4337
}
4438
}
39+
console.log(cachedElements);
4540
}
4641
return cachedElements;
4742
};
@@ -149,20 +144,17 @@ export function scrollToRevealSourceLine(line: number, documentVersion: number,
149144
window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo));
150145
}
151146

152-
export function getEditorLineNumberForPageOffset(offset: number, documentVersion: number, settingsManager: SettingsManager) {
153-
const lineCount = settingsManager.settings?.lineCount ?? 0;
147+
export function getEditorLineNumberForPageOffset(offset: number, documentVersion: number) {
154148
const { previous, next } = getLineElementsAtPageOffset(offset, documentVersion);
155149
if (previous) {
156150
const previousBounds = getElementBounds(previous);
157151
const offsetFromPrevious = (offset - window.scrollY - previousBounds.top);
158152
if (next) {
159153
const progressBetweenElements = offsetFromPrevious / (getElementBounds(next).top - previousBounds.top);
160-
const line = previous.line + progressBetweenElements * (next.line - previous.line);
161-
return clampLine(line, lineCount);
154+
return previous.line + progressBetweenElements * (next.line - previous.line);
162155
} else {
163156
const progressWithinElement = offsetFromPrevious / (previousBounds.height);
164-
const line = previous.line + progressWithinElement;
165-
return clampLine(line, lineCount);
157+
return previous.line + progressWithinElement;
166158
}
167159
}
168160
return null;

extensions/markdown-language-features/preview-src/settings.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export interface PreviewSettings {
77
readonly source: string;
88
readonly line?: number;
99
readonly fragment?: string;
10-
readonly lineCount: number;
10+
readonly selectedLine?: number;
11+
1112
readonly scrollPreviewWithEditor?: boolean;
1213
readonly scrollEditorWithPreview: boolean;
1314
readonly disableSecurityWarnings: boolean;

extensions/markdown-language-features/src/preview/documentRenderer.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ export class MdDocumentRenderer {
6262
markdownDocument: vscode.TextDocument,
6363
resourceProvider: WebviewResourceProvider,
6464
previewConfigurations: MarkdownPreviewConfigurationManager,
65-
initialLine: number | undefined = undefined,
65+
initialLine: number | undefined,
66+
selectedLine: number | undefined,
6667
state: any | undefined,
6768
token: vscode.CancellationToken
6869
): Promise<MarkdownContentProviderOutput> {
@@ -72,7 +73,7 @@ export class MdDocumentRenderer {
7273
source: sourceUri.toString(),
7374
fragment: state?.fragment || markdownDocument.uri.fragment || undefined,
7475
line: initialLine,
75-
lineCount: markdownDocument.lineCount,
76+
selectedLine,
7677
scrollPreviewWithEditor: config.scrollPreviewWithEditor,
7778
scrollEditorWithPreview: config.scrollEditorWithPreview,
7879
doubleClickToSwitchToEditor: config.doubleClickToSwitchToEditor,

extensions/markdown-language-features/src/preview/preview.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,16 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
310310
const shouldReloadPage = forceUpdate || !this.currentVersion || this.currentVersion.resource.toString() !== pendingVersion.resource.toString() || !this._webviewPanel.visible;
311311
this.currentVersion = pendingVersion;
312312

313+
let selectedLine: number | undefined = undefined;
314+
for (const editor of vscode.window.visibleTextEditors) {
315+
if (this.isPreviewOf(editor.document.uri)) {
316+
selectedLine = editor.selection.active.line;
317+
break;
318+
}
319+
}
320+
313321
const content = await (shouldReloadPage
314-
? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this.line, this.state, this._disposeCts.token)
322+
? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this.line, selectedLine, this.state, this._disposeCts.token)
315323
: this._contentProvider.renderBody(document, this));
316324

317325
// Another call to `doUpdate` may have happened.

extensions/markdown-language-features/src/preview/scrolling.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,20 @@ export function scrollEditorToLine(
1111
line: number,
1212
editor: vscode.TextEditor
1313
) {
14+
const revealRange = toRevealRange(line, editor);
15+
editor.revealRange(revealRange, vscode.TextEditorRevealType.AtTop);
16+
}
17+
18+
function toRevealRange(line: number, editor: vscode.TextEditor): vscode.Range {
1419
const sourceLine = Math.floor(line);
20+
if (sourceLine >= editor.document.lineCount) {
21+
return new vscode.Range(editor.document.lineCount - 1, 0, editor.document.lineCount - 1, 0);
22+
}
23+
1524
const fraction = line - sourceLine;
1625
const text = editor.document.lineAt(sourceLine).text;
1726
const start = Math.floor(fraction * text.length);
18-
editor.revealRange(
19-
new vscode.Range(sourceLine, start, sourceLine + 1, 0),
20-
vscode.TextEditorRevealType.AtTop);
27+
return new vscode.Range(sourceLine, start, sourceLine + 1, 0);
2128
}
2229

2330
export class StartingScrollFragment {

0 commit comments

Comments
 (0)