aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/DocumentManager.ts7
-rw-r--r--src/client/util/DragManager.ts5
-rw-r--r--src/client/util/DropConverter.ts14
-rw-r--r--src/client/util/Import & Export/DirectoryImportBox.tsx2
-rw-r--r--src/client/util/Import & Export/ImageUtils.ts2
-rw-r--r--src/client/util/InteractionUtils.tsx22
-rw-r--r--src/client/util/RichTextRules.ts29
-rw-r--r--src/client/util/RichTextSchema.tsx12
-rw-r--r--src/client/util/Scripting.ts4
9 files changed, 62 insertions, 35 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 3d5306841..2d6078cf3 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -148,7 +148,7 @@ export class DocumentManager {
const highlight = () => {
const finalDocView = getFirstDocView(targetDoc);
if (finalDocView) {
- finalDocView.Document.scrollToLinkID = linkId;
+ finalDocView.layoutDoc.scrollToLinkID = linkId;
Doc.linkFollowHighlight(finalDocView.props.Document);
}
};
@@ -219,9 +219,12 @@ export class DocumentManager {
if (linkDoc) {
const target = (doc === linkDoc.anchor1 ? linkDoc.anchor2 : doc === linkDoc.anchor2 ? linkDoc.anchor1 :
(Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) ? linkDoc.anchor2 : linkDoc.anchor1)) as Doc;
+ const targetTimecode = (doc === linkDoc.anchor1 ? Cast(linkDoc.anchor2_timecode, "number") :
+ doc === linkDoc.anchor2 ? Cast(linkDoc.anchor1_timecode, "number"):
+ (Doc.AreProtosEqual(doc, linkDoc.anchor1 as Doc) ? Cast(linkDoc.anchor2_timecode, "number"):Cast(linkDoc.anchor1_timecode, "number")));
if (target) {
const containerDoc = (await Cast(target.annotationOn, Doc)) || target;
- containerDoc.currentTimecode !== undefined && (containerDoc.currentTimecode = NumCast(target?.timecode));
+ containerDoc.currentTimecode = targetTimecode;
const targetContext = await target?.context as Doc;
const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined;
DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc[Id], undefined, doc, finished);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index c856bbb1e..3e9a5b63a 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -220,9 +220,9 @@ export namespace DragManager {
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) {
const finishDrag = (e: DragCompleteEvent) => {
const bd = Docs.Create.ButtonDocument({ _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) });
- params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
+ params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc))); // copy all "captured" arguments into document parameterfields
initialize?.(bd);
- bd.buttonParams = new List<string>(params);
+ Doc.GetProto(bd)["onClick-paramFieldKeys"] = new List<string>(params);
e.docDragData && (e.docDragData.droppedDocuments = [bd]);
};
StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag);
@@ -419,7 +419,6 @@ export namespace DragManager {
if (target) {
const complete = new DragCompleteEvent(false, dragData);
finishDrag?.(complete);
- console.log(complete.aborted);
target.dispatchEvent(
new CustomEvent<DropEvent>("dashOnDrop", {
bubbles: true,
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index d572e64a6..60a6bbb3c 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -35,8 +35,14 @@ export function makeTemplate(doc: Doc, first: boolean = true, rename: Opt<string
any = makeTemplate(d, false) || any;
}
});
- if (!docs.length && first) {
- any = Doc.MakeMetadataFieldTemplate(doc, Doc.GetProto(layoutDoc)) || any;
+ if (first) {
+ if (docs.length) { // bcz: feels hacky : if the root level document has items, it's not a field template, but we still want its caption to be a textTemplate
+ if (doc.caption instanceof RichTextField && !doc.caption.Empty()) {
+ doc["caption-textTemplate"] = ComputedField.MakeFunction(`copyField(this.caption)`);
+ }
+ } else {
+ any = Doc.MakeMetadataFieldTemplate(doc, Doc.GetProto(layoutDoc)) || any;
+ }
}
if (layoutDoc[fieldKey] instanceof RichTextField || layoutDoc[fieldKey] instanceof ImageField) {
if (!StrCast(layoutDoc.title).startsWith("-")) {
@@ -52,10 +58,8 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
// bcz: isButtonBar is intended to allow a collection of linear buttons to be dropped and nested into another collection of buttons... it's not being used yet, and isn't very elegant
if (!doc.onDragStart && !doc.isButtonBar) {
const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
- if (layoutDoc.type === DocumentType.COL || layoutDoc.type === DocumentType.RTF || layoutDoc.type === DocumentType.IMG) {
+ if (layoutDoc.type !== DocumentType.FONTICON) {
!layoutDoc.isTemplateDoc && makeTemplate(layoutDoc);
- } else {
- (layoutDoc.layout instanceof Doc) && !data.userDropAction;
}
layoutDoc.isTemplateDoc = true;
dbox = Docs.Create.FontIconDocument({
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 3d8bcbab7..438904688 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx
@@ -126,7 +126,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
const document = await Docs.Get.DocumentFromType(type, path, { _width: 300, title: name });
const { data, error } = exifData;
if (document) {
- Doc.GetProto(document).exif = error || Docs.Get.DocumentHierarchyFromJson(data);
+ Doc.GetProto(document).exif = error || Docs.Get.FromJson({ data });
docs.push(document);
}
}));
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index ab8c73d15..9fae5ff93 100644
--- a/src/client/util/Import & Export/ImageUtils.ts
+++ b/src/client/util/Import & Export/ImageUtils.ts
@@ -20,7 +20,7 @@ export namespace ImageUtils {
nativeHeight,
exifData: { error, data }
} = await Networking.PostToServer("/inspectImage", { source });
- document.exif = error || Docs.Get.DocumentHierarchyFromJson(data);
+ document.exif = error || Docs.Get.FromJson({ data });
const proto = Doc.GetProto(document);
proto["data-nativeWidth"] = nativeWidth;
proto["data-nativeHeight"] = nativeHeight;
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index f2d569cf3..b1f136430 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -13,7 +13,6 @@ export namespace InteractionUtils {
export class MultiTouchEvent<T extends React.TouchEvent | TouchEvent> {
constructor(
readonly fingers: number,
- // readonly points: T extends React.TouchEvent ? React.TouchList : TouchList,
readonly targetTouches: T extends React.TouchEvent ? React.Touch[] : Touch[],
readonly touches: T extends React.TouchEvent ? React.Touch[] : Touch[],
readonly changedTouches: T extends React.TouchEvent ? React.Touch[] : Touch[],
@@ -23,6 +22,11 @@ export namespace InteractionUtils {
export interface MultiTouchEventDisposer { (): void; }
+ /**
+ *
+ * @param element - element to turn into a touch target
+ * @param startFunc - event handler, typically Touchable.onTouchStart (classes that inherit touchable can pass in this.onTouchStart)
+ */
export function MakeMultiTouchTarget(
element: HTMLElement,
startFunc: (e: Event, me: MultiTouchEvent<React.TouchEvent>) => void
@@ -48,6 +52,11 @@ export namespace InteractionUtils {
};
}
+ /**
+ * Turns an element onto a target for touch hold handling.
+ * @param element - element to add events to
+ * @param func - function to add to the event
+ */
export function MakeHoldTouchTarget(
element: HTMLElement,
func: (e: Event, me: MultiTouchEvent<React.TouchEvent>) => void
@@ -78,7 +87,6 @@ export namespace InteractionUtils {
return myTouches;
}
- // TODO: find a way to reference this function from InkingStroke instead of copy pastign here. copied bc of weird error when on mobile view
export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: number) {
const pts = points.reduce((acc: string, pt: { X: number, Y: number }) => acc + `${pt.X - left},${pt.Y - top} `, "");
return (
@@ -93,6 +101,11 @@ export namespace InteractionUtils {
);
}
+ /**
+ * Returns whether or not the pointer event passed in is of the type passed in
+ * @param e - pointer event. this event could be from a mouse, a pen, or a finger
+ * @param type - InteractionUtils.(PENTYPE | ERASERTYPE | MOUSETYPE | TOUCHTYPE)
+ */
export function IsType(e: PointerEvent | React.PointerEvent, type: string): boolean {
switch (type) {
// pen and eraser are both pointer type 'pen', but pen is button 0 and eraser is button 5. -syip2
@@ -105,6 +118,11 @@ export namespace InteractionUtils {
}
}
+ /**
+ * Returns euclidean distance between two points
+ * @param pt1
+ * @param pt2
+ */
export function TwoPointEuclidist(pt1: React.Touch, pt2: React.Touch): number {
return Math.sqrt(Math.pow(pt1.clientX - pt2.clientX, 2) + Math.pow(pt1.clientY - pt2.clientY, 2));
}
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index b0a124cb8..6bbe81115 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -62,6 +62,17 @@ export class RichTextRules {
// ``` code block
textblockTypeInputRule(/^```$/, schema.nodes.code_block),
+ // create an inline view of a tag stored under the '#' field
+ new InputRule(
+ new RegExp(/#([a-zA-Z_\-]+[a-zA-Z_\-0-9]*)\s$/),
+ (state, match, start, end) => {
+ const tag = match[1];
+ if (!tag) return state.tr;
+ this.Document[DataSym]["#"] = tag;
+ const fieldView = state.schema.nodes.dashField.create({ fieldKey: "#" });
+ return state.tr.deleteRange(start, end).insert(start, fieldView);
+ }),
+
// # heading
textblockTypeInputRule(
new RegExp(/^(#{1,6})\s$/),
@@ -81,7 +92,7 @@ export class RichTextRules {
// create a text display of a metadata field on this or another document, or create a hyperlink portal to another document [[ <fieldKey> : <Doc>]] // [[:Doc]] => hyperlink [[fieldKey]] => show field [[fieldKey:Doc]] => show field of doc
new InputRule(
- new RegExp(/\[\[([a-zA-Z_#@\? \-0-9]*)(=[a-zA-Z_#@\? \-0-9]*)?(:[a-zA-Z_#@\? \-0-9]+)?\]\]$/),
+ new RegExp(/\[\[([a-zA-Z_@\? \-0-9]*)(=[a-zA-Z_@\? \-0-9]*)?(:[a-zA-Z_@\? \-0-9]+)?\]\]$/),
(state, match, start, end) => {
const fieldKey = match[1];
const docid = match[3]?.substring(1);
@@ -104,16 +115,6 @@ export class RichTextRules {
const fieldView = state.schema.nodes.dashField.create({ fieldKey, docid });
return state.tr.deleteRange(start, end).insert(start, fieldView);
}),
- // create an inline view of a tag stored under the '#' field
- new InputRule(
- new RegExp(/#([a-zA-Z_\-0-9]+)\s$/),
- (state, match, start, end) => {
- const tag = match[1];
- if (!tag) return state.tr;
- this.Document[DataSym]["#"] = tag;
- const fieldView = state.schema.nodes.dashField.create({ fieldKey: "#" });
- return state.tr.deleteRange(start, end).insert(start, fieldView);
- }),
// create an inline view of a document {{ <layoutKey> : <Doc> }} // {{:Doc}} => show default view of document {{<layout>}} => show layout for this doc {{<layout> : Doc}} => show layout for another doc
new InputRule(
new RegExp(/\{\{([a-zA-Z_ \-0-9]*)(\([a-zA-Z0-9…._\-]*\))?(:[a-zA-Z_ \-0-9]+)?\}\}$/),
@@ -129,12 +130,12 @@ export class RichTextRules {
}
});
const node = (state.doc.resolve(start) as any).nodeAfter;
- const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: "dashDoc", docid, fieldKey: fieldKey + fieldParam, float: "right", alias: Utils.GenerateGuid() });
+ const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: "dashDoc", docid, fieldKey: fieldKey + fieldParam, float: "unset", alias: Utils.GenerateGuid() });
const sm = state.storedMarks || undefined;
return node ? state.tr.replaceRangeWith(start, end, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
}),
new InputRule(
- new RegExp(/##$/),
+ new RegExp(/>>$/),
(state, match, start, end) => {
const textDoc = this.Document[DataSym];
const numInlines = NumCast(textDoc.inlineTextCount);
@@ -146,7 +147,7 @@ export class RichTextRules {
textDocInline.customTitle = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc
textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point
textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]]
- textDocInline._textContext = ComputedField.MakeFunction(`copyField(this.${inlineFieldKey})`, { this: Doc.name });
+ textDocInline._textContext = ComputedField.MakeFunction(`copyField(self.${inlineFieldKey})`);
textDoc[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text
textDoc[inlineFieldKey] = ""; // set a default value for the annotation
const node = (state.doc.resolve(start) as any).nodeAfter;
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index de2707d36..0599b3ebe 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -27,8 +27,12 @@ import ParagraphNodeSpec from "./ParagraphNodeSpec";
import { Transform } from "./Transform";
import React = require("react");
-const blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
- preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0];
+const
+ blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0],
+ hrDOM: DOMOutputSpecArray = ["hr"],
+ preDOM: DOMOutputSpecArray = ["pre", ["code", 0]],
+ brDOM: DOMOutputSpecArray = ["br"],
+ ulDOM: DOMOutputSpecArray = ["ul", 0];
// :: Object
// [Specs](#model.NodeSpec) for the nodes defined in this schema.
@@ -738,7 +742,7 @@ export class DashDocView {
this._outer = document.createElement("span");
this._outer.style.position = "relative";
this._outer.style.textIndent = "0";
- this._outer.style.border = "1px solid " + StrCast(tbox.Document.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray"));
+ this._outer.style.border = "1px solid " + StrCast(tbox.layoutDoc.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray"));
this._outer.style.width = node.attrs.width;
this._outer.style.height = node.attrs.height;
this._outer.style.display = node.attrs.hidden ? "none" : "inline-block";
@@ -959,8 +963,6 @@ export class DashFieldView {
if (self._options?.length && !self._dashDoc[self._fieldKey]) {
self._dashDoc[self._fieldKey] = StrCast(self._options[0].title);
}
- // NOTE: if the field key starts with "@", then the actual field key is stored in the field 'fieldKey' (removing the @).
- self._fieldKey = self._fieldKey.startsWith("@") ? StrCast(tbox.props.Document[StrCast(self._fieldKey).substring(1)]) : self._fieldKey;
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";
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 57d22eaf8..12628273b 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -41,9 +41,9 @@ export interface CompileError {
export type CompileResult = CompiledScript | CompileError;
export function isCompileError(toBeDetermined: CompileResult): toBeDetermined is CompileError {
if ((toBeDetermined as CompileError).errors) {
- return true
+ return true;
}
- return false
+ return false;
}
export namespace Scripting {