diff options
Diffstat (limited to 'src/client/util')
-rw-r--r-- | src/client/util/DragManager.ts | 38 | ||||
-rw-r--r-- | src/client/util/ProsemirrorExampleTransfer.ts | 18 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 23 |
3 files changed, 60 insertions, 19 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 42a78a4bf..35694a6bd 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,5 +1,5 @@ import { Doc, Field, DocListCast } from "../../new_fields/Doc"; -import { Cast, ScriptCast } from "../../new_fields/Types"; +import { Cast, ScriptCast, StrCast } from "../../new_fields/Types"; import { emptyFunction } from "../../Utils"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import * as globalCssVariables from "../views/globalCssVariables.scss"; @@ -83,6 +83,7 @@ export namespace DragManager { } export let AbortDrag: () => void = emptyFunction; export type MoveFunction = (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean; + export type RemoveFunction = (document: Doc) => boolean; export interface DragDropDisposer { (): void; } export interface DragOptions { @@ -138,6 +139,7 @@ export namespace DragManager { userDropAction: dropActionType; embedDoc?: boolean; moveDocument?: MoveFunction; + removeDocument?: RemoveFunction; isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts } export class LinkDragData { @@ -177,7 +179,8 @@ export namespace DragManager { export function MakeDropTarget( element: HTMLElement, - dropFunc: (e: Event, de: DropEvent) => void + dropFunc: (e: Event, de: DropEvent) => void, + doc?: Doc ): DragDropDisposer { if ("canDrop" in element.dataset) { throw new Error( @@ -185,10 +188,18 @@ export namespace DragManager { ); } element.dataset.canDrop = "true"; - const handler = (e: Event) => { dropFunc(e, (e as CustomEvent<DropEvent>).detail); }; + const handler = (e: Event) => dropFunc(e, (e as CustomEvent<DropEvent>).detail); + const preDropHandler = (e: Event) => { + const de = (e as CustomEvent<DropEvent>).detail; + if (de.complete.docDragData && doc?.targetDropAction) { + de.complete.docDragData.dropAction = StrCast(doc.targetDropAction) as dropActionType; + } + }; element.addEventListener("dashOnDrop", handler); + doc && element.addEventListener("dashPreDrop", preDropHandler); return () => { element.removeEventListener("dashOnDrop", handler); + doc && element.removeEventListener("dashPreDrop", preDropHandler); delete element.dataset.canDrop; }; } @@ -351,12 +362,17 @@ export namespace DragManager { let lastX = downX; let lastY = downY; + let alias = "alias"; const moveHandler = (e: PointerEvent) => { e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : undefined; } if (e.shiftKey && CollectionDockingView.Instance && dragData.droppedDocuments.length === 1) { + !dragData.dropAction && (dragData.dropAction = alias); + if (dragData.dropAction === "move") { + dragData.removeDocument?.(dragData.draggedDocuments[0]); + } AbortDrag(); finishDrag?.(new DragCompleteEvent(true, dragData)); CollectionDockingView.Instance.StartOtherDrag({ @@ -366,7 +382,7 @@ export namespace DragManager { button: 0 }, dragData.droppedDocuments); } - //TODO: Why can't we use e.movementX and e.movementY? + alias = "move"; const moveX = e.pageX - lastX; const moveY = e.pageY - lastY; lastX = e.pageX; @@ -418,6 +434,20 @@ export namespace DragManager { }); if (target) { const complete = new DragCompleteEvent(false, dragData); + target.dispatchEvent( + new CustomEvent<DropEvent>("dashPreDrop", { + bubbles: true, + detail: { + x: e.x, + y: e.y, + complete: complete, + shiftKey: e.shiftKey, + altKey: e.altKey, + metaKey: e.metaKey, + ctrlKey: e.ctrlKey + } + }) + ); finishDrag?.(complete); target.dispatchEvent( new CustomEvent<DropEvent>("dashOnDrop", { diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 680f48f70..356f20ce6 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -7,7 +7,7 @@ import { splitListItem, wrapInList, } from "prosemirror-schema-list"; import { EditorState, Transaction, TextSelection } from "prosemirror-state"; import { SelectionManager } from "./SelectionManager"; import { Docs } from "../documents/Documents"; -import { NumCast, BoolCast, Cast } from "../../new_fields/Types"; +import { NumCast, BoolCast, Cast, StrCast } from "../../new_fields/Types"; import { Doc } from "../../new_fields/Doc"; import { FormattedTextBox } from "../views/nodes/FormattedTextBox"; import { Id } from "../../new_fields/FieldSymbols"; @@ -153,10 +153,16 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (originalDoc instanceof Doc) { + const layoutKey = StrCast(originalDoc.layoutKey); const newDoc = Docs.Create.TextDocument("", { - layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, _singleLine: BoolCast(originalDoc._singleLine), + layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, + layoutKey, + _singleLine: BoolCast(originalDoc._singleLine), x: NumCast(originalDoc.x), y: NumCast(originalDoc.y) + NumCast(originalDoc._height) + 10, _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height) }); + if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) { + newDoc[layoutKey] = originalDoc[layoutKey]; + } FormattedTextBox.SelectOnLoad = newDoc[Id]; props.addDocument(newDoc); } @@ -171,10 +177,16 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (force || props.Document._singleLine) { + const layoutKey = StrCast(originalDoc.layoutKey); const newDoc = Docs.Create.TextDocument("", { - layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, _singleLine: BoolCast(originalDoc._singleLine), + layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, + layoutKey, + _singleLine: BoolCast(originalDoc._singleLine), x: NumCast(originalDoc.x) + NumCast(originalDoc._width) + 10, y: NumCast(originalDoc.y), _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height) }); + if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) { + newDoc[layoutKey] = originalDoc[layoutKey]; + } FormattedTextBox.SelectOnLoad = newDoc[Id]; props.addDocument(newDoc); return true; diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index d23962d5c..8882cdc8e 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -15,7 +15,7 @@ import { ObjectField } from "../../new_fields/ObjectField"; import { listSpec } from "../../new_fields/Schema"; import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField"; import { ComputedField } from "../../new_fields/ScriptField"; -import { BoolCast, Cast, NumCast, StrCast } from "../../new_fields/Types"; +import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../new_fields/Types"; import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../Utils"; import { DocServer } from "../DocServer"; import { Docs } from "../documents/Documents"; @@ -780,7 +780,7 @@ export class DashDocView { if (dashDocBase instanceof Doc) { const aliasedDoc = Doc.MakeAlias(dashDocBase, docid + alias); aliasedDoc.layoutKey = "layout"; - node.attrs.fieldKey && DocumentView.makeCustomViewClicked(aliasedDoc, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); + node.attrs.fieldKey && Doc.makeCustomViewClicked(aliasedDoc, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); self.doRender(aliasedDoc, removeDoc, node, view, getPos); } }); @@ -879,7 +879,7 @@ export class DashDocView { export class DashFieldView { _fieldWrapper: HTMLDivElement; // container for label and value _labelSpan: HTMLSpanElement; // field label - _fieldSpan: HTMLDivElement; // field value + _fieldSpan: HTMLSpanElement; // field value _fieldCheck: HTMLInputElement; _enumerables: HTMLDivElement; // field value _reactionDisposer: IReactionDisposer | undefined; @@ -891,11 +891,12 @@ export class DashFieldView { constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { this._fieldKey = node.attrs.fieldKey; this._textBoxDoc = tbox.props.Document; - this._fieldWrapper = document.createElement("div"); + this._fieldWrapper = document.createElement("p"); this._fieldWrapper.style.width = node.attrs.width; this._fieldWrapper.style.height = node.attrs.height; + this._fieldWrapper.style.fontWeight = "bold"; this._fieldWrapper.style.position = "relative"; - this._fieldWrapper.style.display = "inline-flex"; + this._fieldWrapper.style.display = "inline-block"; const self = this; this._enumerables = document.createElement("div"); @@ -903,7 +904,6 @@ export class DashFieldView { this._enumerables.style.height = "10px"; this._enumerables.style.position = "relative"; this._enumerables.style.display = "none"; - this._enumerables.style.background = "dimGray"; this._enumerables.onpointerdown = async (e) => { e.stopPropagation(); @@ -946,13 +946,13 @@ export class DashFieldView { self._dashDoc![self._fieldKey] = e.target.checked; }; - this._fieldSpan = document.createElement("div"); + this._fieldSpan = document.createElement("span"); this._fieldSpan.id = Utils.GenerateGuid(); this._fieldSpan.contentEditable = "true"; this._fieldSpan.style.position = "relative"; this._fieldSpan.style.display = "none"; this._fieldSpan.style.minWidth = "12px"; - this._fieldSpan.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; + this._fieldSpan.style.fontSize = "large"; this._fieldSpan.onkeypress = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onkeyup = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onmousedown = function (e: any) { e.stopPropagation(); self._enumerables.style.display = "inline-block"; }; @@ -966,7 +966,7 @@ export class DashFieldView { this._labelSpan.innerHTML = `${self._fieldKey}: `; const fieldVal = Cast(this._dashDoc?.[self._fieldKey], "boolean", null); this._fieldCheck.style.display = (fieldVal === true || fieldVal === false) ? "inline-block" : "none"; - this._fieldSpan.style.display = !(fieldVal === true || fieldVal === false) ? "inline-block" : "none"; + this._fieldSpan.style.display = !(fieldVal === true || fieldVal === false) ? StrCast(this._dashDoc?.[self._fieldKey]) ? "" : "inline-block" : "none"; }; this._fieldSpan.onkeydown = function (e: any) { e.stopPropagation(); @@ -987,11 +987,10 @@ export class DashFieldView { }; this._labelSpan = document.createElement("span"); - this._labelSpan.style.backgroundColor = "rgba(155, 155, 155, 0.44)"; this._labelSpan.style.position = "relative"; - this._labelSpan.style.display = "inline-block"; this._labelSpan.style.fontSize = "small"; this._labelSpan.title = "click to see related tags"; + this._labelSpan.style.fontSize = "x-small"; this._labelSpan.onpointerdown = function (e: any) { e.stopPropagation(); let container = tbox.props.ContainingCollectionView; @@ -1029,7 +1028,7 @@ export class DashFieldView { this._fieldSpan.innerHTML = Field.toString(fval as Field) || ""; } this._fieldCheck.style.display = (boolVal === true || boolVal === false) ? "inline-block" : "none"; - this._fieldSpan.style.display = !(boolVal === true || boolVal === false) ? "inline-block" : "none"; + this._fieldSpan.style.display = !(fval === true || fval === false) ? (StrCast(fval) ? "" : "inline-block") : "none"; }, { fireImmediately: true }); this._fieldWrapper.appendChild(this._labelSpan); |