Skip to content

Commit 6512fbf

Browse files
committed
Make full markdown cell draggable
Fix microsoft#104104 Large change because we can't make .monaco-list-row draggable, and really we should not be messing with that element which is owned by the List, so added a new inner container
1 parent 11c0b60 commit 6512fbf

5 files changed

Lines changed: 53 additions & 44 deletions

File tree

src/vs/base/browser/ui/toolbar/toolbar.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export class ToolBar extends Disposable {
3939
private submenuActionViewItems: DropdownMenuActionViewItem[] = [];
4040
private hasSecondaryActions: boolean = false;
4141
private lookupKeybindings: boolean;
42+
private element: HTMLElement;
4243

4344
private _onDidChangeDropdownVisibility = this._register(new EventMultiplexer<boolean>());
4445
readonly onDidChangeDropdownVisibility = this._onDidChangeDropdownVisibility.event;
@@ -52,11 +53,11 @@ export class ToolBar extends Disposable {
5253

5354
this.toggleMenuAction = this._register(new ToggleMenuAction(() => this.toggleMenuActionViewItem?.show(), options.toggleMenuTitle));
5455

55-
let element = document.createElement('div');
56-
element.className = 'monaco-toolbar';
57-
container.appendChild(element);
56+
this.element = document.createElement('div');
57+
this.element.className = 'monaco-toolbar';
58+
container.appendChild(this.element);
5859

59-
this.actionBar = this._register(new ActionBar(element, {
60+
this.actionBar = this._register(new ActionBar(this.element, {
6061
orientation: options.orientation,
6162
ariaLabel: options.ariaLabel,
6263
actionRunner: options.actionRunner,
@@ -134,8 +135,8 @@ export class ToolBar extends Disposable {
134135
}
135136
}
136137

137-
getContainer(): HTMLElement {
138-
return this.actionBar.getContainer();
138+
getElement(): HTMLElement {
139+
return this.element;
139140
}
140141

141142
getItemsWidth(): number {

src/vs/workbench/contrib/notebook/browser/media/notebook.css

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
display: none !important;
7676
}
7777

78-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-drag-image > .monaco-toolbar {
78+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-drag-image .cell-title-toolbar {
7979
display: none;
8080
}
8181

@@ -197,13 +197,13 @@
197197

198198
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .menu.mouseover,
199199
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row:hover .menu,
200-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-output-hover .menu {
200+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-output-hover .menu {
201201
visibility: visible;
202202
}
203203

204204
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row,
205205
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row:hover,
206-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-output-hover {
206+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-output-hover {
207207
outline: none !important;
208208
}
209209

@@ -223,7 +223,7 @@
223223
}
224224

225225
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.collapsed .notebook-folding-indicator,
226-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.collapsed > .monaco-toolbar {
226+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.collapsed .cell-title-toolbar {
227227
display: none;
228228
}
229229

@@ -274,7 +274,7 @@
274274
cursor: pointer;
275275
}
276276

277-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .monaco-toolbar {
277+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar {
278278
visibility: hidden;
279279
display: inline-block;
280280
position: absolute;
@@ -285,25 +285,25 @@
285285
z-index: 30;
286286
}
287287

288-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .monaco-toolbar .action-item {
288+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar .action-item {
289289
width: 24px;
290290
height: 24px;
291291
display: flex;
292292
align-items: center;
293293
margin: 1px 2px;
294294
}
295295

296-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .monaco-toolbar .action-item .action-label {
296+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar .action-item .action-label {
297297
display: flex;
298298
align-items: center;
299299
margin: auto;
300300
}
301301

302-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .monaco-toolbar .action-item .monaco-dropdown {
302+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar .action-item .monaco-dropdown {
303303
width: 100%;
304304
}
305305

306-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .monaco-toolbar .action-item .monaco-dropdown .dropdown-label {
306+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-title-toolbar .action-item .monaco-dropdown .dropdown-label {
307307
display: flex;
308308
}
309309

@@ -422,9 +422,9 @@
422422
height: 2px;
423423
}
424424

425-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-has-toolbar-actions.focused > .monaco-toolbar,
426-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-has-toolbar-actions.cell-output-hover > .monaco-toolbar,
427-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row.cell-has-toolbar-actions:hover > .monaco-toolbar {
425+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-has-toolbar-actions.focused .cell-title-toolbar,
426+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-has-toolbar-actions.cell-output-hover .cell-title-toolbar,
427+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-has-toolbar-actions:hover .cell-title-toolbar {
428428
visibility: visible;
429429
}
430430

@@ -460,6 +460,10 @@
460460
cursor: grab;
461461
}
462462

463+
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .cell-inner-container:hover {
464+
cursor: grab;
465+
}
466+
463467
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator .codicon:hover {
464468
cursor: pointer;
465469
}
@@ -490,7 +494,7 @@
490494
z-index: 10;
491495
}
492496

493-
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list .monaco-list-row.cell-dragging {
497+
.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list .monaco-list-row .cell-dragging {
494498
opacity: 0.5 !important;
495499
}
496500

@@ -502,7 +506,6 @@
502506
width: 100%;
503507
opacity: 0;
504508
transition: opacity 0.2s ease-in-out;
505-
cursor: auto;
506509
padding: 0;
507510
}
508511

src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,14 +1795,14 @@ registerThemingParticipant((theme, collector) => {
17951795
const editorBackgroundColor = theme.getColor(editorBackground);
17961796
if (editorBackgroundColor) {
17971797
collector.addRule(`.notebookOverlay .cell-statusbar-container { border-top: solid 1px ${editorBackgroundColor}; }`);
1798-
collector.addRule(`.notebookOverlay .monaco-list-row > .monaco-toolbar { background-color: ${editorBackgroundColor}; }`);
1798+
collector.addRule(`.notebookOverlay .monaco-list-row .cell-title-toolbar { background-color: ${editorBackgroundColor}; }`);
17991799
collector.addRule(`.notebookOverlay .monaco-list-row.cell-drag-image { background-color: ${editorBackgroundColor}; }`);
18001800
collector.addRule(`.notebookOverlay .cell-bottom-toolbar-container .action-item { background-color: ${editorBackgroundColor} }`);
18011801
}
18021802

18031803
const cellToolbarSeperator = theme.getColor(CELL_TOOLBAR_SEPERATOR);
18041804
if (cellToolbarSeperator) {
1805-
collector.addRule(`.notebookOverlay .monaco-list-row > .monaco-toolbar { border: solid 1px ${cellToolbarSeperator}; }`);
1805+
collector.addRule(`.notebookOverlay .monaco-list-row .cell-title-toolbar { border: solid 1px ${cellToolbarSeperator}; }`);
18061806
collector.addRule(`.notebookOverlay .cell-bottom-toolbar-container .action-item { border: solid 1px ${cellToolbarSeperator} }`);
18071807
collector.addRule(`.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-collapsed-part { border-bottom: solid 1px ${cellToolbarSeperator} }`);
18081808
collector.addRule(`.notebookOverlay .monaco-action-bar .action-item.verticalSeparator { background-color: ${cellToolbarSeperator} }`);
@@ -1834,15 +1834,15 @@ registerThemingParticipant((theme, collector) => {
18341834

18351835
const cellSymbolHighlightColor = theme.getColor(cellSymbolHighlight);
18361836
if (cellSymbolHighlightColor) {
1837-
collector.addRule(`.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row.nb-symbolHighlight .cell-focus-indicator,
1838-
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.nb-symbolHighlight.markdown-cell-row {
1837+
collector.addRule(`.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.code-cell-row .nb-symbolHighlight .cell-focus-indicator,
1838+
.monaco-workbench .notebookOverlay .monaco-list .monaco-list-row.markdown-cell-row .nb-symbolHighlight {
18391839
background-color: ${cellSymbolHighlightColor} !important;
18401840
}`);
18411841
}
18421842

18431843
const focusedEditorBorderColorColor = theme.getColor(focusedEditorBorderColor);
18441844
if (focusedEditorBorderColorColor) {
1845-
collector.addRule(`.notebookOverlay .monaco-list-row.cell-editor-focus .cell-editor-part:before { outline: solid 1px ${focusedEditorBorderColorColor}; }`);
1845+
collector.addRule(`.notebookOverlay .monaco-list-row .cell-editor-focus .cell-editor-part:before { outline: solid 1px ${focusedEditorBorderColorColor}; }`);
18461846
}
18471847

18481848
const cellBorderColor = theme.getColor(notebookCellBorder);
@@ -1895,14 +1895,14 @@ registerThemingParticipant((theme, collector) => {
18951895
}
18961896

18971897
// Cell Margin
1898-
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > div.cell { margin: 0px ${CELL_MARGIN * 2}px 0px ${CELL_MARGIN}px; }`);
1899-
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > div.cell.code { margin-left: ${CODE_CELL_LEFT_MARGIN}px; }`);
1900-
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row { padding-top: ${CELL_TOP_MARGIN}px; }`);
1901-
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row { padding-bottom: ${CELL_BOTTOM_MARGIN}px; }`);
1898+
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell { margin: 0px ${CELL_MARGIN * 2}px 0px ${CELL_MARGIN}px; }`);
1899+
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.code { margin-left: ${CODE_CELL_LEFT_MARGIN}px; }`);
1900+
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > .cell-inner-container { padding-top: ${CELL_TOP_MARGIN}px; }`);
1901+
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .markdown-cell-row > .cell-inner-container { padding-bottom: ${CELL_BOTTOM_MARGIN}px; }`);
19021902
collector.addRule(`.notebookOverlay .output { margin: 0px ${CELL_MARGIN}px 0px ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER}px; }`);
19031903
collector.addRule(`.notebookOverlay .output { width: calc(100% - ${CODE_CELL_LEFT_MARGIN + CELL_RUN_GUTTER + (CELL_MARGIN * 2)}px); }`);
19041904

1905-
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row > div.cell.markdown { padding-left: ${CELL_RUN_GUTTER}px; }`);
1905+
collector.addRule(`.notebookOverlay .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row div.cell.markdown { padding-left: ${CELL_RUN_GUTTER}px; }`);
19061906
collector.addRule(`.notebookOverlay .cell .run-button-container { width: ${CELL_RUN_GUTTER}px; }`);
19071907
collector.addRule(`.notebookOverlay .cell-drag-image .cell-editor-container > div { padding: ${EDITOR_TOP_PADDING}px 16px ${EDITOR_BOTTOM_PADDING}px 16px; }`);
19081908
collector.addRule(`.notebookOverlay .monaco-list .monaco-list-row .cell-focus-indicator-top { height: ${CELL_TOP_MARGIN}px; }`);

src/vs/workbench/contrib/notebook/browser/view/renderers/cellRenderer.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ abstract class AbstractCellRenderer {
228228
}));
229229
}
230230

231-
protected createToolbar(container: HTMLElement): ToolBar {
231+
protected createToolbar(container: HTMLElement, elementClass?: string): ToolBar {
232232
const toolbar = new ToolBar(container, this.contextMenuService, {
233233
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
234234
actionViewItemProvider: action => {
@@ -246,6 +246,10 @@ abstract class AbstractCellRenderer {
246246
}
247247
});
248248

249+
if (elementClass) {
250+
toolbar.getElement().classList.add(elementClass);
251+
}
252+
249253
return toolbar;
250254
}
251255

@@ -263,7 +267,7 @@ abstract class AbstractCellRenderer {
263267
const updateActions = () => {
264268
const actions = this.getCellToolbarActions(templateData.titleMenu);
265269

266-
const hadFocus = DOM.isAncestor(document.activeElement, templateData.toolbar.getContainer());
270+
const hadFocus = DOM.isAncestor(document.activeElement, templateData.toolbar.getElement());
267271
templateData.toolbar.setActions(actions.primary, actions.secondary);
268272
if (hadFocus) {
269273
this.notebookEditor.focus();
@@ -387,19 +391,20 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
387391

388392
renderTemplate(container: HTMLElement): MarkdownCellRenderTemplate {
389393
container.classList.add('markdown-cell-row');
394+
container = DOM.append(container, DOM.$('.cell-inner-container'));
390395
const disposables = new DisposableStore();
391396
const contextKeyService = disposables.add(this.contextKeyServiceProvider(container));
392-
const toolbar = disposables.add(this.createToolbar(container));
393-
const focusIndicator = DOM.append(container, DOM.$('.cell-focus-indicator.cell-focus-indicator-side.cell-focus-indicator-left'));
394-
focusIndicator.setAttribute('draggable', 'true');
397+
const toolbar = disposables.add(this.createToolbar(container, 'cell-title-toolbar'));
398+
const focusIndicatorLeft = DOM.append(container, DOM.$('.cell-focus-indicator.cell-focus-indicator-side.cell-focus-indicator-left'));
399+
container.setAttribute('draggable', 'true');
395400

396401
const codeInnerContent = DOM.append(container, $('.cell.code'));
397402
const editorPart = DOM.append(codeInnerContent, $('.cell-editor-part'));
398403
const editorContainer = DOM.append(editorPart, $('.cell-editor-container'));
399404
editorPart.style.display = 'none';
400405

401406
const innerContent = DOM.append(container, $('.cell.markdown'));
402-
const foldingIndicator = DOM.append(focusIndicator, DOM.$('.notebook-folding-indicator'));
407+
const foldingIndicator = DOM.append(focusIndicatorLeft, DOM.$('.notebook-folding-indicator'));
403408

404409
const { collapsedPart, expandButton } = this.setupCollapsedPart(container);
405410

@@ -417,7 +422,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
417422
cellContainer: innerContent,
418423
editorPart,
419424
editorContainer,
420-
focusIndicatorLeft: focusIndicator,
425+
focusIndicatorLeft,
421426
foldingIndicator,
422427
disposables,
423428
elementDisposables: new DisposableStore(),
@@ -445,7 +450,7 @@ export class MarkdownCellRenderer extends AbstractCellRenderer implements IListR
445450

446451
private getMarkdownDragImage(templateData: MarkdownCellRenderTemplate): HTMLElement {
447452
const dragImageContainer = DOM.$('.cell-drag-image.monaco-list-row.focused.markdown-cell-row');
448-
dragImageContainer.innerHTML = templateData.container.innerHTML;
453+
dragImageContainer.innerHTML = templateData.container.outerHTML;
449454

450455
// Remove all rendered content nodes after the
451456
const markdownContent = dragImageContainer.querySelector('.cell.markdown')!;
@@ -720,15 +725,14 @@ export class CellDragAndDropController extends Disposable {
720725

721726
registerDragHandle(templateData: BaseCellRenderTemplate, dragImageProvider: DragImageProvider): void {
722727
const container = templateData.container;
723-
const dragHandle = templateData.focusIndicatorLeft;
724728

725-
templateData.disposables.add(domEvent(dragHandle, DOM.EventType.DRAG_END)(() => {
729+
templateData.disposables.add(domEvent(container, DOM.EventType.DRAG_END)(() => {
726730
// Note, templateData may have a different element rendered into it by now
727731
container.classList.remove(DRAGGING_CLASS);
728732
this.dragCleanup();
729733
}));
730734

731-
templateData.disposables.add(domEvent(dragHandle, DOM.EventType.DRAG_START)(event => {
735+
templateData.disposables.add(domEvent(container, DOM.EventType.DRAG_START)(event => {
732736
if (!event.dataTransfer) {
733737
return;
734738
}
@@ -737,7 +741,7 @@ export class CellDragAndDropController extends Disposable {
737741
this.currentDraggedCell.dragging = true;
738742

739743
const dragImage = dragImageProvider();
740-
container.parentElement!.appendChild(dragImage);
744+
container.parentElement!.parentElement!.appendChild(dragImage);
741745
event.dataTransfer.setDragImage(dragImage, 0, 0);
742746
setTimeout(() => container.parentElement!.removeChild(dragImage!), 0); // Comment this out to debug drag image layout
743747

@@ -965,11 +969,12 @@ export class CodeCellRenderer extends AbstractCellRenderer implements IListRende
965969

966970
renderTemplate(container: HTMLElement): CodeCellRenderTemplate {
967971
container.classList.add('code-cell-row');
972+
container = DOM.append(container, DOM.$('.cell-inner-container'));
968973
const disposables = new DisposableStore();
969974
const contextKeyService = disposables.add(this.contextKeyServiceProvider(container));
970975

971976
DOM.append(container, $('.cell-focus-indicator.cell-focus-indicator-top'));
972-
const toolbar = disposables.add(this.createToolbar(container));
977+
const toolbar = disposables.add(this.createToolbar(container, 'cell-title-toolbar'));
973978
const focusIndicator = DOM.append(container, DOM.$('.cell-focus-indicator.cell-focus-indicator-side.cell-focus-indicator-left'));
974979
focusIndicator.setAttribute('draggable', 'true');
975980

src/vs/workbench/contrib/preferences/browser/settingsTree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
604604
}
605605

606606
private fixToolbarIcon(toolbar: ToolBar): void {
607-
const button = toolbar.getContainer().querySelector('.codicon-toolbar-more');
607+
const button = toolbar.getElement().querySelector('.codicon-toolbar-more');
608608
if (button) {
609609
(<HTMLElement>button).tabIndex = -1;
610610

0 commit comments

Comments
 (0)