aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/DragManager.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util/DragManager.ts')
-rw-r--r--src/client/util/DragManager.ts459
1 files changed, 189 insertions, 270 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index bbc29585c..df2f5fe3c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,7 +1,5 @@
-import { action, runInAction } from "mobx";
-import { Doc, Field } from "../../new_fields/Doc";
-import { Cast, StrCast, ScriptCast } from "../../new_fields/Types";
-import { URLField } from "../../new_fields/URLField";
+import { Doc, Field, DocListCast } from "../../new_fields/Doc";
+import { Cast, ScriptCast } from "../../new_fields/Types";
import { emptyFunction } from "../../Utils";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
import * as globalCssVariables from "../views/globalCssVariables.scss";
@@ -20,43 +18,46 @@ import { convertDropDataToButtons } from "./DropConverter";
export type dropActionType = "alias" | "copy" | undefined;
export function SetupDrag(
_reference: React.RefObject<HTMLElement>,
- docFunc: () => Doc | Promise<Doc>,
+ docFunc: () => Doc | Promise<Doc> | undefined,
moveFunc?: DragManager.MoveFunction,
dropAction?: dropActionType,
- options?: any,
+ treeViewId?: string,
dontHideOnDrop?: boolean,
dragStarted?: () => void
) {
- let onRowMove = async (e: PointerEvent) => {
+ const onRowMove = async (e: PointerEvent) => {
e.stopPropagation();
e.preventDefault();
document.removeEventListener("pointermove", onRowMove);
document.removeEventListener('pointerup', onRowUp);
- let doc = await docFunc();
- var dragData = new DragManager.DocumentDragData([doc]);
- dragData.dropAction = dropAction;
- dragData.moveDocument = moveFunc;
- dragData.options = options;
- dragData.dontHideOnDrop = dontHideOnDrop;
- DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
- dragStarted && dragStarted();
+ const doc = await docFunc();
+ if (doc) {
+ const dragData = new DragManager.DocumentDragData([doc]);
+ dragData.dropAction = dropAction;
+ dragData.moveDocument = moveFunc;
+ dragData.treeViewId = treeViewId;
+ dragData.dontHideOnDrop = dontHideOnDrop;
+ DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
+ dragStarted && dragStarted();
+ }
};
- let onRowUp = (): void => {
+ const onRowUp = (): void => {
document.removeEventListener("pointermove", onRowMove);
document.removeEventListener('pointerup', onRowUp);
};
- let onItemDown = async (e: React.PointerEvent) => {
+ const onItemDown = async (e: React.PointerEvent) => {
if (e.button === 0) {
e.stopPropagation();
if (e.shiftKey && CollectionDockingView.Instance) {
e.persist();
- CollectionDockingView.Instance.StartOtherDrag({
+ const dragDoc = await docFunc();
+ dragDoc && CollectionDockingView.Instance.StartOtherDrag({
pageX: e.pageX,
pageY: e.pageY,
preventDefault: emptyFunction,
button: 0
- }, [await docFunc()]);
+ }, [dragDoc]);
} else {
document.addEventListener("pointermove", onRowMove);
document.addEventListener("pointerup", onRowUp);
@@ -66,62 +67,9 @@ export function SetupDrag(
return onItemDown;
}
-function moveLinkedDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean {
- const document = SelectionManager.SelectedDocuments()[0];
- document && document.props.removeDocument && document.props.removeDocument(doc);
- addDocument(doc);
- return true;
-}
-
-export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: number, linkDoc: Doc, sourceDoc: Doc) {
- let draggeddoc = LinkManager.Instance.getOppositeAnchor(linkDoc, sourceDoc);
- if (draggeddoc) {
- let moddrag = await Cast(draggeddoc.annotationOn, Doc);
- let dragdocs = moddrag ? [moddrag] : [draggeddoc];
- let dragData = new DragManager.DocumentDragData(dragdocs);
- dragData.moveDocument = moveLinkedDocument;
- DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, {
- handlers: {
- dragComplete: action(emptyFunction),
- },
- hideSource: false
- });
- }
-}
-
-export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc, singleLink?: Doc) {
- let srcTarg = sourceDoc.proto;
- let draggedDocs: Doc[] = [];
-
- if (srcTarg) {
- let linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg);
- if (linkDocs) {
- draggedDocs = linkDocs.map(link => {
- let opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc);
- if (opp) return opp;
- }) as Doc[];
- }
- }
- if (draggedDocs.length) {
- let moddrag: Doc[] = [];
- for (const draggedDoc of draggedDocs) {
- let doc = await Cast(draggedDoc.annotationOn, Doc);
- if (doc) moddrag.push(doc);
- }
- let dragdocs = moddrag.length ? moddrag : draggedDocs;
- let dragData = new DragManager.DocumentDragData(dragdocs);
- dragData.moveDocument = moveLinkedDocument;
- DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, {
- handlers: {
- dragComplete: action(emptyFunction),
- },
- hideSource: false
- });
- }
-}
-
-
export namespace DragManager {
+ let dragDiv: HTMLDivElement;
+
export function Root() {
const root = document.getElementById("root");
if (!root) {
@@ -129,79 +77,45 @@ export namespace DragManager {
}
return root;
}
+ export let AbortDrag: () => void = emptyFunction;
+ export type MoveFunction = (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
- let dragDiv: HTMLDivElement;
-
- export enum DragButtons {
- Left = 1,
- Right = 2,
- Both = Left | Right
- }
-
- interface DragOptions {
- handlers: DragHandlers;
-
- hideSource: boolean | (() => boolean);
-
- dragHasStarted?: () => void;
-
- withoutShiftDrag?: boolean;
-
- finishDrag?: (dropData: { [id: string]: any }) => void;
-
- offsetX?: number;
-
+ export interface DragDropDisposer { (): void; }
+ export interface DragOptions {
+ dragComplete?: (e: DragCompleteEvent) => void; // function to invoke when drag has completed
+ hideSource?: boolean; // hide source document during drag
+ offsetX?: number; // offset of top left of source drag visual from cursor
offsetY?: number;
}
- export interface DragDropDisposer {
- (): void;
- }
-
- export class DragCompleteEvent { }
-
- export interface DragHandlers {
- dragComplete: (e: DragCompleteEvent) => void;
- }
-
- export interface DropOptions {
- handlers: DropHandlers;
- }
+ // event called when the drag operation results in a drop action
export class DropEvent {
constructor(
readonly x: number,
readonly y: number,
- readonly data: { [id: string]: any },
- readonly mods: string
+ readonly complete: DragCompleteEvent,
+ readonly altKey: boolean,
+ readonly metaKey: boolean,
+ readonly ctrlKey: boolean
) { }
}
- export interface DropHandlers {
- drop: (e: Event, de: DropEvent) => void;
- }
-
- export function MakeDropTarget(
- element: HTMLElement,
- options: DropOptions
- ): DragDropDisposer {
- if ("canDrop" in element.dataset) {
- throw new Error(
- "Element is already droppable, can't make it droppable again"
- );
+ // event called when the drag operation has completed (aborted or completed a drop) -- this will be after any drop event has been generated
+ export class DragCompleteEvent {
+ constructor(aborted: boolean, dragData: { [id: string]: any }) {
+ this.aborted = aborted;
+ this.docDragData = dragData instanceof DocumentDragData ? dragData : undefined;
+ this.annoDragData = dragData instanceof PdfAnnoDragData ? dragData : undefined;
+ this.linkDragData = dragData instanceof LinkDragData ? dragData : undefined;
+ this.columnDragData = dragData instanceof ColumnDragData ? dragData : undefined;
}
- element.dataset.canDrop = "true";
- const handler = (e: Event) => {
- const ce = e as CustomEvent<DropEvent>;
- options.handlers.drop(e, ce.detail);
- };
- element.addEventListener("dashOnDrop", handler);
- return () => {
- element.removeEventListener("dashOnDrop", handler);
- delete element.dataset.canDrop;
- };
+ aborted: boolean;
+ docDragData?: DocumentDragData;
+ annoDragData?: PdfAnnoDragData;
+ linkDragData?: LinkDragData;
+ columnDragData?: ColumnDragData;
}
- export type MoveFunction = (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
export class DocumentDragData {
constructor(dragDoc: Doc[]) {
this.draggedDocuments = dragDoc;
@@ -210,6 +124,9 @@ export namespace DragManager {
}
draggedDocuments: Doc[];
droppedDocuments: Doc[];
+ dragDivName?: string;
+ treeViewId?: string;
+ dontHideOnDrop?: boolean;
offset: number[];
dropAction: dropActionType;
userDropAction: dropActionType;
@@ -217,16 +134,32 @@ export namespace DragManager {
moveDocument?: MoveFunction;
isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts
applyAsTemplate?: boolean;
- [id: string]: any;
}
-
- export class AnnotationDragData {
+ export class LinkDragData {
+ constructor(linkSourceDoc: Doc) {
+ this.linkSourceDocument = linkSourceDoc;
+ }
+ droppedDocuments: Doc[] = [];
+ linkSourceDocument: Doc;
+ dontClearTextBox?: boolean;
+ linkDocument?: Doc;
+ }
+ export class ColumnDragData {
+ constructor(colKey: SchemaHeaderField) {
+ this.colKey = colKey;
+ }
+ colKey: SchemaHeaderField;
+ }
+ // used by PDFs to conditionally (if the drop completes) create a text annotation when dragging from the PDF toolbar when a text region has been selected.
+ // this is pretty clunky and should be rethought out using linkDrag or DocumentDrag
+ export class PdfAnnoDragData {
constructor(dragDoc: Doc, annotationDoc: Doc, dropDoc: Doc) {
this.dragDocument = dragDoc;
this.dropDocument = dropDoc;
this.annotationDocument = annotationDoc;
this.offset = [0, 0];
}
+ linkedToDoc?: boolean;
targetContext: Doc | undefined;
dragDocument: Doc;
annotationDocument: Doc;
@@ -236,98 +169,103 @@ export namespace DragManager {
userDropAction: dropActionType;
}
- export let StartDragFunctions: (() => void)[] = [];
+ export function MakeDropTarget(
+ element: HTMLElement,
+ dropFunc: (e: Event, de: DropEvent) => void
+ ): DragDropDisposer {
+ if ("canDrop" in element.dataset) {
+ throw new Error(
+ "Element is already droppable, can't make it droppable again"
+ );
+ }
+ element.dataset.canDrop = "true";
+ const handler = (e: Event) => dropFunc(e, (e as CustomEvent<DropEvent>).detail);
+ element.addEventListener("dashOnDrop", handler);
+ return () => {
+ element.removeEventListener("dashOnDrop", handler);
+ delete element.dataset.canDrop;
+ };
+ }
+ // drag a document and drop it (or make an alias/copy on drop)
export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
- runInAction(() => StartDragFunctions.map(func => func()));
+ const finishDrag = (e: DragCompleteEvent) => {
+ e.docDragData && (e.docDragData.droppedDocuments =
+ dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result :
+ dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) :
+ dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d)
+ );
+ e.docDragData?.droppedDocuments.forEach((drop: Doc, i: number) =>
+ Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []).map(prop => drop[prop] = undefined));
+ };
dragData.draggedDocuments.map(d => d.dragFactory); // does this help? trying to make sure the dragFactory Doc is loaded
- StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
- (dropData: { [id: string]: any }) => {
- (dropData.droppedDocuments =
- dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result :
- dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) :
- dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d)
- );
- dropData.droppedDocuments.forEach((drop: Doc, i: number) =>
- Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []).map(prop => drop[prop] = undefined));
- });
+ StartDrag(eles, dragData, downX, downY, options, finishDrag);
}
+ // drag a button template and drop a new button
export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
- let dragData = new DragManager.DocumentDragData([]);
- runInAction(() => StartDragFunctions.map(func => func()));
- StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
- (dropData: { [id: string]: any }) => {
- let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
- bd.onClick = ScriptField.MakeScript(script);
- params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
- initialize && initialize(bd);
- bd.buttonParams = new List<string>(params);
- dropData.droppedDocuments = [bd];
- });
+ const finishDrag = (e: DragCompleteEvent) => {
+ const bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
+ bd.onClick = ScriptField.MakeScript(script);
+ params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
+ initialize && initialize(bd);
+ bd.buttonParams = new List<string>(params);
+ e.docDragData && (e.docDragData.droppedDocuments = [bd]);
+ };
+ StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag);
}
- export function StartLinkedDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
- dragData.moveDocument = moveLinkedDocument;
+ // drag links and drop link targets (aliasing them if needed)
+ export async function StartLinkTargetsDrag(dragEle: HTMLElement, downX: number, downY: number, sourceDoc: Doc, specificLinks?: Doc[]) {
+ const draggedDocs = (specificLinks ? specificLinks : DocListCast(sourceDoc.links)).map(link => LinkManager.Instance.getOppositeAnchor(link, sourceDoc)).filter(l => l) as Doc[];
- runInAction(() => StartDragFunctions.map(func => func()));
- StartDrag(eles, dragData, downX, downY, options,
- (dropData: { [id: string]: any }) => {
- let droppedDocuments: Doc[] = dragData.draggedDocuments.reduce((droppedDocs: Doc[], d) => {
- let dvs = DocumentManager.Instance.getDocumentViews(d);
- if (dvs.length) {
- let containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined;
- let inContext = dvs.filter(dv => dv.props.ContainingCollectionView === containingView);
- if (inContext.length) {
- inContext.forEach(dv => droppedDocs.push(dv.props.Document));
+ if (draggedDocs.length) {
+ const moddrag: Doc[] = [];
+ for (const draggedDoc of draggedDocs) {
+ const doc = await Cast(draggedDoc.annotationOn, Doc);
+ if (doc) moddrag.push(doc);
+ }
+
+ const dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs);
+ dragData.moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (doc: Doc) => boolean): boolean => {
+ const document = SelectionManager.SelectedDocuments()[0];
+ document && document.props.removeDocument && document.props.removeDocument(doc);
+ addDocument(doc);
+ return true;
+ };
+ const containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined;
+ const finishDrag = (e: DragCompleteEvent) =>
+ e.docDragData && (e.docDragData.droppedDocuments =
+ dragData.draggedDocuments.reduce((droppedDocs, d) => {
+ const dvs = DocumentManager.Instance.getDocumentViews(d).filter(dv => dv.props.ContainingCollectionView === containingView);
+ if (dvs.length) {
+ dvs.forEach(dv => droppedDocs.push(dv.props.Document));
} else {
droppedDocs.push(Doc.MakeAlias(d));
}
- } else {
- droppedDocs.push(Doc.MakeAlias(d));
- }
- return droppedDocs;
- }, []);
- dropData.droppedDocuments = droppedDocuments;
- });
- }
+ return droppedDocs;
+ }, [] as Doc[]));
- export function StartAnnotationDrag(eles: HTMLElement[], dragData: AnnotationDragData, downX: number, downY: number, options?: DragOptions) {
- StartDrag(eles, dragData, downX, downY, options);
- }
-
- export class LinkDragData {
- constructor(linkSourceDoc: Doc, blacklist: Doc[] = []) {
- this.linkSourceDocument = linkSourceDoc;
- this.blacklist = blacklist;
+ StartDrag([dragEle], dragData, downX, downY, undefined, finishDrag);
}
- droppedDocuments: Doc[] = [];
- linkSourceDocument: Doc;
- blacklist: Doc[];
- dontClearTextBox?: boolean;
- [id: string]: any;
}
- // for column dragging in schema view
- export class ColumnDragData {
- constructor(colKey: SchemaHeaderField) {
- this.colKey = colKey;
- }
- colKey: SchemaHeaderField;
- [id: string]: any;
+ // drag&drop the pdf annotation anchor which will create a text note on drop via a dropCompleted() DragOption
+ export function StartPdfAnnoDrag(eles: HTMLElement[], dragData: PdfAnnoDragData, downX: number, downY: number, options?: DragOptions) {
+ StartDrag(eles, dragData, downX, downY, options);
}
- export function StartLinkDrag(ele: HTMLElement, dragData: LinkDragData, downX: number, downY: number, options?: DragOptions) {
- StartDrag([ele], dragData, downX, downY, options);
+ // drags a linker button and creates a link on drop
+ export function StartLinkDrag(ele: HTMLElement, sourceDoc: Doc, downX: number, downY: number, options?: DragOptions) {
+ StartDrag([ele], new DragManager.LinkDragData(sourceDoc), downX, downY, options);
}
+ // drags a column from a schema view
export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?: DragOptions) {
StartDrag([ele], dragData, downX, downY, options);
}
- export let AbortDrag: () => void = emptyFunction;
-
- function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
+ function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
eles = eles.filter(e => e);
if (!dragDiv) {
dragDiv = document.createElement("div");
@@ -336,80 +274,64 @@ export namespace DragManager {
DragManager.Root().appendChild(dragDiv);
}
SelectionManager.SetIsDragging(true);
- let scaleXs: number[] = [];
- let scaleYs: number[] = [];
- let xs: number[] = [];
- let ys: number[] = [];
-
- const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments :
- dragData instanceof AnnotationDragData ? [dragData.dragDocument] : [];
- let dragElements = eles.map(ele => {
- const w = ele.offsetWidth,
- h = ele.offsetHeight;
+ const scaleXs: number[] = [];
+ const scaleYs: number[] = [];
+ const xs: number[] = [];
+ const ys: number[] = [];
+
+ const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof PdfAnnoDragData ? [dragData.dragDocument] : [];
+ const dragElements = eles.map(ele => {
+ if (!ele.parentNode) dragDiv.appendChild(ele);
+ const dragElement = ele.parentNode === dragDiv ? ele : ele.cloneNode(true) as HTMLElement;
const rect = ele.getBoundingClientRect();
- const scaleX = rect.width / w,
- scaleY = rect.height / h;
- let x = rect.left,
- y = rect.top;
- xs.push(x);
- ys.push(y);
+ const scaleX = rect.width / ele.offsetWidth,
+ scaleY = rect.height / ele.offsetHeight;
+ xs.push(rect.left);
+ ys.push(rect.top);
scaleXs.push(scaleX);
scaleYs.push(scaleY);
- let dragElement = ele.cloneNode(true) as HTMLElement;
dragElement.style.opacity = "0.7";
- dragElement.style.borderRadius = getComputedStyle(ele).borderRadius;
dragElement.style.position = "absolute";
dragElement.style.margin = "0";
dragElement.style.top = "0";
dragElement.style.bottom = "";
dragElement.style.left = "0";
- dragElement.style.transition = "none";
dragElement.style.color = "black";
+ dragElement.style.transition = "none";
dragElement.style.transformOrigin = "0 0";
+ dragElement.style.borderRadius = getComputedStyle(ele).borderRadius;
dragElement.style.zIndex = globalCssVariables.contextMenuZindex;// "1000";
- dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`;
+ dragElement.style.transform = `translate(${rect.left + (options?.offsetX || 0)}px, ${rect.top + (options?.offsetY || 0)}px) scale(${scaleX}, ${scaleY})`;
dragElement.style.width = `${rect.width / scaleX}px`;
dragElement.style.height = `${rect.height / scaleY}px`;
if (docs.length) {
- var pdfBox = dragElement.getElementsByTagName("canvas");
- var pdfBoxSrc = ele.getElementsByTagName("canvas");
+ const pdfBox = dragElement.getElementsByTagName("canvas");
+ const pdfBoxSrc = ele.getElementsByTagName("canvas");
Array.from(pdfBox).map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0));
- var pdfView = dragElement.getElementsByClassName("pdfViewer-viewer");
- var pdfViewSrc = ele.getElementsByClassName("pdfViewer-viewer");
- let tops = Array.from(pdfViewSrc).map(p => p.scrollTop);
- let oldopacity = dragElement.style.opacity;
+ const pdfView = dragElement.getElementsByClassName("pdfViewer-viewer");
+ const pdfViewSrc = ele.getElementsByClassName("pdfViewer-viewer");
+ const tops = Array.from(pdfViewSrc).map(p => p.scrollTop);
+ const oldopacity = dragElement.style.opacity;
dragElement.style.opacity = "0";
setTimeout(() => {
dragElement.style.opacity = oldopacity;
Array.from(pdfView).map((v, i) => v.scrollTo({ top: tops[i] }));
}, 0);
}
- let set = dragElement.getElementsByTagName('*');
if (dragElement.hasAttribute("style")) (dragElement as any).style.pointerEvents = "none";
+ const set = dragElement.getElementsByTagName('*');
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < set.length; i++) {
- if (set[i].hasAttribute("style")) {
- let s = set[i];
- (s as any).style.pointerEvents = "none";
- }
+ set[i].hasAttribute("style") && ((set[i] as any).style.pointerEvents = "none");
}
-
dragDiv.appendChild(dragElement);
return dragElement;
});
- let hideSource = false;
- if (options) {
- if (typeof options.hideSource === "boolean") {
- hideSource = options.hideSource;
- } else {
- hideSource = options.hideSource();
- }
- }
-
- eles.map(ele => ele.hidden = hideSource);
+ const hideSource = options?.hideSource ? true : false;
+ eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.parentElement.hidden = hideSource) : (ele.hidden = hideSource));
let lastX = downX;
let lastY = downY;
@@ -418,9 +340,9 @@ export namespace DragManager {
if (dragData instanceof DocumentDragData) {
dragData.userDropAction = e.ctrlKey ? "alias" : undefined;
}
- if (((options && !options.withoutShiftDrag) || !options) && e.shiftKey && CollectionDockingView.Instance) {
+ if (e.shiftKey && CollectionDockingView.Instance) {
AbortDrag();
- finishDrag && finishDrag(dragData);
+ finishDrag?.(new DragCompleteEvent(true, dragData));
CollectionDockingView.Instance.StartOtherDrag({
pageX: e.pageX,
pageY: e.pageY,
@@ -429,61 +351,56 @@ export namespace DragManager {
}, dragData.droppedDocuments);
}
//TODO: Why can't we use e.movementX and e.movementY?
- let moveX = e.pageX - lastX;
- let moveY = e.pageY - lastY;
+ const moveX = e.pageX - lastX;
+ const moveY = e.pageY - lastY;
lastX = e.pageX;
lastY = e.pageY;
dragElements.map((dragElement, i) => (dragElement.style.transform =
- `translate(${(xs[i] += moveX) + (options ? (options.offsetX || 0) : 0)}px, ${(ys[i] += moveY) + (options ? (options.offsetY || 0) : 0)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`)
+ `translate(${(xs[i] += moveX) + (options?.offsetX || 0)}px, ${(ys[i] += moveY) + (options?.offsetY || 0)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`)
);
};
- let hideDragShowOriginalElements = () => {
+ const hideDragShowOriginalElements = () => {
dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
- eles.map(ele => ele.hidden = false);
+ eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.parentElement.hidden = false) : (ele.hidden = false));
};
- let endDrag = () => {
+ const endDrag = () => {
document.removeEventListener("pointermove", moveHandler, true);
document.removeEventListener("pointerup", upHandler);
- if (options) {
- options.handlers.dragComplete({});
- }
};
AbortDrag = () => {
hideDragShowOriginalElements();
SelectionManager.SetIsDragging(false);
+ options?.dragComplete?.(new DragCompleteEvent(true, dragData));
endDrag();
};
const upHandler = (e: PointerEvent) => {
hideDragShowOriginalElements();
dispatchDrag(eles, e, dragData, options, finishDrag);
SelectionManager.SetIsDragging(false);
+ options?.dragComplete?.(new DragCompleteEvent(false, dragData));
endDrag();
};
document.addEventListener("pointermove", moveHandler, true);
document.addEventListener("pointerup", upHandler);
}
- function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
- let removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
- // let parent = dragEle.parentElement;
- // if (parent) parent.removeChild(dragEle);
- let ret = [dragEle, dragEle.style.width, dragEle.style.height];
+ function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (e: DragCompleteEvent) => void) {
+ const removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
+ const ret = { ele: dragEle, w: dragEle.style.width, h: dragEle.style.height };
dragEle.style.width = "0";
dragEle.style.height = "0";
return ret;
});
const target = document.elementFromPoint(e.x, e.y);
removed.map(r => {
- let dragEle = r[0] as HTMLElement;
- dragEle.style.width = r[1] as string;
- dragEle.style.height = r[2] as string;
- // let parent = r[1];
- // if (parent && dragEle) parent.appendChild(dragEle);
+ r.ele.style.width = r.w;
+ r.ele.style.height = r.h;
});
if (target) {
- finishDrag && finishDrag(dragData);
+ const complete = new DragCompleteEvent(false, dragData);
+ finishDrag?.(complete);
target.dispatchEvent(
new CustomEvent<DropEvent>("dashOnDrop", {
@@ -491,8 +408,10 @@ export namespace DragManager {
detail: {
x: e.x,
y: e.y,
- data: dragData,
- mods: e.altKey ? "AltKey" : e.ctrlKey ? "CtrlKey" : e.metaKey ? "MetaKey" : ""
+ complete: complete,
+ altKey: e.altKey,
+ metaKey: e.metaKey,
+ ctrlKey: e.ctrlKey
}
})
);