Support drag and drop copy for markdown cells

For #116393

Also removes some logging and improves drag/drop responsiveness
This commit is contained in:
Matt Bierner 2021-02-10 17:37:28 -08:00
parent b262ce0ac4
commit 6dd156d04b
6 changed files with 57 additions and 33 deletions

View file

@ -20,10 +20,7 @@ type extendMarkdownItFnType = (
const notebook = acquireNotebookRendererApi('notebookCoreTestRenderer');
notebook.onDidCreateMarkdown(({ element, content }: any) => {
console.log('did create markdown cell');
const rendered = markdownIt.render(content);
element.innerHTML = rendered;
});
console.log('markdown-it');
}());

View file

@ -171,7 +171,7 @@ export interface ICommonNotebookEditor {
setMarkdownCellEditState(cellId: string, editState: CellEditState): void;
markdownCellDragStart(cellId: string, position: { clientY: number }): void;
markdownCellDrag(cellId: string, position: { clientY: number }): void;
markdownCellDragEnd(cellId: string, position: { clientY: number }): void;
markdownCellDragEnd(cellId: string, position: { clientY: number, ctrlKey: boolean, altKey: boolean }): void;
}
//#endregion

View file

@ -2125,27 +2125,27 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
}
}
markdownCellDragStart(cellId: string, position: { clientY: number }): void {
markdownCellDragStart(cellId: string, ctx: { clientY: number }): void {
const cell = this.viewModel?.viewCells.find(vc => vc.id === cellId);
if (cell && cell instanceof MarkdownCellViewModel) {
this._dndController?.startExplicitDrag(cell, position);
this._dndController?.startExplicitDrag(cell, ctx);
}
}
markdownCellDrag(cellId: string, position: { clientY: number }): void {
markdownCellDrag(cellId: string, ctx: { clientY: number }): void {
const cell = this.viewModel?.viewCells.find(vc => vc.id === cellId);
if (cell && cell instanceof MarkdownCellViewModel) {
this._dndController?.explicitDrag(cell, position);
this._dndController?.explicitDrag(cell, ctx);
}
}
markdownCellDragEnd(cellId: string, position: { clientY: number }): void {
markdownCellDragEnd(cellId: string, ctx: { clientY: number, ctrlKey: boolean, altKey: boolean }): void {
const cell = this.viewModel?.viewCells.find(vc => vc.id === cellId);
if (cell && cell instanceof MarkdownCellViewModel) {
this._dndController?.endExplicitDrag(cell, position);
this._dndController?.endExplicitDrag(cell, ctx);
}
}

View file

@ -101,10 +101,15 @@ export interface ICellDragMessage {
}
export interface ICellDragEndMessage {
__vscode_notebook_message: boolean;
type: 'cell-drag-end';
cellId: string;
position: { clientX: number, clientY: number };
readonly __vscode_notebook_message: boolean;
readonly type: 'cell-drag-end';
readonly cellId: string;
readonly ctrlKey: boolean
readonly altKey: boolean;
readonly position: {
readonly clientX: number;
readonly clientY: number;
};
}
export interface IClearMessage {
@ -768,7 +773,11 @@ var requirejs = (function() {
} else if (data.type === 'cell-drag') {
this.notebookEditor.markdownCellDrag(data.cellId, data.position);
} else if (data.type === 'cell-drag-end') {
this.notebookEditor.markdownCellDragEnd(data.cellId, data.position);
this.notebookEditor.markdownCellDragEnd(data.cellId, {
clientY: data.position.clientY,
ctrlKey: data.ctrlKey,
altKey: data.altKey,
});
}
return;
}

View file

@ -64,17 +64,14 @@ export class CellDragAndDropController extends Disposable {
};
addCellDragListener(DOM.EventType.DRAG_OVER, event => {
console.log('dragOver');
event.browserEvent.preventDefault();
this.onCellDragover(event);
});
addCellDragListener(DOM.EventType.DROP, event => {
console.log('drop');
event.browserEvent.preventDefault();
this.onCellDrop(event);
});
addCellDragListener(DOM.EventType.DRAG_LEAVE, event => {
console.log('drag leave');
event.browserEvent.preventDefault();
this.onCellDragLeave(event);
});
@ -304,11 +301,11 @@ export class CellDragAndDropController extends Disposable {
}
}
public endExplicitDrag(cell: ICellViewModel, position: { clientY: number }) {
public endExplicitDrag(cell: ICellViewModel, ctx: { clientY: number, ctrlKey: boolean, altKey: boolean }) {
this.currentDraggedCell = undefined;
this.setInsertIndicatorVisibility(false);
const target = this.list.elementAt(position.clientY);
const target = this.list.elementAt(ctx.clientY);
if (!target || target === cell) {
return;
}
@ -316,16 +313,16 @@ export class CellDragAndDropController extends Disposable {
const cellTop = this.list.getAbsoluteTopOfElement(target);
const cellHeight = this.list.elementHeight(target);
const dragOffset = this.list.scrollTop + position.clientY - cellTop;
const dragOffset = this.list.scrollTop + ctx.clientY - cellTop;
const dragPosInElement = dragOffset - cellTop;
const dragPosRatio = dragPosInElement / cellHeight;
const dropDirection = this.getDropInsertDirection(dragPosRatio);
const isCopy = false; // TODO
const isCopy = (ctx.ctrlKey && !platform.isMacintosh) || (ctx.altKey && platform.isMacintosh);
if (isCopy) {
// this.copyCells(draggedCells, event.draggedOverCell, dropDirection);
this.copyCells([cell], target, dropDirection);
} else {
const viewModel = this.notebookEditor.viewModel!;
let originalToIdx = viewModel.getCellIndex(target);

View file

@ -659,6 +659,32 @@ function webviewPreloads() {
type: 'initialized'
});
document.addEventListener('dragover', e => {
// Allow dropping dragged markdown cells
e.preventDefault();
});
const markdownCellDragDataType = 'x-vscode-markdown-cell-drag';
document.addEventListener('drop', e => {
const data = e.dataTransfer?.getData(markdownCellDragDataType);
if (!data) {
return;
}
e.preventDefault();
const { cellId } = JSON.parse(data);
const msg: ICellDragEndMessage = {
__vscode_notebook_message: true,
type: 'cell-drag-end',
cellId: cellId,
ctrlKey: e.ctrlKey,
altKey: e.altKey,
position: { clientX: e.clientX, clientY: e.clientY },
};
vscode.postMessage(msg);
});
function createMarkdownPreview(cellId: string, content: string, top: number) {
let cellContainer = document.getElementById(cellId);
if (!cellContainer) {
@ -685,6 +711,11 @@ function webviewPreloads() {
previewContainerNode.setAttribute('draggable', 'true');
previewContainerNode.addEventListener('dragstart', e => {
if (!e.dataTransfer) {
return;
}
e.dataTransfer.setData(markdownCellDragDataType, JSON.stringify({ cellId }));
(e.target as HTMLElement).classList.add('dragging');
const msg: ICellDragStartMessage = {
@ -697,8 +728,6 @@ function webviewPreloads() {
});
previewContainerNode.addEventListener('drag', e => {
console.log('drag', e);
const msg: ICellDragMessage = {
__vscode_notebook_message: true,
type: 'cell-drag',
@ -710,14 +739,6 @@ function webviewPreloads() {
previewContainerNode.addEventListener('dragend', e => {
(e.target as HTMLElement).classList.remove('dragging');
const msg: ICellDragEndMessage = {
__vscode_notebook_message: true,
type: 'cell-drag-end',
cellId: cellId,
position: { clientX: e.clientX, clientY: e.clientY },
};
vscode.postMessage(msg);
});
cellContainer.appendChild(previewContainerNode);