src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts/ListSettingWidget/addDragAndDrop
class ListSettingWidget:	protected addDragAndDrop(rowElement: HTMLElement, item: IListDataItem, idx: number) {
		if (this.inReadMode) {
			rowElement.draggable = true;
			rowElement.classList.add('draggable');
		} else {
			rowElement.draggable = false;
			rowElement.classList.remove('draggable');
		}

		this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DRAG_START, (ev) => {
			this.dragDetails = {
				element: rowElement,
				item,
				itemIndex: idx
			};
			if (ev.dataTransfer) {
				ev.dataTransfer.dropEffect = 'move';
				const dragImage = this.getDragImage(item);
				document.body.appendChild(dragImage);
				ev.dataTransfer.setDragImage(dragImage, -10, -10);
				setTimeout(() => document.body.removeChild(dragImage), 0);
			}
		}));
		this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DRAG_OVER, (ev) => {
			if (!this.dragDetails) {
				return false;
			}
			ev.preventDefault();
			if (ev.dataTransfer) {
				ev.dataTransfer.dropEffect = 'move';
			}
			return true;
		}));
		let counter = 0;
		this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DRAG_ENTER, (ev) => {
			counter++;
			rowElement.classList.add('drag-hover');
		}));
		this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DRAG_LEAVE, (ev) => {
			counter--;
			if (!counter) {
				rowElement.classList.remove('drag-hover');
			}
		}));
		this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DROP, (ev) => {
			// cancel the op if we dragged to a completely different setting
			if (!this.dragDetails) {
				return false;
			}
			ev.preventDefault();
			counter = 0;
			if (this.dragDetails.element !== rowElement) {
				this._onDidChangeList.fire({
					originalItem: this.dragDetails.item,
					sourceIndex: this.dragDetails.itemIndex,
					item,
					targetIndex: idx
				});
			}
			return true;
		}));
		this.listDisposables.add(DOM.addDisposableListener(rowElement, DOM.EventType.DRAG_END, (ev) => {
			counter = 0;
			rowElement.classList.remove('drag-hover');
			if (ev.dataTransfer) {
				ev.dataTransfer.clearData();
			}
			if (this.dragDetails) {
				this.dragDetails = undefined;
			}
		}));
	}