From 8717e90d12c8caa16984f5a55eb8f442dcf5cbab Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Jul 2021 14:31:30 -0400 Subject: fixe MakeClone to handle links properly. fixed cloning richtext to update rich text references to documents properly. fixed dragging to call MakeClone properly. --- src/client/util/DragManager.ts | 12 +++---- src/client/util/LinkManager.ts | 38 ++++++++-------------- src/client/util/Scripting.ts | 2 +- src/client/views/StyleProvider.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 4 +-- .../collectionSchema/CollectionSchemaCells.tsx | 20 ++++++------ src/fields/Doc.ts | 33 ++++++++++++------- 8 files changed, 55 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index ab58f25e9..dd50727dd 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -210,16 +210,16 @@ export namespace DragManager { dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(() => dropDoc); return dropDoc; }; - const finishDrag = (e: DragCompleteEvent) => { + const finishDrag = async (e: DragCompleteEvent) => { const docDragData = e.docDragData; dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails if (docDragData && !docDragData.droppedDocuments.length) { docDragData.dropAction = dragData.userDropAction || dragData.dropAction; docDragData.droppedDocuments = - dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : + await Promise.all(dragData.draggedDocuments.map(async d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result) : docDragData.dropAction === "alias" ? Doc.MakeAlias(d) : docDragData.dropAction === "proto" ? Doc.GetProto(d) : - docDragData.dropAction === "copy" ? Doc.MakeClone(d) : d); + docDragData.dropAction === "copy" ? (await Doc.MakeClone(d)).clone : d)); !["same", "proto"].includes(docDragData.dropAction as any) && docDragData.droppedDocuments.forEach((drop: Doc, i: number) => { const dragProps = Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []); const remProps = (dragData?.removeDropProperties || []).concat(Array.from(dragProps)); @@ -509,7 +509,7 @@ export namespace DragManager { `translate(${(xs[i] += moveVec.x) + (options?.offsetX || 0)}px, ${(ys[i] += moveVec.y) + (options?.offsetY || 0)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`) ); }; - const upHandler = (e: PointerEvent) => { + const upHandler = async (e: PointerEvent) => { dispatchDrag(document.elementFromPoint(e.x, e.y) || document.body, e, new DragCompleteEvent(false, dragData), snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom), finishDrag, options); endDrag(); }; @@ -517,7 +517,7 @@ export namespace DragManager { document.addEventListener("pointerup", upHandler); } - function dispatchDrag(target: Element, e: PointerEvent, complete: DragCompleteEvent, pos: { x: number, y: number }, finishDrag?: (e: DragCompleteEvent) => void, options?: DragOptions) { + async function dispatchDrag(target: Element, e: PointerEvent, complete: DragCompleteEvent, pos: { x: number, y: number }, finishDrag?: (e: DragCompleteEvent) => void, options?: DragOptions) { const dropArgs = { bubbles: true, detail: { @@ -531,7 +531,7 @@ export namespace DragManager { } }; target.dispatchEvent(new CustomEvent("dashPreDrop", dropArgs)); - finishDrag?.(complete); + await finishDrag?.(complete); target.dispatchEvent(new CustomEvent("dashOnDrop", dropArgs)); options?.dragComplete?.(complete); } diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 3c3d5c3b8..08f4ac9b7 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -1,15 +1,14 @@ +import { observable, observe, action } from "mobx"; import { computedFn } from "mobx-utils"; -import { Doc, DocListCast, Opt, DirectLinksSym, Field } from "../../fields/Doc"; -import { BoolCast, Cast, StrCast, PromiseValue } from "../../fields/Types"; +import { DirectLinksSym, Doc, DocListCast, Field, Opt } from "../../fields/Doc"; +import { List } from "../../fields/List"; +import { ProxyField } from "../../fields/Proxy"; +import { BoolCast, Cast, PromiseValue, StrCast } from "../../fields/Types"; import { LightboxView } from "../views/LightboxView"; import { DocumentViewSharedProps, ViewAdjustment } from "../views/nodes/DocumentView"; import { DocumentManager } from "./DocumentManager"; import { SharingManager } from "./SharingManager"; import { UndoManager } from "./UndoManager"; -import { observe, observable, reaction } from "mobx"; -import { listSpec } from "../../fields/Schema"; -import { List } from "../../fields/List"; -import { ProxyField } from "../../fields/Proxy"; type CreateViewFunc = (doc: Doc, followLinkLocation: string, finished?: () => void) => void; /* @@ -34,7 +33,7 @@ export class LinkManager { LinkManager._instance = this; setTimeout(() => { LinkManager.userDocs = [Doc.LinkDBDoc().data as Doc, ...SharingManager.Instance.users.map(user => user.linkDatabase)]; - const addLinkToDoc = (link: Doc): any => { + const addLinkToDoc = action((link: Doc): any => { const a1 = link?.anchor1; const a2 = link?.anchor2; if (a1 instanceof Promise || a2 instanceof Promise) return PromiseValue(a1).then(a1 => PromiseValue(a2).then(a2 => addLinkToDoc(link))); @@ -43,8 +42,8 @@ export class LinkManager { Doc.GetProto(a2)[DirectLinksSym].add(link); Doc.GetProto(link)[DirectLinksSym].add(link); } - }; - const remLinkFromDoc = (link: Doc): any => { + }); + const remLinkFromDoc = action((link: Doc): any => { const a1 = link?.anchor1; const a2 = link?.anchor2; if (a1 instanceof Promise || a2 instanceof Promise) return PromiseValue(a1).then(a1 => PromiseValue(a2).then(a2 => remLinkFromDoc(link))); @@ -53,7 +52,7 @@ export class LinkManager { Doc.GetProto(a2)[DirectLinksSym].delete(link); Doc.GetProto(link)[DirectLinksSym].delete(link); } - }; + }); const watchUserLinks = (userLinks: List) => { const toRealField = (field: Field) => field instanceof ProxyField ? field.value() : field; // see List.ts. data structure is not a simple list of Docs, but a list of ProxyField/Fields observe(userLinks, change => { @@ -75,8 +74,10 @@ export class LinkManager { }); } - public addLink(linkDoc: Doc) { - return Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); + public addLink(linkDoc: Doc, checkExists = false) { + if (!checkExists || !DocListCast(Doc.LinkDBDoc().data).includes(linkDoc)) { + Doc.AddDocToList(Doc.LinkDBDoc(), "data", linkDoc); + } } public deleteLink(linkDoc: Doc) { return Doc.RemoveDocFromList(Doc.LinkDBDoc(), "data", linkDoc); } public deleteAllLinksOnAnchor(anchor: Doc) { LinkManager.Instance.relatedLinker(anchor).forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc)); } @@ -85,19 +86,6 @@ export class LinkManager { public getAllDirectLinks(anchor: Doc): Doc[] { return Array.from(Doc.GetProto(anchor)[DirectLinksSym]); } // finds all links that contain the given anchor - public getAllLinks(): Doc[] { return []; }//this.allLinks(); } - - // allLinks = computedFn(function allLinks(this: any): Doc[] { - // const linkData = Doc.LinkDBDoc().data; - // const lset = new Set(DocListCast(linkData)); - // SharingManager.Instance.users.forEach(user => DocListCast(user.linkDatabase?.data).forEach(doc => lset.add(doc))); - // LinkManager.Instance.allLinks().filter(link => { - // const a1 = Cast(link?.anchor1, Doc, null); - // const a2 = Cast(link?.anchor2, Doc, null); - // return link && ((a1?.author !== undefined && a2?.author !== undefined) || link.author === Doc.CurrentUserEmail) && (Doc.AreProtosEqual(anchor, a1) || Doc.AreProtosEqual(anchor, a2) || Doc.AreProtosEqual(link, anchor)); - // }); - // return Array.from(lset); - // }, true); relatedLinker = computedFn(function relatedLinker(this: any, anchor: Doc): Doc[] { const lfield = Doc.LayoutFieldKey(anchor); diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index c3c3083be..f981f84cd 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -181,7 +181,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an if (batch) { batch.end(); } - onError?.(error); + onError?.(script + " " + error); return { success: false, error, result: errorVal }; } }; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 6b94539c9..32ddc140c 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -101,7 +101,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt 400 || col.alpha() < 0.25) return Colors.DARK_GRAY; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index f39443ae2..a5d27f038 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -454,7 +454,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: if (completed) completed(set); else { if (isFreeformView && generatedDocuments.length > 1) { - addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)!); + addDocument(DocUtils.pileup(generatedDocuments, options.x!, options.y!)); } else { generatedDocuments.forEach(addDocument); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b1f2750c3..1f4fcb2a5 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -368,8 +368,8 @@ export class MarqueeView extends React.Component this.props.removeDocument?.(d)); const newCollection = DocUtils.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2); - this.props.addDocument?.(newCollection!); - this.props.selectDocuments([newCollection!]); + this.props.addDocument?.(newCollection); + this.props.selectDocuments([newCollection]); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); } diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx index 90f64f163..0c434eae5 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx @@ -246,13 +246,13 @@ export class CollectionSchemaCell extends React.Component { } else { // check if the input is a number let inputIsNum = true; - for (let s of value) { - if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) { + for (const s of value) { + if (isNaN(parseInt(s)) && !(s === ".") && !(s === ",")) { inputIsNum = false; } } // check if the input is a boolean - let inputIsBool: boolean = value == "false" || value == "true"; + const inputIsBool: boolean = value === "false" || value === "true"; // what to do in the case if (!inputIsNum && !inputIsBool && !value.startsWith("=")) { // if it's not a number, it's a string, and should be processed as such @@ -263,12 +263,12 @@ export class CollectionSchemaCell extends React.Component { const vsqLength = valueSansQuotes.length; // get rid of outer quotes valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0, - valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength); + valueSansQuotes.charAt(vsqLength - 1) === "\"" ? vsqLength - 1 : vsqLength); } let inputAsString = '"'; // escape any quotes in the string for (const i of valueSansQuotes) { - if (i == '"') { + if (i === '"') { inputAsString += '\\"'; } else { inputAsString += i; @@ -278,7 +278,7 @@ export class CollectionSchemaCell extends React.Component { inputAsString += '"'; //two options here: we can strip off outer quotes or we can figure out what's going on with the script const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length + const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length; script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); // handle numbers and expressions } else if (inputIsNum || value.startsWith("=")) { @@ -286,18 +286,18 @@ export class CollectionSchemaCell extends React.Component { const inputscript = value.substring(value.startsWith("=") ? 1 : 0); // if commas are not stripped, the parser only considers the numbers after the last comma let inputSansCommas = ""; - for (let s of inputscript) { - if (!(s == ",")) { + for (const s of inputscript) { + if (!(s === ",")) { inputSansCommas += s; } } const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = value.length !== value.length || value.length - 2 !== value.length + const changeMade = value.length !== value.length || value.length - 2 !== value.length; script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); // handle booleans } else if (inputIsBool) { const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = value.length !== value.length || value.length - 2 !== value.length + const changeMade = value.length !== value.length || value.length - 2 !== value.length; script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); } } diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 464a8ad05..7993af149 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -516,30 +516,30 @@ export namespace Doc { return alias; } - export async function makeClone(doc: Doc, cloneMap: Map, rtfs: { copy: Doc, key: string, field: RichTextField }[], exclusions: string[], dontCreate: boolean, asBranch: boolean): Promise { + export async function makeClone(doc: Doc, cloneMap: Map, linkMap: Map, rtfs: { copy: Doc, key: string, field: RichTextField }[], exclusions: string[], dontCreate: boolean, asBranch: boolean): Promise { if (Doc.IsBaseProto(doc)) return doc; if (cloneMap.get(doc[Id])) return cloneMap.get(doc[Id])!; const copy = dontCreate ? asBranch ? (Cast(doc.branchMaster, Doc, null) || doc) : doc : new Doc(undefined, true); cloneMap.set(doc[Id], copy); - if (LinkManager.Instance.getAllLinks().includes(doc) && LinkManager.Instance.getAllLinks().indexOf(copy) === -1) LinkManager.Instance.addLink(copy); - const filter = [...exclusions, ...Cast(doc.cloneFieldFilter, listSpec("string"), [])]; - await Promise.all([...Object.keys(doc), "links"].map(async key => { + const fieldExclusions = (doc.type === DocumentType.TEXTANCHOR) ? exclusions.filter(ex => ex !== "annotationOn") : exclusions; + const filter = [...fieldExclusions, ...Cast(doc.cloneFieldFilter, listSpec("string"), [])]; + await Promise.all(Object.keys(doc).map(async key => { if (filter.includes(key)) return; const assignKey = (val: any) => !dontCreate && (copy[key] = val); const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key])); - const field = key === "links" && Doc.IsPrototype(doc) ? doc[key] : ProxyField.WithoutProxy(() => doc[key]); + const field = ProxyField.WithoutProxy(() => doc[key]); const copyObjectField = async (field: ObjectField) => { const list = Cast(doc[key], listSpec(Doc)); const docs = list && (await DocListCastAsync(list))?.filter(d => d instanceof Doc); if (docs !== undefined && docs.length) { - const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, rtfs, exclusions, dontCreate, asBranch))); + const clones = await Promise.all(docs.map(async d => Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch))); !dontCreate && assignKey(new List(clones)); } else if (doc[key] instanceof Doc) { - assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, rtfs, exclusions, dontCreate, asBranch)); // reference documents except copy documents that are expanded teplate fields + assignKey(key.includes("layout[") ? undefined : key.startsWith("layout") ? doc[key] as Doc : await Doc.makeClone(doc[key] as Doc, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch)); // reference documents except copy documents that are expanded teplate fields } else { !dontCreate && assignKey(ObjectField.MakeCopy(field)); if (field instanceof RichTextField) { - if (field.Data.includes('"docid":') || field.Data.includes('"targetId":') || field.Data.includes('"linkId":')) { + if (field.Data.includes('"audioId":') || field.Data.includes('"textId":') || field.Data.includes('"anchorId":')) { rtfs.push({ copy, key, field }); } } @@ -547,14 +547,17 @@ export namespace Doc { }; if (key === "proto") { if (doc[key] instanceof Doc) { - assignKey(await Doc.makeClone(doc[key]!, cloneMap, rtfs, exclusions, dontCreate, asBranch)); + assignKey(await Doc.makeClone(doc[key] as Doc, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch)); + } + } else if (key === "anchor1" || key === "anchor2") { + if (doc[key] instanceof Doc) { + assignKey(await Doc.makeClone(doc[key] as Doc, cloneMap, linkMap, rtfs, exclusions, true, asBranch)); } } else { if (field instanceof RefField) { assignKey(field); } else if (cfield instanceof ComputedField) { !dontCreate && assignKey(ComputedField.MakeFunction(cfield.script.originalScript)); - (key === "links" && field instanceof ObjectField) && await copyObjectField(field); } else if (field instanceof ObjectField) { await copyObjectField(field); } else if (field instanceof Promise) { @@ -564,6 +567,10 @@ export namespace Doc { } } })); + for (const link of Array.from(doc[DirectLinksSym])) { + const linkClone = await Doc.makeClone(link, cloneMap, linkMap, rtfs, exclusions, dontCreate, asBranch); + linkMap.set(link, linkClone); + } if (!dontCreate) { Doc.SetInPlace(copy, "title", (asBranch ? "BRANCH: " : "CLONE: ") + doc.title, true); asBranch ? (copy.branchOf = doc) : (copy.cloneOf = doc); @@ -576,8 +583,10 @@ export namespace Doc { } export async function MakeClone(doc: Doc, dontCreate: boolean = false, asBranch = false) { const cloneMap = new Map(); + const linkMap = new Map(); const rtfMap: { copy: Doc, key: string, field: RichTextField }[] = []; - const copy = await Doc.makeClone(doc, cloneMap, rtfMap, ["context", "annotationOn", "cloneOf", "branches", "branchOf"], dontCreate, asBranch); + const copy = await Doc.makeClone(doc, cloneMap, linkMap, rtfMap, ["context", "annotationOn", "cloneOf", "branches", "branchOf"], dontCreate, asBranch); + Array.from(linkMap.entries()).map((links: Doc[]) => LinkManager.Instance.addLink(links[1], true)); rtfMap.map(({ copy, key, field }) => { const replacer = (match: any, attr: string, id: string, offset: any, string: any) => { const mapped = cloneMap.get(id); @@ -589,7 +598,7 @@ export namespace Doc { }; const regex = `(${Utils.prepend("/doc/")})([^"]*)`; const re = new RegExp(regex, "g"); - copy[key] = new RichTextField(field.Data.replace(/("docid":|"targetId":|"linkId":)"([^"]+)"/g, replacer).replace(re, replacer2), field.Text); + copy[key] = new RichTextField(field.Data.replace(/("textId":|"audioId":|"anchorId":)"([^"]+)"/g, replacer).replace(re, replacer2), field.Text); }); return { clone: copy, map: cloneMap }; } -- cgit v1.2.3-70-g09d2 From 61a0064d7ce862e88792112b3d92f59896f9561f Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Jul 2021 19:43:29 -0400 Subject: from last --- src/client/views/nodes/ImageBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index d876ae818..cfd43bb62 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -340,7 +340,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { this._marqueeing = undefined; - this.props.select(false) + this.props.select(false); } render() { -- cgit v1.2.3-70-g09d2 From b25dac80353e522c74aade90c3df8f01f38de0b7 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 27 Jul 2021 21:02:49 -0400 Subject: from last - fixes shift-dragging to a new tab --- src/client/util/DragManager.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index dd50727dd..c4842e88a 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -427,7 +427,7 @@ export namespace DragManager { SnappingManager.clearSnapLines(); batch.end(); }); - const moveHandler = (e: PointerEvent) => { + const moveHandler = async (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" : dragData.defaultDropAction; @@ -438,7 +438,7 @@ export namespace DragManager { dragData.removeDocument?.(dragData.draggedDocuments[0]); } AbortDrag(); - finishDrag?.(new DragCompleteEvent(true, dragData)); + await finishDrag?.(new DragCompleteEvent(true, dragData)); DragManager.StartWindowDrag?.({ pageX: e.pageX, pageY: e.pageY, -- cgit v1.2.3-70-g09d2 From 795764089a464304be12e5b41dced0045350cc86 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 29 Jul 2021 10:56:37 -0400 Subject: added button to lightbox to create a tab from current document. changed stepInto to first shrinkwrap(), then to step through collection --- src/client/views/LightboxView.scss | 30 +++++++++++++++++++++++++++++- src/client/views/LightboxView.tsx | 22 +++++++++++++++------- 2 files changed, 44 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/views/LightboxView.scss b/src/client/views/LightboxView.scss index 4ea2dc2d6..5d42cd97f 100644 --- a/src/client/views/LightboxView.scss +++ b/src/client/views/LightboxView.scss @@ -1,3 +1,32 @@ + + .lightboxView-navBtn { + margin: auto; + position: absolute; + right: 10; + top: 10; + background: transparent; + border-radius: 8; + color:white; + opacity: 0.7; + width: 35; + &:hover { + opacity: 1; + } + } + .lightboxView-tabBtn { + margin: auto; + position: absolute; + right: 35; + top: 10; + background: transparent; + border-radius: 8; + color:white; + opacity: 0.7; + width: 35; + &:hover { + opacity: 1; + } + } .lightboxView-frame { position: absolute; top: 0; left: 0; @@ -15,7 +44,6 @@ position: relative; background: transparent; border-radius: 8; - color:white; opacity: 0.7; width: 35; &:hover { diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index ce36d9182..88739fe91 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -1,19 +1,20 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, observable, trace } from 'mobx'; +import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import "normalize.css"; import * as React from 'react'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { Cast, NumCast, StrCast } from '../../fields/Types'; -import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue, returnFalse } from '../../Utils'; +import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../Utils'; import { DocUtils } from '../documents/Documents'; import { DocumentManager } from '../util/DocumentManager'; import { LinkManager } from '../util/LinkManager'; import { SelectionManager } from '../util/SelectionManager'; import { Transform } from '../util/Transform'; +import { CollectionDockingView } from './collections/CollectionDockingView'; import { TabDocView } from './collections/TabDocView'; import "./LightboxView.scss"; -import { DocumentView, ViewAdjustment } from './nodes/DocumentView'; +import { DocumentView } from './nodes/DocumentView'; import { DefaultStyleProvider, wavyBorderPath } from './StyleProvider'; interface LightboxViewProps { @@ -160,7 +161,7 @@ export class LightboxView extends React.Component { const { doc, target } = LightboxView._history?.lastElement(); const docView = DocumentManager.Instance.getLightboxDocumentView(target || doc); if (docView) { - LightboxView._docTarget = undefined; + LightboxView._docTarget = target; const focusSpeed = 1000; doc._viewTransition = `transform ${focusSpeed}ms`; if (!target) docView.ComponentView?.shrinkWrap?.(); @@ -197,7 +198,6 @@ export class LightboxView extends React.Component { TabDocView.PinDoc(coll, { hidePresBox: true }); } } - setTimeout(LightboxView.Next); } future = () => LightboxView._future; @@ -228,7 +228,6 @@ export class LightboxView extends React.Component { const targetView = target && DocumentManager.Instance.getLightboxDocumentView(target); if (doc === r.props.Document && (!target || target === doc)) r.ComponentView?.shrinkWrap?.(); else target && targetView?.focus(target, { willZoom: true, scale: 0.9, instant: true }); - LightboxView._docTarget = undefined; })); })} Document={LightboxView.LightboxDoc} @@ -270,7 +269,16 @@ export class LightboxView extends React.Component { LightboxView.Next(); })} -
{ + e.stopPropagation(); + CollectionDockingView.AddSplit(LightboxView._docTarget || LightboxView._doc!, "onRight"); + SelectionManager.DeselectAll(); + LightboxView.SetLightboxDoc(undefined); + }}> + +
+
{ e.stopPropagation(); LightboxView.LightboxDoc!._fitWidth = !LightboxView.LightboxDoc!._fitWidth; }}>
-- cgit v1.2.3-70-g09d2 From 93c06962c18c916518616ab8f53944487e59fc2a Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 29 Jul 2021 12:32:19 -0400 Subject: fixed linking to text in custom text view. --- src/client/views/nodes/DocumentView.scss | 2 +- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 8f86417d6..281f25fb3 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -147,7 +147,7 @@ .documentView-titleWrapper, .documentView-titleWrapper-hover { overflow: hidden; - color: white; + color: gray; transform-origin: top left; top: 0; width: 100%; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 6dd63fb47..8cac21927 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -787,7 +787,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } componentDidMount() { - this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. + !this.props.dontSelectOnLoad && this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. this._cachedLinks = DocListCast(this.Document.links); this._disposers.breakupDictation = reaction(() => DocumentManager.Instance.RecordingEvent, this.breakupDictation); this._disposers.autoHeight = reaction(() => this.autoHeight, autoHeight => autoHeight && this.tryUpdateScrollHeight()); -- cgit v1.2.3-70-g09d2 From a5faca5f510e60ecce125ab59096d4e943352ea5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 29 Jul 2021 17:49:14 -0400 Subject: fixed issues with following links to anchors in PDFs/etc and getting scroll position right. --- src/Utils.ts | 11 ++++++----- src/client/views/MarqueeAnnotator.tsx | 10 ++++++++-- src/client/views/StyleProvider.tsx | 1 + .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 10 +++++----- src/client/views/nodes/WebBox.tsx | 3 ++- src/client/views/pdf/PDFViewer.tsx | 3 ++- 6 files changed, 24 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index ef9c51b8b..d87c3cc6b 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -191,11 +191,12 @@ export namespace Utils { return { h: h, s: s, l: l }; } - export function scrollIntoView(targetY: number, targetHgt: number, scrollTop: number, contextHgt: number) { - if (scrollTop + contextHgt < targetY + targetHgt * 1.1) { - return Math.ceil(targetY + targetHgt * 1.1 - contextHgt); - } else if (scrollTop > targetY - targetHgt * .1) { - return Math.max(0, Math.floor(targetY - targetHgt * .1)); + export function scrollIntoView(targetY: number, targetHgt: number, scrollTop: number, contextHgt: number, minSpacing: number) { + if (scrollTop + contextHgt < targetY + minSpacing + targetHgt) { + return Math.ceil(targetY + minSpacing + targetHgt - contextHgt); + } + if (scrollTop > targetY - minSpacing - targetHgt) { + return Math.max(0, Math.floor(targetY - minSpacing - targetHgt)); } } diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 717bd0768..805cda95c 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -120,9 +120,11 @@ export class MarqueeAnnotator extends React.Component { return marqueeAnno; } - const textRegionAnno = Docs.Create.HTMLAnchorDocument([], { annotationOn: this.props.rootDoc, title: "Selection on " + this.props.rootDoc.title, _width: 1, _height: 1 }); + const textRegionAnno = Docs.Create.HTMLAnchorDocument([], { annotationOn: this.props.rootDoc, backgroundColor: "transparent", title: "Selection on " + this.props.rootDoc.title }); + let minX = Number.MAX_VALUE; let maxX = -Number.MAX_VALUE; let minY = Number.MAX_VALUE; + let maxY = -Number.MIN_VALUE; const annoDocs: Doc[] = []; savedAnnoMap.forEach((value: HTMLDivElement[], key: number) => value.map(anno => { const textRegion = new Doc(); @@ -135,12 +137,16 @@ export class MarqueeAnnotator extends React.Component { annoDocs.push(textRegion); anno.remove(); minY = Math.min(NumCast(textRegion.y), minY); + minX = Math.min(NumCast(textRegion.x), minX); + maxY = Math.max(NumCast(textRegion.y) + NumCast(textRegion._height), maxY); maxX = Math.max(NumCast(textRegion.x) + NumCast(textRegion._width), maxX); })); const textRegionAnnoProto = Doc.GetProto(textRegionAnno); textRegionAnnoProto.y = Math.max(minY, 0); - textRegionAnnoProto.x = Math.max(maxX, 0); + textRegionAnnoProto.x = Math.max(minX, 0); + textRegionAnnoProto.height = Math.max(maxY, 0) - Math.max(minY, 0); + textRegionAnnoProto.width = Math.max(maxX, 0) - Math.max(minX, 0); // mainAnnoDocProto.text = this._selectionText; textRegionAnnoProto.textInlineAnnotations = new List(annoDocs); savedAnnoMap.clear(); diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 32ddc140c..dc6ac0366 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -174,6 +174,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ({ ...this.childDataProvider(doc, ""), ...this.childSizeProvider(doc, "") })); if (measuredDocs.length) { const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) => // computes range of content - ({ - xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) }, - yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) } - }) + xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) }, + yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) } + }) , { xrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE }, yrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE } @@ -1486,7 +1486,7 @@ export class CollectionFreeFormView extends CollectionSubView e.preventDefault()} onContextMenu={this.onContextMenu} style={{ - pointerEvents: this.backgroundEvents ? "all" : this.props.pointerEvents as any, + pointerEvents: this.props.Document.type === DocumentType.HTMLANCHOR ? "none" : this.backgroundEvents ? "all" : this.props.pointerEvents as any, transform: `scale(${this.contentScaling || 1})`, width: `${100 / (this.contentScaling || 1)}%`, height: this.isAnnotationOverlay && this.Document.scrollHeight ? this.Document.scrollHeight : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 88e38712a..c60798c6d 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -162,7 +162,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { if (this._sidebarRef?.current?.makeDocUnfiltered(doc)) return 1; if (doc !== this.rootDoc && this._outerRef.current) { - const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); + const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1); + const scrollTo = doc.type === DocumentType.TEXTANCHOR ? NumCast(doc.y) : Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), windowHeifht, windowHeight * .1); if (scrollTo !== undefined) { const focusSpeed = smooth ? 500 : 0; this._initialScroll !== undefined && (this._initialScroll = scrollTo); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 4a50dccf3..e8c7a4ab0 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -184,7 +184,8 @@ export class PDFViewer extends React.Component { const mainCont = this._mainCont.current; let focusSpeed: Opt; if (doc !== this.props.rootDoc && mainCont && this._pdfViewer) { - const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1)); + const windowHeight = this.props.PanelHeight() / (this.props.scaling?.() || 1); + const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.props.layoutDoc._scrollTop), windowHeight, .1 * windowHeight); if (scrollTo !== undefined) { focusSpeed = 500; -- cgit v1.2.3-70-g09d2 From e950b1828e2331f840b3b25dc9f8cb332ffe0105 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 29 Jul 2021 17:49:48 -0400 Subject: from last --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7fa5fd871..35da09af6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -835,6 +835,7 @@ export class CollectionFreeFormView extends CollectionSubView ({ ...this.childDataProvider(doc, ""), ...this.childSizeProvider(doc, "") })); if (measuredDocs.length) { const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) => // computes range of content + ({ xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) }, yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) } }) @@ -1486,7 +1487,8 @@ export class CollectionFreeFormView extends CollectionSubView e.preventDefault()} onContextMenu={this.onContextMenu} style={{ - pointerEvents: this.props.Document.type === DocumentType.HTMLANCHOR ? "none" : this.backgroundEvents ? "all" : this.props.pointerEvents as any, + pointerEvents: this.props.Document.type === DocumentType.HTMLANCHOR ? "none" : // bcz: ugh.. this is here to prevent htmlanchor's, which render as freeform views, from grabbing events -- need a better approach. + this.backgroundEvents ? "all" : this.props.pointerEvents as any, transform: `scale(${this.contentScaling || 1})`, width: `${100 / (this.contentScaling || 1)}%`, height: this.isAnnotationOverlay && this.Document.scrollHeight ? this.Document.scrollHeight : `${100 / (this.contentScaling || 1)}%`// : this.isAnnotationOverlay ? (this.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() -- cgit v1.2.3-70-g09d2 From 3d4716badd33afe0776da7fdd907a057ac88d698 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 29 Jul 2021 18:49:02 -0400 Subject: fixed navigating to a PDF anchor from sidebar. --- src/client/util/SelectionManager.ts | 3 ++- src/client/views/SidebarAnnos.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 00f0894c7..7aeb19391 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -4,6 +4,7 @@ import { Doc, Opt } from "../../fields/Doc"; import { CollectionSchemaView } from "../views/collections/collectionSchema/CollectionSchemaView"; import { CollectionViewType } from "../views/collections/CollectionView"; import { DocumentView } from "../views/nodes/DocumentView"; +import { DocumentType } from "../documents/DocumentTypes"; export namespace SelectionManager { @@ -22,7 +23,7 @@ export namespace SelectionManager { @action SelectView(docView: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it - if (!manager.SelectedViews.get(docView)) { + if (!manager.SelectedViews.get(docView) && docView.props.Document.type !== DocumentType.HTMLANCHOR) { if (!ctrlPressed) { this.DeselectAll(); } diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 9c5a54574..c5ae82c61 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -79,7 +79,7 @@ export class SidebarAnnos extends React.Component { sidebarStyleProvider = (doc: Opt, props: Opt, property: string) => { if (property === StyleProp.ShowTitle) { - return doc === this.props.rootDoc ? 0 : StrCast(this.props.layoutDoc["sidebar-childShowTitle"], "title"); + return doc === this.props.rootDoc ? undefined : StrCast(this.props.layoutDoc["sidebar-childShowTitle"], "title"); } return this.props.styleProvider?.(doc, props, property); } -- cgit v1.2.3-70-g09d2 From e63ebde5c968f458b4aa8fade0271fbbcaf451c4 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 29 Jul 2021 19:30:16 -0400 Subject: from last --- src/client/views/nodes/WebBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index c60798c6d..abc3a7d7d 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -163,7 +163,7 @@ export class WebBox extends ViewBoxAnnotatableComponent Date: Thu, 29 Jul 2021 20:15:46 -0400 Subject: converted HTMLANCHOR and TEXTANCHOR to MARKER --- src/client/documents/DocumentTypes.ts | 4 +--- src/client/documents/Documents.ts | 14 +++++--------- src/client/util/DocumentManager.ts | 4 ++-- src/client/util/SelectionManager.ts | 2 +- src/client/views/StyleProvider.tsx | 2 +- src/client/views/collections/CollectionTimeView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/WebBox.tsx | 2 +- src/fields/Doc.ts | 2 +- 9 files changed, 14 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 8565784b4..dba7ff907 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -18,7 +18,7 @@ export enum DocumentType { LABEL = "label", // simple text label BUTTON = "button", // onClick button WEBCAM = "webcam", // webcam - HTMLANCHOR = "htmlanchor", // text selection anchor in PDF/Web + MARKER = "marker", // generic marker document not intended to be viewed independently of its context (e.g., for text selections in PDF/Web/RTF) DATE = "date", // calendar view of a date SCRIPTING = "script", // script editor EQUATION = "equation", // equation editor @@ -40,6 +40,4 @@ export enum DocumentType { LINKDB = "linkdb", // database of links ??? why do we have this SCRIPTDB = "scriptdb", // database of scripts GROUPDB = "groupdb", // database of groups - - TEXTANCHOR = "textanchor" // selection of text in a text box } \ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f1db3e32c..e863b4198 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -427,7 +427,7 @@ export namespace Docs { [DocumentType.PRESELEMENT, { layout: { view: PresElementBox, dataField: defaultDataKey } }], - [DocumentType.HTMLANCHOR, { + [DocumentType.MARKER, { layout: { view: CollectionView, dataField: defaultDataKey }, options: { links: ComputedField.MakeFunction("links(self)") as any, hideLinkButton: true } }], @@ -452,10 +452,6 @@ export namespace Docs { layout: { view: EmptyBox, dataField: defaultDataKey }, options: { links: ComputedField.MakeFunction("links(self)") as any } }], - [DocumentType.TEXTANCHOR, { - layout: { view: EmptyBox, dataField: defaultDataKey }, - options: { targetDropAction: "move", links: ComputedField.MakeFunction("links(self)") as any, hideLinkButton: true } - }] ]); const suffix = "Proto"; @@ -670,9 +666,9 @@ export namespace Docs { viewProps["acl-Override"] = "None"; viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add; const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true); - ![DocumentType.LINK, DocumentType.TEXTANCHOR, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc); + ![DocumentType.LINK, DocumentType.MARKER, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc); - !Doc.IsSystem(dataDoc) && ![DocumentType.HTMLANCHOR, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR, DocumentType.TEXTANCHOR].includes(proto.type as any) && + !Doc.IsSystem(dataDoc) && ![DocumentType.MARKER, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR].includes(proto.type as any) && !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc); return viewDoc; @@ -802,7 +798,7 @@ export namespace Docs { } export function TextanchorDocument(options: DocumentOptions = {}, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.TEXTANCHOR), undefined, options, id); + return InstanceFromProto(Prototypes.get(DocumentType.MARKER), undefined, options, id); } export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string) { @@ -811,7 +807,7 @@ export namespace Docs { return inst; } export function HTMLAnchorDocument(documents: Array, options: DocumentOptions, id?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.HTMLANCHOR), new List(documents), options, id); + return InstanceFromProto(Prototypes.get(DocumentType.MARKER), new List(documents), options, id); } export function PileDocument(documents: Array, options: DocumentOptions, id?: string) { diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 304215a8f..5b092258a 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -28,7 +28,7 @@ export class DocumentManager { DocListCast(view.rootDoc.links).forEach(link => { const whichOtherAnchor = view.props.LayoutTemplateString?.includes("anchor2") ? "anchor1" : "anchor2"; const otherDoc = link && (link[whichOtherAnchor] as Doc); - const otherDocAnno = otherDoc?.type === DocumentType.TEXTANCHOR ? otherDoc.annotationOn as Doc : undefined; + const otherDocAnno = DocumentType.MARKER === otherDoc?.type ? otherDoc.annotationOn as Doc : undefined; otherDoc && DocumentManager.Instance.DocumentViews?.filter(dv => Doc.AreProtosEqual(dv.rootDoc, otherDoc) || Doc.AreProtosEqual(dv.rootDoc, otherDocAnno)). forEach(otherView => { if (otherView.rootDoc.type !== DocumentType.LINK || otherView.props.LayoutTemplateString !== view.props.LayoutTemplateString) { @@ -162,7 +162,7 @@ export class DocumentManager { const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext : undefined; const targetDocContext = contextDoc || annotatedDoc; const targetDocContextView = targetDocContext && getFirstDocView(targetDocContext); - const focusView = !docView && targetDoc.type === DocumentType.TEXTANCHOR && annoContainerView ? annoContainerView : docView; + const focusView = !docView && targetDoc.type === DocumentType.MARKER && annoContainerView ? annoContainerView : docView; if (!docView && annoContainerView && !focusView) { annoContainerView.focus(targetDoc); // this allows something like a PDF view to remove its doc filters to expose the target so that it can be found in the retry code below } diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 7aeb19391..dbcc49f3d 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -23,7 +23,7 @@ export namespace SelectionManager { @action SelectView(docView: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it - if (!manager.SelectedViews.get(docView) && docView.props.Document.type !== DocumentType.HTMLANCHOR) { + if (!manager.SelectedViews.get(docView) && docView.props.Document.type !== DocumentType.MARKER) { if (!ctrlPressed) { this.DeselectAll(); } diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index dc6ac0366..c9e532745 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -174,7 +174,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt doc) { @observable _focusRangeFilters: Opt; getAnchor = () => { - const anchor = Docs.Create.TextanchorDocument({ + const anchor = Docs.Create.HTMLAnchorDocument({ title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as any, annotationOn: this.rootDoc }); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 35da09af6..8ef0057bd 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1487,7 +1487,7 @@ export class CollectionFreeFormView extends CollectionSubView e.preventDefault()} onContextMenu={this.onContextMenu} style={{ - pointerEvents: this.props.Document.type === DocumentType.HTMLANCHOR ? "none" : // bcz: ugh.. this is here to prevent htmlanchor's, which render as freeform views, from grabbing events -- need a better approach. + pointerEvents: this.props.Document.type === DocumentType.MARKER ? "none" : // bcz: ugh.. this is here to prevent markers, which render as freeform views, from grabbing events -- need a better approach. this.backgroundEvents ? "all" : this.props.pointerEvents as any, transform: `scale(${this.contentScaling || 1})`, width: `${100 / (this.contentScaling || 1)}%`, diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index abc3a7d7d..f5b1f96f2 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -163,7 +163,7 @@ export class WebBox extends ViewBoxAnnotatableComponent ex !== "annotationOn") : exclusions; + const fieldExclusions = doc.type === DocumentType.MARKER ? exclusions.filter(ex => ex !== "annotationOn") : exclusions; const filter = [...fieldExclusions, ...Cast(doc.cloneFieldFilter, listSpec("string"), [])]; await Promise.all(Object.keys(doc).map(async key => { if (filter.includes(key)) return; -- cgit v1.2.3-70-g09d2