Skip to content

Commit 6259126

Browse files
committed
Move more code out of cellRenderer #131808
1 parent e8980d8 commit 6259126

File tree

5 files changed

+199
-140
lines changed

5 files changed

+199
-140
lines changed

src/tsec.exemptions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"vs/editor/browser/widget/diffReview.ts",
2323
"vs/editor/standalone/browser/colorizer.ts",
2424
"vs/workbench/api/worker/extHostExtensionService.ts",
25-
"vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts",
25+
"vs/workbench/contrib/notebook/browser/view/renderers/cellDragRenderer.ts",
2626
"vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts",
2727
"vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts"
2828
],

src/vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { Delayer } from 'vs/base/common/async';
88
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
99
import * as platform from 'vs/base/common/platform';
1010
import { expandCellRangesWithHiddenCells, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
11+
import { CellViewModelStateChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents';
12+
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
1113
import { BaseCellRenderTemplate, INotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon';
1214
import { cloneNotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
1315
import { CellEditType, ICellMoveEdit, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
@@ -28,6 +30,25 @@ interface CellDragEvent {
2830
dragPosRatio: number;
2931
}
3032

33+
export class CellDragAndDropPart extends CellPart {
34+
renderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void {
35+
if (element.dragging) {
36+
templateData.container.classList.add(DRAGGING_CLASS);
37+
} else {
38+
templateData.container.classList.remove(DRAGGING_CLASS);
39+
}
40+
}
41+
42+
prepareLayout(): void {
43+
}
44+
45+
updateInternalLayoutNow(element: ICellViewModel): void {
46+
}
47+
48+
updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void {
49+
}
50+
}
51+
3152
export class CellDragAndDropController extends Disposable {
3253
// TODO@roblourens - should probably use dataTransfer here, but any dataTransfer set makes the editor think I am dropping a file, need
3354
// to figure out how to prevent that
@@ -97,14 +118,6 @@ export class CellDragAndDropController extends Disposable {
97118
});
98119
}
99120

100-
renderElement(element: ICellViewModel, templateData: BaseCellRenderTemplate): void {
101-
if (element.dragging) {
102-
templateData.container.classList.add(DRAGGING_CLASS);
103-
} else {
104-
templateData.container.classList.remove(DRAGGING_CLASS);
105-
}
106-
}
107-
108121
private setInsertIndicatorVisibility(visible: boolean) {
109122
this.listInsertionIndicator.style.opacity = visible ? '1' : '0';
110123
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as DOM from 'vs/base/browser/dom';
7+
import { Color } from 'vs/base/common/color';
8+
import * as platform from 'vs/base/common/platform';
9+
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
10+
import { EditorOption } from 'vs/editor/common/config/editorOptions';
11+
import { Range } from 'vs/editor/common/core/range';
12+
import * as languages from 'vs/editor/common/languages';
13+
import { tokenizeLineToHTML } from 'vs/editor/common/languages/textToHtmlTokenizer';
14+
import { ITextModel } from 'vs/editor/common/model';
15+
import { BaseCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon';
16+
17+
class EditorTextRenderer {
18+
19+
private static _ttPolicy = window.trustedTypes?.createPolicy('cellRendererEditorText', {
20+
createHTML(input) { return input; }
21+
});
22+
23+
getRichText(editor: ICodeEditor, modelRange: Range): HTMLElement | null {
24+
const model = editor.getModel();
25+
if (!model) {
26+
return null;
27+
}
28+
29+
const colorMap = this.getDefaultColorMap();
30+
const fontInfo = editor.getOptions().get(EditorOption.fontInfo);
31+
const fontFamilyVar = '--notebook-editor-font-family';
32+
const fontSizeVar = '--notebook-editor-font-size';
33+
const fontWeightVar = '--notebook-editor-font-weight';
34+
35+
const style = ``
36+
+ `color: ${colorMap[languages.ColorId.DefaultForeground]};`
37+
+ `background-color: ${colorMap[languages.ColorId.DefaultBackground]};`
38+
+ `font-family: var(${fontFamilyVar});`
39+
+ `font-weight: var(${fontWeightVar});`
40+
+ `font-size: var(${fontSizeVar});`
41+
+ `line-height: ${fontInfo.lineHeight}px;`
42+
+ `white-space: pre;`;
43+
44+
const element = DOM.$('div', { style });
45+
46+
const fontSize = fontInfo.fontSize;
47+
const fontWeight = fontInfo.fontWeight;
48+
element.style.setProperty(fontFamilyVar, fontInfo.fontFamily);
49+
element.style.setProperty(fontSizeVar, `${fontSize}px`);
50+
element.style.setProperty(fontWeightVar, fontWeight);
51+
52+
const linesHtml = this.getRichTextLinesAsHtml(model, modelRange, colorMap);
53+
element.innerHTML = linesHtml as string;
54+
return element;
55+
}
56+
57+
private getRichTextLinesAsHtml(model: ITextModel, modelRange: Range, colorMap: string[]): string | TrustedHTML {
58+
const startLineNumber = modelRange.startLineNumber;
59+
const startColumn = modelRange.startColumn;
60+
const endLineNumber = modelRange.endLineNumber;
61+
const endColumn = modelRange.endColumn;
62+
63+
const tabSize = model.getOptions().tabSize;
64+
65+
let result = '';
66+
67+
for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
68+
const lineTokens = model.getLineTokens(lineNumber);
69+
const lineContent = lineTokens.getLineContent();
70+
const startOffset = (lineNumber === startLineNumber ? startColumn - 1 : 0);
71+
const endOffset = (lineNumber === endLineNumber ? endColumn - 1 : lineContent.length);
72+
73+
if (lineContent === '') {
74+
result += '<br>';
75+
} else {
76+
result += tokenizeLineToHTML(lineContent, lineTokens.inflate(), colorMap, startOffset, endOffset, tabSize, platform.isWindows);
77+
}
78+
}
79+
80+
return EditorTextRenderer._ttPolicy?.createHTML(result) ?? result;
81+
}
82+
83+
private getDefaultColorMap(): string[] {
84+
const colorMap = languages.TokenizationRegistry.getColorMap();
85+
const result: string[] = ['#000000'];
86+
if (colorMap) {
87+
for (let i = 1, len = colorMap.length; i < len; i++) {
88+
result[i] = Color.Format.CSS.formatHex(colorMap[i]);
89+
}
90+
}
91+
return result;
92+
}
93+
}
94+
95+
export class CodeCellDragImageRenderer {
96+
getDragImage(templateData: BaseCellRenderTemplate, editor: ICodeEditor, type: 'code' | 'markdown'): HTMLElement {
97+
let dragImage = this.getDragImageImpl(templateData, editor, type);
98+
if (!dragImage) {
99+
// TODO@roblourens I don't think this can happen
100+
dragImage = document.createElement('div');
101+
dragImage.textContent = '1 cell';
102+
}
103+
104+
return dragImage;
105+
}
106+
107+
private getDragImageImpl(templateData: BaseCellRenderTemplate, editor: ICodeEditor, type: 'code' | 'markdown'): HTMLElement | null {
108+
const dragImageContainer = templateData.container.cloneNode(true) as HTMLElement;
109+
dragImageContainer.classList.forEach(c => dragImageContainer.classList.remove(c));
110+
dragImageContainer.classList.add('cell-drag-image', 'monaco-list-row', 'focused', `${type}-cell-row`);
111+
112+
const editorContainer: HTMLElement | null = dragImageContainer.querySelector('.cell-editor-container');
113+
if (!editorContainer) {
114+
return null;
115+
}
116+
117+
const richEditorText = new EditorTextRenderer().getRichText(editor, new Range(1, 1, 1, 1000));
118+
if (!richEditorText) {
119+
return null;
120+
}
121+
DOM.reset(editorContainer, richEditorText);
122+
123+
return dragImageContainer;
124+
}
125+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as DOM from 'vs/base/browser/dom';
7+
import { ICellViewModel, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
8+
import { CellViewModelStateChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents';
9+
import { CellPart } from 'vs/workbench/contrib/notebook/browser/view/cellParts/cellPart';
10+
import { BaseCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon';
11+
12+
export class CellFocusPart extends CellPart {
13+
private currentCell: ICellViewModel | undefined;
14+
15+
constructor(
16+
containerElement: HTMLElement,
17+
notebookEditor: INotebookEditor
18+
) {
19+
super();
20+
21+
this._register(DOM.addDisposableListener(containerElement, DOM.EventType.FOCUS, () => {
22+
if (this.currentCell) {
23+
notebookEditor.focusElement(this.currentCell);
24+
}
25+
}, true));
26+
}
27+
28+
renderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void {
29+
this.currentCell = element;
30+
}
31+
32+
override unrenderCell(element: ICellViewModel, templateData: BaseCellRenderTemplate): void {
33+
this.currentCell = undefined;
34+
}
35+
36+
prepareLayout(): void {
37+
}
38+
39+
updateInternalLayoutNow(element: ICellViewModel): void {
40+
}
41+
42+
updateState(element: ICellViewModel, e: CellViewModelStateChangeEvent): void {
43+
}
44+
}

0 commit comments

Comments
 (0)