From af37e51657913a4f1cc1536f7d7ad9f991d4dc32 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 24 Mar 2022 11:34:53 -0400 Subject: fixes for webbox scroll bars and resizer divider to show up properly --- src/client/views/nodes/WebBox.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/WebBox.scss') diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index 7dc970496..9d8825ad1 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -5,10 +5,16 @@ height: 100%; position: relative; display: flex; - .webBox-background { + .webBox-sideResizer { + position: absolute; width: 100%; height: 100%; cursor: ew-resize; + background: yellow; + } + .webBox-background { + width: 100%; + height: 100%; background: lightGray; } @@ -193,7 +199,7 @@ } div.webBox-outerContent::-webkit-scrollbar-thumb { - display: none; + cursor: nw-resize; } } -- cgit v1.2.3-70-g09d2 From 2c3264bca271af170b620cfc44ecdfafb77aacc0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 28 Mar 2022 12:20:07 -0400 Subject: enabled dragging documents onto tab bar without shift. modified link pivot document to automatically update when links are added and be a stacking view --- src/client/util/DragManager.ts | 4 +-- src/client/views/nodes/DocumentLinksButton.tsx | 35 ++++++++------------------ src/client/views/nodes/DocumentView.tsx | 26 ++++++++++++++++++- src/client/views/nodes/WebBox.scss | 2 +- 4 files changed, 39 insertions(+), 28 deletions(-) (limited to 'src/client/views/nodes/WebBox.scss') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index c9c499fff..0d6a77f71 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -458,9 +458,9 @@ export namespace DragManager { if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : dragData.defaultDropAction; } - if (e?.shiftKey && dragData.draggedDocuments.length === 1) { + if (((e.target as any)?.className === "lm_tabs" || e?.shiftKey) && dragData.draggedDocuments.length === 1) { dragData.dropAction = dragData.userDropAction || "same"; - if (dragData.dropAction === "move") { + if (dragData.dropAction === "move" || dragData.dropAction === "same") { dragData.removeDocument?.(dragData.draggedDocuments[0]); } AbortDrag(); diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 7e6ca4248..804e82856 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -2,9 +2,10 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "@material-ui/core"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, DocListCastAsync, Opt, WidthSym } from "../../../fields/Doc"; +import { Doc, Opt } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; -import { Cast, StrCast } from "../../../fields/Types"; +import { ScriptField } from "../../../fields/ScriptField"; +import { StrCast } from "../../../fields/Types"; import { TraceMobx } from "../../../fields/util"; import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../../Utils"; import { DocServer } from "../../DocServer"; @@ -20,7 +21,6 @@ import { DocumentView } from "./DocumentView"; import { LinkDescriptionPopup } from "./LinkDescriptionPopup"; import { TaskCompletionBox } from "./TaskCompletedBox"; import React = require("react"); -import { Transform } from "../../util/Transform"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; @@ -72,31 +72,18 @@ export class DocumentLinksButton extends React.Component { setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { if (doubleTap) { - const rootDoc = this.props.View.rootDoc; - const docid = Doc.CurrentUserEmail + Doc.GetProto(rootDoc)[Id] + "-pivotish"; - DocServer.GetRefField(docid).then(async docx => { + const linkSource = this.props.View.rootDoc; + const docid = Doc.CurrentUserEmail + Doc.GetProto(linkSource)[Id] + "-pivotish"; + DocServer.GetRefField(docid).then(docx => { const rootAlias = () => { - const rootAlias = Doc.MakeAlias(rootDoc); + const rootAlias = Doc.MakeAlias(linkSource); rootAlias.x = rootAlias.y = 0; return rootAlias; }; - let wid = rootDoc[WidthSym](); - const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([rootAlias()], { title: this.props.View.Document.title + "-pivot", _width: 500, _height: 500, }, docid); - const docs = await DocListCastAsync(Doc.GetProto(target).data); - if (!target.pivotFocusish) (Doc.GetProto(target).pivotFocusish = target); - DocListCast(rootDoc.links).forEach(link => { - const other = LinkManager.getOppositeAnchor(link, rootDoc); - const otherdoc = !other ? undefined : other.annotationOn ? Cast(other.annotationOn, Doc, null) : other; - if (otherdoc && !docs?.some(d => Doc.AreProtosEqual(d, otherdoc))) { - const alias = Doc.MakeAlias(otherdoc); - alias.x = wid; - alias.y = 0; - alias._lockedPosition = false; - wid += otherdoc[WidthSym](); - Doc.AddDocToList(Doc.GetProto(target), "data", alias); - } - }); - LightboxView.SetLightboxDoc(target); + const linkCollection = ((docx instanceof Doc) && docx) || Docs.Create.StackingDocument([/*rootAlias()*/], { title: this.props.View.Document.title + "-pivot", _width: 500, _height: 500, }, docid); + linkCollection.linkSource = linkSource; + if (!linkCollection.reactionScript) linkCollection.reactionScript = ScriptField.MakeScript("updateLinkCollection(self)"); + LightboxView.SetLightboxDoc(linkCollection); }); } else DocumentLinksButton.LinkEditorDocView = this.props.View; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e7de87ea5..955698190 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -2,7 +2,7 @@ import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, Field, Opt, StrListCast } from "../../../fields/Doc"; +import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, DocListCastAsync, Field, Opt, StrListCast, WidthSym } from "../../../fields/Doc"; import { Document } from '../../../fields/documentSchemas'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; @@ -1247,6 +1247,10 @@ export class DocumentView extends React.Component { return this.props.ScreenToLocalTransform().translate(-this.centeringX, -this.centeringY).scale(1 / this.nativeScaling); } componentDidMount() { + this._disposers.reactionScript = reaction( + () => ScriptCast(this.rootDoc.reactionScript)?.script?.run({ this: this.props.Document, self: Cast(this.rootDoc, Doc, null) || this.props.Document }).result, + output => output + ); this._disposers.height = reaction( () => NumCast(this.layoutDoc._height), action(height => { @@ -1298,4 +1302,24 @@ export class DocumentView extends React.Component { ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) { if (dv.Document.layoutKey === "layout_" + detailLayoutKeySuffix) dv.switchViews(false, "layout"); else dv.switchViews(true, detailLayoutKeySuffix); +}); + +ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc) { + const linkSource = Cast(linkCollection.linkSource, Doc, null); + const collectedLinks = DocListCast(Doc.GetProto(linkCollection).data); + let wid = linkSource[WidthSym](); + const links = DocListCast(linkSource.links); + links.forEach(link => { + const other = LinkManager.getOppositeAnchor(link, linkSource); + const otherdoc = !other ? undefined : other.annotationOn ? Cast(other.annotationOn, Doc, null) : other; + if (otherdoc && !collectedLinks?.some(d => Doc.AreProtosEqual(d, otherdoc))) { + const alias = Doc.MakeAlias(otherdoc); + alias.x = wid; + alias.y = 0; + alias._lockedPosition = false; + wid += otherdoc[WidthSym](); + Doc.AddDocToList(Doc.GetProto(linkCollection), "data", alias); + } + }); + return links; }); \ No newline at end of file diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index 9d8825ad1..ff38e37dd 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -10,7 +10,7 @@ width: 100%; height: 100%; cursor: ew-resize; - background: yellow; + background: darkgray; } .webBox-background { width: 100%; -- cgit v1.2.3-70-g09d2 From 6d2d18385e09da7645ff9c077240820f2d2043c9 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 2 May 2022 11:04:45 -0400 Subject: fixed up html clippings to have a better background color heuristic and to allow dragging clippings from webBox's. --- src/client/views/MarqueeAnnotator.tsx | 6 ++-- src/client/views/collections/CollectionSubView.tsx | 5 ++-- src/client/views/nodes/WebBox.scss | 11 ++++--- src/client/views/nodes/WebBox.tsx | 35 +++++++++++++++++----- 4 files changed, 40 insertions(+), 17 deletions(-) (limited to 'src/client/views/nodes/WebBox.scss') diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index a6b012bd6..2c7b04495 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -27,7 +27,7 @@ export interface MarqueeAnnotatorProps { containerOffset?: () => number[]; mainCont: HTMLDivElement; docView: DocumentView; - savedAnnotations: ObservableMap; + savedAnnotations: () => ObservableMap; annotationLayer: HTMLDivElement; addDocument: (doc: Doc) => boolean; getPageFromScroll?: (top: number) => number; @@ -128,7 +128,7 @@ export class MarqueeAnnotator extends React.Component { @undoBatch @action makeAnnotationDocument = (color: string, isLinkButton?: boolean, savedAnnotations?: ObservableMap): Opt => { - const savedAnnoMap = savedAnnotations ?? this.props.savedAnnotations; + const savedAnnoMap = savedAnnotations ?? this.props.savedAnnotations(); if (savedAnnoMap.size === 0) return undefined; const savedAnnos = Array.from(savedAnnoMap.values())[0]; if (savedAnnos.length && (savedAnnos[0] as any).marqueeing) { @@ -239,7 +239,7 @@ export class MarqueeAnnotator extends React.Component { copy.style.height = fbounds.height.toString() + "px"; copy.className = "marqueeAnnotator-annotationBox"; (copy as any).marqueeing = true; - MarqueeAnnotator.previewNewAnnotation(this.props.savedAnnotations, this.props.annotationLayer, copy, this.props.getPageFromScroll?.(this._top) || 0); + MarqueeAnnotator.previewNewAnnotation(this.props.savedAnnotations(), this.props.annotationLayer, copy, this.props.getPageFromScroll?.(this._top) || 0); } AnchorMenu.Instance.jumpTo(cliX, cliY); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 30e0adf24..247d0563a 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -317,10 +317,11 @@ export function CollectionSubView(moreProps?: X) { }); } else { const srcWeb = SelectionManager.Docs().lastElement(); - const srcUrl = (srcWeb?.data as WebField).url?.href?.match(/http[s]?:\/\/[^/]*/)?.[0]; + const srcUrl = (srcWeb?.data as WebField)?.url?.href?.match(/https?:\/\/[^/]*/)?.[0]; const reg = new RegExp(Utils.prepend(""), "g"); const modHtml = srcUrl ? html.replace(reg, srcUrl) : html; - const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: "-web page-", _width: 300, _height: 300 }); + const backgroundColor = tags.map(tag => tag.match(/.*(background-color: ?[^;]*)/)?.[1]?.replace(/background-color: ?(.*)/, "$1")).filter(t => t)?.[0]; + const htmlDoc = Docs.Create.HtmlDocument(modHtml, { ...options, title: srcUrl ? "from:" + srcUrl : "-web clip-", _width: 300, _height: 300, backgroundColor }); Doc.GetProto(htmlDoc)["data-text"] = Doc.GetProto(htmlDoc).text = text; addDocument(htmlDoc); if (srcWeb) { diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index ff38e37dd..b037e7220 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -5,17 +5,18 @@ height: 100%; position: relative; display: flex; - .webBox-sideResizer { + + .webBox-sideResizer { position: absolute; width: 100%; height: 100%; cursor: ew-resize; background: darkgray; } - .webBox-background { + + .webBox-background { width: 100%; height: 100%; - background: lightGray; } .webBox-ui { @@ -120,7 +121,7 @@ box-shadow: $standard-box-shadow; transition: 0.2s; - &:hover{ + &:hover { filter: brightness(0.85); } } @@ -160,6 +161,7 @@ .webBox-cont { pointer-events: none; } + .webBox-cont, .webBox-cont-interactive { padding: 0vw; @@ -193,6 +195,7 @@ top: 0; left: 0; overflow: auto; + .webBox-innerContent { position: relative; } diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 5c72417cc..4d4ed6c67 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -80,8 +80,6 @@ export class WebBox extends ViewBoxAnnotatableComponent this._webUrl = this._url); // setting the weburl will change the src parameter of the embedded iframe and force a navigation to it. } @@ -231,6 +229,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this.urlEditor; // controls to be added to the top bar when a document of this type is selected @@ -256,6 +255,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { + + // this.createTextAnnotation(sel, sel.getRangeAt(0)); const anchor = AnchorMenu.Instance?.GetAnchor(this._savedAnnotations) ?? Docs.Create.WebanchorDocument(this._url, { @@ -267,6 +268,9 @@ export class WebBox extends ViewBoxAnnotatableComponent ObservableMap) | undefined; + savedAnnotationsCreator: (() => ObservableMap) = () => this._textAnnotationCreator?.() || this._savedAnnotations; + @action iframeUp = (e: PointerEvent) => { this.props.docViewPath().lastElement()?.docView?.cleanupPointerEvents(); // pointerup events aren't generated on containing document view, so we have to invoke it here. @@ -275,7 +279,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this.createTextAnnotation(sel, sel.getRangeAt(0)); AnchorMenu.Instance.jumpTo(e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale); } @@ -283,6 +287,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { + this._textAnnotationCreator = undefined; + const sel = this._iframe?.contentWindow?.getSelection?.(); const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!); const scale = (this.props.scaling?.() || 1) * mainContBounds.scale; const word = getWordAtPoint(e.target, e.clientX, e.clientY); @@ -546,6 +552,9 @@ export class WebBox extends ViewBoxAnnotatableComponent = undefined; @observable _previewWidth: Opt = undefined; toggleSidebar = action((preview: boolean = false) => { - const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); + var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); + if (!nativeWidth) { + const defaultNativeWidth = this.dataDoc[this.fieldKey] instanceof WebField ? 850 : this.Document[WidthSym](); + Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth); + Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || this.Document[HeightSym]() / this.Document[WidthSym]() * defaultNativeWidth); + nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); + } const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth; const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth + WebBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth; const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); @@ -620,9 +635,13 @@ export class WebBox extends ViewBoxAnnotatableComponent !this.SidebarShown ? 0 : @@ -716,7 +735,7 @@ export class WebBox extends ViewBoxAnnotatableComponent -
+
}
-- cgit v1.2.3-70-g09d2 From f072a9f2c1ad69eb8ae4242fa5d2e18bbd94f6ef Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 6 May 2022 11:45:44 -0400 Subject: changed following links to open up icons all the way down to the target document. allow StartLink to work with webBox w/ text selection. fixed web clippings to have a cursor and grab keyDown events. --- src/client/util/DocumentManager.ts | 42 +++++++++++++++------- .../util/Import & Export/DirectoryImportBox.tsx | 2 +- src/client/util/LinkManager.ts | 11 +++--- src/client/util/SharingManager.tsx | 30 ++++++++-------- src/client/views/DocumentDecorations.tsx | 13 ++++--- src/client/views/MainView.tsx | 2 +- src/client/views/collections/TabDocView.tsx | 2 +- src/client/views/collections/TreeView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collectionLinear/CollectionLinearView.tsx | 2 +- .../collectionSchema/CollectionSchemaCells.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 3 +- src/client/views/nodes/LinkDescriptionPopup.tsx | 1 + src/client/views/nodes/PDFBox.tsx | 1 + src/client/views/nodes/WebBox.scss | 3 ++ src/client/views/nodes/WebBox.tsx | 11 +++--- src/client/views/nodes/trails/PresBox.tsx | 4 +-- src/client/views/search/SearchBox.tsx | 2 +- 18 files changed, 84 insertions(+), 51 deletions(-) (limited to 'src/client/views/nodes/WebBox.scss') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index b6c28d2fe..aeddc3249 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -156,7 +156,7 @@ export class DocumentManager { targetDoc: Doc, // document to display willZoom: boolean, // whether to zoom doc to take up most of screen createViewFunc = DocumentManager.addView, // how to create a view of the doc if it doesn't exist - docContext?: Doc, // context to load that should contain the target + docContext: Doc[], // context to load that should contain the target linkDoc?: Doc, // link that's being followed closeContextIfNotFound: boolean = false, // after opening a context where the document should be, this determines whether the context should be closed if the Doc isn't actually there originatingDoc: Opt = undefined, // doc that initiated the display of the target odoc @@ -190,31 +190,40 @@ export class DocumentManager { finished?.(); }; const annoContainerView = (!wasHidden || resolvedTarget !== annotatedDoc) && annotatedDoc && getFirstDocView(annotatedDoc); - const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined; - const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext : undefined; + const contextDocs = docContext.length ? await DocListCastAsync(docContext[0].data) : undefined; + const contextDoc = contextDocs?.find(doc => Doc.AreProtosEqual(doc, targetDoc) || Doc.AreProtosEqual(doc, annotatedDoc)) ? docContext.lastElement() : undefined; const targetDocContext = contextDoc || annotatedDoc; const targetDocContextView = (targetDocContext && getFirstDocView(targetDocContext)) || (wasHidden && annoContainerView);// if we have an annotation container and the target was hidden, then try again because we just un-hid the document above const focusView = !docView && targetDoc.type === DocumentType.MARKER && annoContainerView ? annoContainerView : docView; - if ((!docView && targetDoc.type !== DocumentType.MARKER) && annoContainerView) { + if (annoContainerView) { if (annoContainerView.props.Document.layoutKey === "layout_icon") { - annoContainerView.iconify(() => this.jumpToDocument( - targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, - finished, originalTarget, noSelect, presZoom)); + annoContainerView.iconify(() => annoContainerView.focus(targetDoc, { + originalTarget, willZoom, scale: presZoom, afterFocus: (didFocus: boolean) => + new Promise(res => { + focusAndFinish(true); + res(ViewAdjustment.doNothing); + }) + })); return; - } else { + } else if (!docView && targetDoc.type !== DocumentType.MARKER) { 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 } } if (focusView) { !noSelect && Doc.linkFollowHighlight(focusView.rootDoc); //TODO:glr make this a setting in PresBox - focusView.focus(targetDoc, { + const doFocus = (forceDidFocus: boolean) => focusView.focus(originalTarget ?? targetDoc, { originalTarget, willZoom, scale: presZoom, afterFocus: (didFocus: boolean) => new Promise(res => { - focusAndFinish(didFocus); + focusAndFinish(forceDidFocus || didFocus); res(ViewAdjustment.doNothing); }) }); + if (focusView.props.Document.layoutKey === "layout_icon") { + focusView.iconify(() => doFocus(true)); + } else { + doFocus(false); + } } else { if (!targetDocContext) { // we don't have a view and there's no context specified ... create a new view of the target using the dockFunc or default createViewFunc(Doc.BrushDoc(targetDoc), finished); // bcz: should we use this?: Doc.MakeAlias(targetDoc))); @@ -228,7 +237,7 @@ export class DocumentManager { targetDocContext._viewTransition = undefined; if (targetDocContext.layoutKey === "layout_icon") { targetDocContextView.iconify(() => this.jumpToDocument( - targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, + resolvedTarget ?? targetDoc, willZoom, createViewFunc, docContext, linkDoc, closeContextIfNotFound, originatingDoc, finished, originalTarget, noSelect, presZoom)); } return ViewAdjustment.doNothing; @@ -263,7 +272,16 @@ export class DocumentManager { }; setTimeout(() => findView(0), 0); } - } else { // there's no context view so we need to create one first and try again when that finishes + } else { + if (docContext.length && docContext[0]?.layoutKey === "layout_icon") { + const docContextView = this.getFirstDocumentView(docContext[0]); + if (docContextView) { + return docContextView.iconify(() => this.jumpToDocument( + targetDoc, willZoom, createViewFunc, docContext.slice(1, docContext.length), linkDoc, closeContextIfNotFound, originatingDoc, + finished, originalTarget, noSelect, presZoom)); + } + } + // there's no context view so we need to create one first and try again when that finishes const finishFunc = () => this.jumpToDocument(targetDoc, true, createViewFunc, docContext, linkDoc, true /* if we don't find the target, we want to get rid of the context just created */, undefined, finished, originalTarget); createViewFunc(targetDocContext, // after creating the context, this calls the finish function that will retry looking for the target finishFunc); diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 39e9251a5..37571ae01 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -161,7 +161,7 @@ export class DirectoryImportBox extends React.Component { await GooglePhotos.Export.CollectionToAlbum({ collection: importContainer }); Doc.AddDocToList(Doc.GetProto(parent.props.Document), "data", importContainer); !this.persistent && this.props.removeDocument && this.props.removeDocument(doc); - DocumentManager.Instance.jumpToDocument(importContainer, true); + DocumentManager.Instance.jumpToDocument(importContainer, true, undefined, []); } runInAction(() => { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 9445533dc..b28662a57 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -1,3 +1,4 @@ +import { validationResult } from "express-validator/check"; import { action, observable, observe } from "mobx"; import { computedFn } from "mobx-utils"; import { DirectLinksSym, Doc, DocListCast, Field, Opt } from "../../fields/Doc"; @@ -241,10 +242,12 @@ export class LinkManager { } else { const containerAnnoDoc = Cast(target.annotationOn, Doc, null); const containerDoc = containerAnnoDoc || target; - const containerDocContext = Cast(containerDoc?.context, Doc, null); - const targetContext = LightboxView.LightboxDoc ? containerAnnoDoc || containerDocContext : containerDocContext; - const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; - DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "lightbox"), finished), targetNavContext, linkDoc, undefined, sourceDoc, allFinished); + var containerDocContext = containerDoc?.context ? [Cast(containerDoc?.context, Doc, null)] : [] as Doc[]; + while (containerDocContext.length && !DocumentManager.Instance.getDocumentView(containerDocContext[0]) && containerDocContext[0].context) { + containerDocContext = [Cast(containerDocContext[0].context, Doc, null), ...containerDocContext]; + } + const targetContexts = LightboxView.LightboxDoc ? [containerAnnoDoc || containerDocContext[0]] : containerDocContext; + DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "lightbox"), finished), targetContexts, linkDoc, undefined, sourceDoc, allFinished); } } else { allFinished(); diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 6d7f7e8df..11450309a 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -370,11 +370,11 @@ export class SharingManager extends React.Component<{}> { if (!uniform) dropdownValues.unshift("-multiple-"); if (override) dropdownValues.unshift("None"); return dropdownValues.filter(permission => !Doc.UserDoc().noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)).map(permission => - ( - - ) + ( + + ) ); } @@ -388,7 +388,7 @@ export class SharingManager extends React.Component<{}> { onClick={() => { let context: Opt; if (this.targetDoc && this.targetDocView && docs.length === 1 && (context = this.targetDocView.props.ContainingCollectionView)) { - DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, context.props.Document); + DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, [context.props.Document]); } }} onPointerEnter={action(() => { @@ -548,10 +548,10 @@ export class SharingManager extends React.Component<{}> { {this.sharingOptions(uniform)} ) : ( -
- {permissions} -
- )} +
+ {permissions} +
+ )}
); @@ -572,7 +572,7 @@ export class SharingManager extends React.Component<{}> {
Owner -
+
) : null, @@ -622,10 +622,10 @@ export class SharingManager extends React.Component<{}> { {this.sharingOptions(uniform, group.title === "Override")} ) : ( -
- {permissions} -
- )} +
+ {permissions} +
+ )} ); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index eb2bcc18c..936946df0 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -113,7 +113,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P } } - titleEntered = (e: React.KeyboardEvent) => e.key === "Enter" && (e.target as any).blur(); + titleEntered = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + e.stopPropagation(); + (e.target as any).blur(); + } + } @action onTitleDown = (e: React.PointerEvent): void => { setupMoveUpEvents(this, e, e => this.onBackgroundMove(true, e), (e) => { }, action((e) => { @@ -288,7 +293,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P if (fixedAspect && (resizeHdl === "documentDecorations-bottomRightResizer" || resizeHdl === "documentDecorations-topLeftResizer")) { // need to generalize for bl and tr drag handles const project = (p: number[], a: number[], b: number[]) => { const atob = [b[0] - a[0], b[1] - a[1]]; - const atop = [p[0] - a[0], p[1] - a[1]]; first + const atop = [p[0] - a[0], p[1] - a[1]]; const len = atob[0] * atob[0] + atob[1] * atob[1]; let dot = atop[0] * atob[0] + atop[1] * atob[1]; const t = dot / len; @@ -501,7 +506,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P value={this._accumulatedTitle} onBlur={e => this.titleBlur()} onChange={action(e => this._accumulatedTitle = e.target.value)} - onKeyPress={this.titleEntered} /> : + onKeyDown={this.titleEntered} /> :
{`${this.selectionTitle}`}
; @@ -521,7 +526,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox; const resizerScheme = colorScheme ? "documentDecorations-resizer" + colorScheme : ""; - const rotation = NumCast(seldoc.rootDoc._jitterRotation) + const rotation = NumCast(seldoc.rootDoc._jitterRotation); const rdeg = rotation / 180 * Math.PI; return (
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index c794c73db..db51c54f8 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -133,7 +133,7 @@ export class MainView extends React.Component { window.addEventListener("paste", KeyManager.Instance.paste as any); document.addEventListener("dash", (e: any) => { // event used by chrome plugin to tell Dash which document to focus on const id = FormattedTextBox.GetDocFromUrl(e.detail); - DocServer.GetRefField(id).then(doc => (doc instanceof Doc) ? DocumentManager.Instance.jumpToDocument(doc, false, undefined) : (null)); + DocServer.GetRefField(id).then(doc => (doc instanceof Doc) ? DocumentManager.Instance.jumpToDocument(doc, false, undefined, []) : (null)); }); document.addEventListener("linkAnnotationToDash", Hypothesis.linkListener); this.initEventListeners(); diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx index 78b125e07..8dfc7edc7 100644 --- a/src/client/views/collections/TabDocView.tsx +++ b/src/client/views/collections/TabDocView.tsx @@ -256,7 +256,7 @@ export class TabDocView extends React.Component { } PresBox.Instance?._selectedArray.clear(); pinDoc && PresBox.Instance?._selectedArray.set(pinDoc, undefined); //Update selected array - DocumentManager.Instance.jumpToDocument(doc, false, undefined); + DocumentManager.Instance.jumpToDocument(doc, false, undefined, []); batch.end(); }); } diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index 72480b094..164021358 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -72,7 +72,7 @@ export enum TreeSort { Down = "down", Zindex = "z", None = "none" -}; +} /** * Renders a treeView of a collection of documents * diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5d1e1892c..5b3a7db41 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1423,7 +1423,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (oldDiv.childNodes) { + if (oldDiv.childNodes && newDiv) { for (let i = 0; i < oldDiv.childNodes.length; i++) { this.replaceCanvases(oldDiv.childNodes[i] as HTMLElement, newDiv.childNodes[i] as HTMLElement); } diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx index e3d4f86c1..c615bfb8e 100644 --- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx +++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx @@ -231,7 +231,7 @@ export class CollectionLinearView extends CollectionSubView() { Currently playing: {CollectionStackedTimeline.CurrentlyPlaying.map((clip, i) => - DocumentManager.Instance.jumpToDocument(clip, true)}> + DocumentManager.Instance.jumpToDocument(clip, true, undefined, [])}> {clip.title + (i === CollectionStackedTimeline.CurrentlyPlaying.length - 1 ? "" : ",")} )} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx index c2bb3b3ac..adcd9e1e3 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx @@ -199,7 +199,7 @@ export class CollectionSchemaCell extends React.Component { const aliasdoc = await SearchUtil.GetAliasesOfDocument(this._rowDataDoc); const targetContext = aliasdoc.length <= 0 ? undefined : Cast(aliasdoc[0].context, Doc, null); // Jump to the this document - DocumentManager.Instance.jumpToDocument(this._rowDoc, false, emptyFunction, targetContext, + DocumentManager.Instance.jumpToDocument(this._rowDoc, false, emptyFunction, targetContext ? [targetContext] : [], undefined, undefined, undefined, () => this.props.setPreviewDoc(this._rowDoc)); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 8570f6fff..02ea87103 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -663,7 +663,7 @@ export class DocumentViewInternal extends DocComponent !this.props.isSelected() && LightboxView.LightboxDoc !== this.rootDoc && this.thumb && + !Doc.AreProtosEqual(DocumentLinksButton.StartLink, this.rootDoc) && !this._componentView?.isAnyChildContentActive?.() ? true : false @computed get contents() { TraceMobx(); diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx index a9d33f161..ccac66996 100644 --- a/src/client/views/nodes/LinkDescriptionPopup.tsx +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -54,6 +54,7 @@ export class LinkDescriptionPopup extends React.Component<{}> { top: LinkDescriptionPopup.popupY ? LinkDescriptionPopup.popupY : 350, }}> e.stopPropagation()} onKeyPress={e => e.key === "Enter" && this.onDismiss(true)} placeholder={"(Optional) Enter link description..."} onChange={(e) => this.descriptionChanged(e)}> diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 69662d53a..48465976a 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -75,6 +75,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent { + return; // currently we render pdf icons as text labels const docViewContent = this.props.docViewPath().lastElement().ContentDiv!; const newDiv = docViewContent.cloneNode(true) as HTMLDivElement; newDiv.style.width = (this.layoutDoc[WidthSym]()).toString(); diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index b037e7220..d8dd074a5 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -156,6 +156,9 @@ position: absolute; top: 0; left: 0; + cursor: text; + padding: 15px; + height: 100% } .webBox-cont { diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 80961c92f..f441e5d36 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -207,8 +207,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { - if (this._mainCont.current) { + createTextAnnotation = (sel: Selection, selRange: Range | undefined) => { + if (this._mainCont.current && selRange) { const clientRects = selRange.getClientRects(); for (let i = 0; i < clientRects.length; i++) { const rect = clientRects.item(i); @@ -235,7 +235,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this.urlEditor; // controls to be added to the top bar when a document of this type is selected scrollFocus = (doc: Doc, smooth: boolean) => { - this.props.select(true); + this.props.select(false); // hack to preven the webBox from being replaced with a thumbnail that currently doesn't show the the anchors if (StrCast(doc.webUrl) !== this._url) this.submitURL(StrCast(doc.webUrl), !smooth); if (DocListCast(this.props.Document[this.fieldKey + "-sidebar"]).includes(doc) && !this.SidebarShown) { this.toggleSidebar(!smooth); @@ -252,7 +252,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { @@ -279,7 +279,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this.createTextAnnotation(sel, sel.getRangeAt(0)); + this._textAnnotationCreator = () => this.createTextAnnotation(sel, !sel.isCollapsed ? sel.getRangeAt(0) : undefined); AnchorMenu.Instance.jumpTo(e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale); } @@ -650,6 +650,7 @@ export class WebBox extends ViewBoxAnnotatableComponent e.stopPropagation()} style={{ width: !this.layoutDoc.forceReflow ? NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]) || `100%` : "100%", }}> {this.urlContent}
; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 30ad43562..820d7ef96 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -389,11 +389,11 @@ export class PresBox extends ViewBoxBaseComponent() { LightboxView.SetLightboxDoc(targetDoc); } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) { LightboxView.SetLightboxDoc(undefined); - await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right + await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, [srcContext], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { LightboxView.SetLightboxDoc(undefined); //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right + await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, [srcContext], undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right } // After navigating to the document, if it is added as a presPinView then it will // adjust the pan and scale to that of the pinView when it was added. diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 9257cb75e..3d36efbc4 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -365,7 +365,7 @@ export class SearchBox extends ViewBoxBaseComponent() { * or opening it in a new tab. */ selectElement = async (doc: Doc, finishFunc: () => void) => { - await DocumentManager.Instance.jumpToDocument(doc, true, undefined, undefined, undefined, undefined, undefined, finishFunc); + await DocumentManager.Instance.jumpToDocument(doc, true, undefined, [], undefined, undefined, undefined, finishFunc); } /** -- cgit v1.2.3-70-g09d2