From d4ae1056b281979864a7e6668a85951bd586684e Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 31 Aug 2023 19:19:34 -0400
Subject: fixed compile errors and switched to use_azure = false for server.

---
 src/client/views/nodes/WebBox.tsx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index febf8341e..a4fac977c 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -50,7 +50,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     public static openSidebarWidth = 250;
     public static sidebarResizerWidth = 5;
     static webStyleSheet = addStyleSheet();
-    private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
+    private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void);
     private _setBrushViewer: undefined | ((view: { width: number; height: number; panX: number; panY: number }, transTime: number) => void);
     private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
     private _outerRef: React.RefObject<HTMLDivElement> = React.createRef();
@@ -368,7 +368,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
         const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale;
         const word = getWordAtPoint(e.target, e.clientX, e.clientY);
-        this._setPreviewCursor?.(e.clientX, e.clientY, false, true);
+        this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.rootDoc);
         MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
         e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale]);
         if (word || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
@@ -719,7 +719,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         if (sel?.empty) sel.empty(); // Chrome
         else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
         if (x !== undefined && y !== undefined) {
-            this._setPreviewCursor?.(x, y, false, false);
+            this._setPreviewCursor?.(x, y, false, false, this.rootDoc);
             ContextMenu.Instance.closeMenu();
             ContextMenu.Instance.setIgnoreEvents(false);
             if (e?.button === 2 || e?.altKey) {
@@ -993,7 +993,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     }
     searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value);
     showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno));
-    setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func);
+    setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
     panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth;
     panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
     scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
-- 
cgit v1.2.3-70-g09d2


From aa71a67ea048ba03654bf56a9793c06f857a863b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 2 Sep 2023 10:49:04 -0400
Subject: switched web default to wikipedia from bing since bing search
 requires scripts.  change link doc preview to use showDocument instead of
 addDocTab so that existing docs can be found.

---
 src/client/documents/Documents.ts         | 2 +-
 src/client/util/CurrentUserUtils.ts       | 4 +++-
 src/client/views/nodes/LinkDocPreview.tsx | 8 +++++++-
 src/client/views/nodes/WebBox.tsx         | 3 +--
 4 files changed, 12 insertions(+), 5 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 919958b24..bfb07325d 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1084,7 +1084,7 @@ export namespace Docs {
             const nwid = options._nativeWidth || undefined;
             const nhght = options._nativeHeight || undefined;
             if (!nhght && width && height && nwid) options._nativeHeight = (Number(nwid) * Number(height)) / Number(width);
-            return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url ? url : 'http://www.bing.com/'), options);
+            return InstanceFromProto(Prototypes.get(DocumentType.WEB), new WebField(url ? url : 'https://www.wikipedia.org/'), options);
         }
 
         export function HtmlDocument(html: string, options: DocumentOptions = {}) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 11cc5f900..af0f62c0f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -8,7 +8,7 @@ import { RichTextField } from "../../fields/RichTextField";
 import { listSpec } from "../../fields/Schema";
 import { ScriptField } from "../../fields/ScriptField";
 import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types";
-import { nullAudio } from "../../fields/URLField";
+import { nullAudio, URLField, WebField } from "../../fields/URLField";
 import { SetCachedGroups, SharingPermissions } from "../../fields/util";
 import { GestureUtils } from "../../pen-gestures/GestureUtils";
 import { addStyleSheetRule, OmitKeys, Utils } from "../../Utils";
@@ -913,6 +913,8 @@ export class CurrentUserUtils {
         Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MySharedDocs)
         Doc.AddDocToList(Doc.MyFilesystem, undefined, Doc.MyRecentlyClosed)
 
+        Doc.GetProto(DocCast(Doc.UserDoc().emptyWebpage)).data = new WebField("https://www.wikipedia.org")
+
         if (doc.activeDashboard instanceof Doc) {
             // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
             doc.activeDashboard.colorScheme = doc.activeDashboard.colorScheme === ColorScheme.Light ? undefined : doc.activeDashboard.colorScheme;
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 42c8ea6a4..0ee83bc08 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -19,6 +19,7 @@ import { Transform } from '../../util/Transform';
 import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
 import './LinkDocPreview.scss';
 import React = require('react');
+import { DocumentManager } from '../../util/DocumentManager';
 
 interface LinkDocPreviewProps {
     linkDoc?: Doc;
@@ -176,7 +177,12 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
             const webDoc =
                 Array.from(SearchUtil.SearchCollection(Doc.MyFilesystem, this.props.hrefs[0]).keys()).lastElement() ??
                 Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true });
-            this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
+            DocumentManager.Instance.showDocument(webDoc, {
+                openLocation: OpenWhere.lightbox,
+                willPan: true,
+                zoomTime: 500,
+            });
+            //this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
         }
     };
 
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index a4fac977c..1435dff7c 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -364,14 +364,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     };
     @action
     iframeDown = (e: PointerEvent) => {
-        const sel = this._iframe?.contentWindow?.getSelection?.();
         const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
         const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale;
         const word = getWordAtPoint(e.target, e.clientX, e.clientY);
         this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.rootDoc);
         MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
         e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale]);
-        if (word || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
+        if (word || !Object.keys(e.target as any).includes('className') || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
             setTimeout(
                 action(() => (this._marqueeing = undefined)),
                 100
-- 
cgit v1.2.3-70-g09d2


From 2ab7a3130b4b548f26ba8e650a24f4695e3133dc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 2 Sep 2023 15:30:31 -0400
Subject: restored some cors server code to allow bing and google searches to
 work.  adjusted webBox to change nativeWidth when navigating to a wider page
 (eg., from google search to target). enabled scripts for google and bing
 pages.  enabled entering web page url through documents title.

---
 src/client/views/nodes/WebBox.tsx   | 34 ++++++++++++++++++++++++----------
 src/server/server_Initialization.ts | 22 +++++++++++++++-------
 2 files changed, 39 insertions(+), 17 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 1435dff7c..f5db2ccfd 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
 import { observer } from 'mobx-react';
 import * as WebRequest from 'web-request';
 import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
@@ -196,8 +196,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         });
         this._disposers.urlchange = reaction(
             () => WebCast(this.rootDoc.data),
+            url => this.submitURL(false, false)
+        );
+        this._disposers.titling = reaction(
+            () => StrCast(this.rootDoc.title),
             url => {
-                this.submitURL(url.url.href, false, false);
+                url.startsWith('www') && this.setData('http://' + url);
+                url.startsWith('http') && this.setData(url);
             }
         );
 
@@ -416,6 +421,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     }
 
     _iframetimeout: any = undefined;
+    @observable _warning = 0;
     @action
     iframeLoaded = (e: any) => {
         const iframe = this._iframe;
@@ -429,6 +435,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         try {
             href = iframe?.contentWindow?.location.href;
         } catch (e) {
+            runInAction(() => this._warning++);
             href = undefined;
         }
         let requrlraw = decodeURIComponent(href?.replace(Utils.prepend('') + '/corsProxy/', '') ?? this._url.toString());
@@ -461,12 +468,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             //     { passive: false }
             // );
             const initHeights = () => {
-                this._scrollHeight = Math.max(this._scrollHeight, (iframeContent.body.children[0] as any)?.scrollHeight || 0);
+                this._scrollHeight = Math.max(this._scrollHeight, iframeContent.body.scrollHeight || 0);
                 if (this._scrollHeight) {
                     this.rootDoc.nativeHeight = Math.min(NumCast(this.rootDoc.nativeHeight), this._scrollHeight);
                     this.layoutDoc.height = Math.min(this.layoutDoc[Height](), (this.layoutDoc[Width]() * NumCast(this.rootDoc.nativeHeight)) / NumCast(this.rootDoc.nativeWidth));
                 }
             };
+            const swidth = Math.max(NumCast(this.layoutDoc.nativeWidth), iframeContent.body.scrollWidth || 0);
+            if (swidth) {
+                const aspectResize = swidth / NumCast(this.rootDoc.nativeWidth);
+                this.rootDoc.nativeWidth = swidth;
+                this.rootDoc.nativeHeight = NumCast(this.rootDoc.nativeHeight) * aspectResize;
+                this.layoutDoc.height = this.layoutDoc[Height]() * aspectResize;
+            }
             initHeights();
             this._iframetimeout && clearTimeout(this._iframetimeout);
             this._iframetimeout = setTimeout(
@@ -544,7 +558,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
     goTo = (scrollTop: number, duration: number, easeFunc: 'linear' | 'ease' | undefined) => {
         if (this._outerRef.current) {
-            const iframeHeight = Math.max(scrollTop, this._scrollHeight - this.panelHeight());
             if (duration) {
                 smoothScroll(duration, [this._outerRef.current], scrollTop, easeFunc);
                 this.setDashScrollTop(scrollTop, duration);
@@ -609,9 +622,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         );
     };
     @action
-    submitURL = (newUrl?: string, preview?: boolean, dontUpdateIframe?: boolean) => {
-        if (!newUrl) return;
-        if (!newUrl.startsWith('http')) newUrl = 'http://' + newUrl;
+    submitURL = (preview?: boolean, dontUpdateIframe?: boolean) => {
         try {
             if (!preview) {
                 if (this._webPageHasBeenRendered) {
@@ -667,9 +678,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             !Doc.noviceMode &&
                 funcs.push({ description: (this.layoutDoc[this.fieldKey + '_useCors'] ? "Don't Use" : 'Use') + ' Cors', event: () => (this.layoutDoc[this.fieldKey + '_useCors'] = !this.layoutDoc[this.fieldKey + '_useCors']), icon: 'snowflake' });
             funcs.push({
-                description: (this.layoutDoc.allowScripts ? 'Prevent' : 'Allow') + ' Scripts',
+                description: (this.dataDoc[this.fieldKey + '_allowScripts'] ? 'Prevent' : 'Allow') + ' Scripts',
                 event: () => {
-                    this.layoutDoc.allowScripts = !this.layoutDoc.allowScripts;
+                    this.dataDoc[this.fieldKey + '_allowScripts'] = !this.dataDoc[this.fieldKey + '_allowScripts'];
                     if (this._iframe) {
                         runInAction(() => (this._hackHide = true));
                         setTimeout(action(() => (this._hackHide = false)));
@@ -743,8 +754,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         }
         if (field instanceof WebField) {
             const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl;
+            const scripts = this.dataDoc[this.fieldKey + '_allowScripts'] || this._webUrl.includes('wikipedia.org') || this._webUrl.includes('google.com') || this._webUrl.startsWith('https://bing');
+            //if (!scripts) console.log('No scripts for: ' + url);
             return (
                 <iframe
+                    key={this._warning}
                     className="webBox-iframe"
                     ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
                     src={url}
@@ -752,7 +766,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                     scrolling="no" // ugh.. on windows, I get an inner scroll bar for the iframe's body even though the scrollHeight should be set to the full height of the document.
                     // the 'allow-top-navigation' and 'allow-top-navigation-by-user-activation' attributes are left out to prevent iframes from redirecting the top-level Dash page
                     // sandbox={"allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts"} />;
-                    sandbox={`${this.layoutDoc.allowScripts ? 'allow-scripts' : ''} allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin`}
+                    sandbox={`${scripts ? 'allow-scripts' : ''} allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin`}
                 />
             );
         }
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index ee32de152..438cde8cf 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -149,15 +149,23 @@ function registerAuthenticationRoutes(server: express.Express) {
 
 function registerCorsProxy(server: express.Express) {
     server.use('/corsProxy', async (req, res) => {
-        //const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : '';
-        let requrl = decodeURIComponent(req.url.substring(1));
-        const qsplit = requrl.split('?q=');
-        const newqsplit = requrl.split('&q=');
+        const referer = req.headers.referer ? decodeURIComponent(req.headers.referer) : '';
+        let requrlraw = decodeURIComponent(req.url.substring(1));
+        const qsplit = requrlraw.split('?q=');
+        const newqsplit = requrlraw.split('&q=');
         if (qsplit.length > 1 && newqsplit.length > 1) {
             const lastq = newqsplit[newqsplit.length - 1];
-            requrl = qsplit[0] + '?q=' + lastq.split('&')[0] + '&' + qsplit[1].split('&')[1];
+            requrlraw = qsplit[0] + '?q=' + lastq.split('&')[0] + '&' + qsplit[1].split('&')[1];
+        }
+        const requrl = requrlraw.startsWith('/') ? referer + requrlraw : requrlraw;
+        // cors weirdness here...
+        // if the referer is a cors page and the cors() route (I think) redirected to /corsProxy/<path> and the requested url path was relative,
+        // then we redirect again to the cors referer and just add the relative path.
+        if (!requrl.startsWith('http') && req.originalUrl.startsWith('/corsProxy') && referer?.includes('corsProxy')) {
+            res.redirect(referer + (referer.endsWith('/') ? '' : '/') + requrl);
+        } else {
+            proxyServe(req, requrl, res);
         }
-        proxyServe(req, requrl, res);
     });
 }
 
@@ -178,7 +186,7 @@ function proxyServe(req: any, requrl: string, response: any) {
                         .replace('<head>', '<head> <style>[id ^= "google"] { display: none; } </style>')
                         // .replace('<script', '<noscript')
                         // .replace('</script', '</noscript')
-                        // .replace(/href="https?([^"]*)"/g, httpsToCors)
+                        .replace(/href="https?([^"]*)"/g, httpsToCors)
                         .replace(/data-srcset="[^"]*"/g, '')
                         .replace(/srcset="[^"]*"/g, '')
                         .replace(/target="_blank"/g, '');
-- 
cgit v1.2.3-70-g09d2


From b5605e12c760af341516f5bc0b0fe4afb14a14ca Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 5 Sep 2023 11:11:11 -0400
Subject: change getAnchor to honor addAsAnnotation so that pinning docs
 doesn't add to annotation list.  fixed dragging anchor menu icons so that
 they appear.

---
 src/client/util/DocumentManager.ts                 |   5 +-
 src/client/views/DocComponent.tsx                  |   3 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   1 +
 src/client/views/nodes/DocumentView.tsx            |   1 +
 src/client/views/nodes/ImageBox.tsx                |   7 +-
 src/client/views/nodes/WebBox.tsx                  |   6 +-
 src/client/views/pdf/AnchorMenu.tsx                | 122 +++++----------------
 7 files changed, 39 insertions(+), 106 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index bfe0e1b48..b9f6059f4 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -11,7 +11,6 @@ import { CollectionDockingView } from '../views/collections/CollectionDockingVie
 import { TabDocView } from '../views/collections/TabDocView';
 import { LightboxView } from '../views/LightboxView';
 import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere, OpenWhereMod } from '../views/nodes/DocumentView';
-import { FormattedTextBox } from '../views/nodes/formattedText/FormattedTextBox';
 import { KeyValueBox } from '../views/nodes/KeyValueBox';
 import { LinkAnchorBox } from '../views/nodes/LinkAnchorBox';
 import { PresBox } from '../views/nodes/trails';
@@ -320,7 +319,9 @@ export class DocumentManager {
     @action
     restoreDocView(viewSpec: Opt<Doc>, docView: DocumentView, options: DocFocusOptions, contextView: Opt<DocumentView>, targetDoc: Doc) {
         if (viewSpec && docView) {
-            if (docView.ComponentView instanceof FormattedTextBox) docView.ComponentView?.focus(viewSpec, options);
+            //if (docView.ComponentView instanceof FormattedTextBox)
+            //viewSpec !== docView.rootDoc &&
+            docView.ComponentView?.focus?.(viewSpec, options);
             PresBox.restoreTargetDocView(docView, viewSpec, options.zoomTime ?? 500);
             Doc.linkFollowHighlight(viewSpec ? [docView.rootDoc, viewSpec] : docView.rootDoc, undefined, options.effect);
             if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.rootDoc._layout_currentTimecode));
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 6a1efdf9c..483b92957 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -139,7 +139,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
             const indocs = doc instanceof Doc ? [doc] : doc;
             const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin);
 
-            docs.forEach(doc => doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true));
+            // docs.forEach(doc => doc.annotationOn === this.props.Document && Doc.SetInPlace(doc, 'annotationOn', undefined, true));
             const targetDataDoc = this.dataDoc;
             const value = DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]);
             const toRemove = value.filter(v => docs.includes(v));
@@ -194,6 +194,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
                     added.forEach(doc => {
                         doc._dragOnlyWithinContainer = undefined;
                         if (annotationKey ?? this._annotationKeySuffix()) Doc.GetProto(doc).annotationOn = this.rootDoc;
+                        else Doc.GetProto(doc).annotationOn = undefined;
                         Doc.SetContainer(doc, this.rootDoc);
                         inheritParentAcls(targetDataDoc, doc, true);
                     });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 16d6f1270..7768ca547 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -311,6 +311,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
     focus = (anchor: Doc, options: DocFocusOptions) => {
         if (this._lightboxDoc) return;
+        if (anchor.type !== DocumentType.CONFIG && !DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]).includes(anchor)) return;
         const xfToCollection = options?.docTransform ?? Transform.Identity();
         const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined };
         const cantTransform = this.fitContentsToBox || ((this.rootDoc._isGroup || this.layoutDoc._lockedTransform) && !LightboxView.LightboxDoc);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f7773ff18..ab99f3c6d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -121,6 +121,7 @@ export interface DocComponentView {
     reverseNativeScaling?: () => boolean; // DocumentView's setup screenToLocal based on the doc having a nativeWidth/Height.  However, some content views (e.g., FreeFormView w/ fitContentsToBox set) may ignore the native dimensions so this flags the DocumentView to not do Nativre scaling.
     shrinkWrap?: () => void; // requests a document to display all of its contents with no white space.  currently only implemented (needed?) for freeform views
     select?: (ctrlKey: boolean, shiftKey: boolean) => void;
+    focus?: (textAnchor: Doc, options: DocFocusOptions) => Opt<number>;
     menuControls?: () => JSX.Element; // controls to display in the top menu bar when the document is selected.
     isAnyChildContentActive?: () => boolean; // is any child content of the document active
     onClickScriptDisable?: () => 'never' | 'always'; // disable click scripts : never, always, or undefined = only when selected
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index f5c6a9273..a19cc3555 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -85,8 +85,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     };
 
     getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
+        const visibleAnchor = this._getAnchor?.(this._savedAnnotations, false); // use marquee anchor, otherwise, save zoom/pan as anchor
         const anchor =
-            this._getAnchor?.(this._savedAnnotations, false) ?? // use marquee anchor, otherwise, save zoom/pan as anchor
+            visibleAnchor ??
             Docs.Create.ConfigDocument({
                 title: 'ImgAnchor:' + this.rootDoc.title,
                 config_panX: NumCast(this.layoutDoc._freeform_panX),
@@ -96,8 +97,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
             });
         if (anchor) {
             if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
-            /* addAsAnnotation &&*/ this.addDocument(anchor);
-            PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: true } }, this.rootDoc);
+            (addAsAnnotation || visibleAnchor) && this.addDocument(anchor);
+            PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: visibleAnchor ? false : true } }, this.rootDoc);
             return anchor;
         }
         return this.rootDoc;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f5db2ccfd..5f891e9a0 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -330,8 +330,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 ele.append(contents);
             }
         } catch (e) {}
+        const visibleAnchor = this._getAnchor(this._savedAnnotations, false);
         const anchor =
-            this._getAnchor(this._savedAnnotations, false) ??
+            visibleAnchor ??
             Docs.Create.ConfigDocument({
                 title: StrCast(this.rootDoc.title + ' ' + this.layoutDoc._layout_scrollTop),
                 y: NumCast(this.layoutDoc._layout_scrollTop),
@@ -340,8 +341,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
         anchor.text_html = ele?.innerHTML;
-        //addAsAnnotation &&
-        this.addDocumentWrapper(anchor);
+        (addAsAnnotation || visibleAnchor) && this.addDocumentWrapper(anchor);
         return anchor;
     };
 
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 6a8b06377..a52250145 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -3,7 +3,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
 import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx';
 import { observer } from 'mobx-react';
-import { EditorView } from 'prosemirror-view';
 import { ColorState } from 'react-color';
 import { Doc, Opt } from '../../../fields/Doc';
 import { StrCast } from '../../../fields/Types';
@@ -15,68 +14,24 @@ import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu';
 import { LinkPopup } from '../linking/LinkPopup';
 import './AnchorMenu.scss';
 import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
+import { SettingsManager } from '../../util/SettingsManager';
 
 @observer
 export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     static Instance: AnchorMenu;
 
     private _disposer: IReactionDisposer | undefined;
-    private _disposer2: IReactionDisposer | undefined;
-    private _commentCont = React.createRef<HTMLButtonElement>();
-    private _palette = [
-        'rgba(208, 2, 27, 0.8)',
-        'rgba(238, 0, 0, 0.8)',
-        'rgba(245, 166, 35, 0.8)',
-        'rgba(248, 231, 28, 0.8)',
-        'rgba(245, 230, 95, 0.616)',
-        'rgba(139, 87, 42, 0.8)',
-        'rgba(126, 211, 33, 0.8)',
-        'rgba(65, 117, 5, 0.8)',
-        'rgba(144, 19, 254, 0.8)',
-        'rgba(238, 169, 184, 0.8)',
-        'rgba(224, 187, 228, 0.8)',
-        'rgba(225, 223, 211, 0.8)',
-        'rgba(255, 255, 255, 0.8)',
-        'rgba(155, 155, 155, 0.8)',
-        'rgba(0, 0, 0, 0.8)',
-    ];
+    private _commentRef = React.createRef<HTMLDivElement>();
+    private _cropRef = React.createRef<HTMLDivElement>();
 
     @observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)';
 
     @observable public Status: 'marquee' | 'annotation' | '' = '';
 
     // GPT additions
-    @observable private GPTMode: GPTPopupMode = GPTPopupMode.SUMMARY;
     @observable private selectedText: string = '';
-    @observable private editorView?: EditorView;
-    @observable private textDoc?: Doc;
-    @observable private highlightRange: number[] | undefined;
-    private selectionRange: number[] | undefined;
-
-    @action
-    setGPTMode = (mode: GPTPopupMode) => {
-        this.GPTMode = mode;
-    };
-
     @action
-    setHighlightRange(r: number[] | undefined) {
-        this.highlightRange = r;
-    }
-
-    @action
-    public setSelectedText = (txt: string) => {
-        this.selectedText = txt;
-    };
-
-    @action
-    public setEditorView = (editor: EditorView) => {
-        this.editorView = editor;
-    };
-
-    @action
-    public setTextDoc = (textDoc: Doc) => {
-        this.textDoc = textDoc;
-    };
+    public setSelectedText = (txt: string) => (this.selectedText = txt);
 
     public onMakeAnchor: () => Opt<Doc> = () => undefined; // Method to get anchor from text search
 
@@ -105,20 +60,12 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
 
     componentWillUnmount() {
         this._disposer?.();
-        this._disposer2?.();
     }
 
     componentDidMount() {
-        this._disposer2 = reaction(
-            () => this._opacity,
-            opacity => {},
-            { fireImmediately: true }
-        );
         this._disposer = reaction(
             () => SelectionManager.Views().slice(),
-            selected => {
-                AnchorMenu.Instance.fadeOut(true);
-            }
+            selected => AnchorMenu.Instance.fadeOut(true)
         );
     }
 
@@ -129,17 +76,12 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     gptSummarize = async (e: React.PointerEvent) => {
         // move this logic to gptpopup, need to implement generate again
         GPTPopup.Instance.setVisible(true);
-        this.setHighlightRange(undefined);
         GPTPopup.Instance.setMode(GPTPopupMode.SUMMARY);
         GPTPopup.Instance.setLoading(true);
 
         try {
             const res = await gptAPICall(this.selectedText, GPTCallType.SUMMARY);
-            if (res) {
-                GPTPopup.Instance.setText(res);
-            } else {
-                GPTPopup.Instance.setText('Something went wrong.');
-            }
+            GPTPopup.Instance.setText(res || 'Something went wrong.');
         } catch (err) {
             console.error(err);
         }
@@ -151,7 +93,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             this,
             e,
             (e: PointerEvent) => {
-                this.StartDrag(e, this._commentCont.current!);
+                this.StartDrag(e, this._commentRef.current!);
                 return true;
             },
             returnFalse,
@@ -168,7 +110,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             this,
             e,
             (e: PointerEvent) => {
-                this.StartCropDrag(e, this._commentCont.current!);
+                this.StartCropDrag(e, this._cropRef.current!);
                 return true;
             },
             returnFalse,
@@ -214,37 +156,21 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
      * all selected text available to summarize but its only supported for pdf and web ATM.
      * @returns Whether the GPT icon for summarization should appear
      */
-    canSummarize = (): boolean => {
-        const docs = SelectionManager.Docs();
-        if (docs.length > 0) {
-            return docs.some(doc => doc.type === DocumentType.PDF || doc.type === DocumentType.WEB);
-        }
-        return false;
-    };
-
-    /**
-     * Returns whether the selected text can be edited.
-     * @returns Whether the GPT icon for summarization should appear
-     */
-    canEdit = (): boolean => {
-        const docs = SelectionManager.Docs();
-        if (docs.length > 0) {
-            return docs.some(doc => doc.type === 'rtf');
-        }
-        return false;
-    };
+    canSummarize = () => SelectionManager.Docs().some(doc => [DocumentType.PDF, DocumentType.WEB].includes(doc.type as any));
 
     render() {
         const buttons =
             this.Status === 'marquee' ? (
                 <>
                     {this.highlighter}
-                    <IconButton
-                        tooltip="Drag to Place Annotation" //
-                        onPointerDown={this.pointerDown}
-                        icon={<FontAwesomeIcon icon="comment-alt" />}
-                        color={StrCast(Doc.UserDoc().userColor)}
-                    />
+                    <div ref={this._commentRef}>
+                        <IconButton
+                            tooltip="Drag to Place Annotation" //
+                            onPointerDown={this.pointerDown}
+                            icon={<FontAwesomeIcon icon="comment-alt" />}
+                            color={SettingsManager.userColor}
+                        />
+                    </div>
                     {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/}
                     {AnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && (
                         <IconButton
@@ -270,12 +196,14 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                         color={StrCast(Doc.UserDoc().userColor)}
                     />
                     {AnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : (
-                        <IconButton
-                            tooltip="Click/Drag to create cropped image" //
-                            onPointerDown={this.cropDown}
-                            icon={<FontAwesomeIcon icon="image" />}
-                            color={StrCast(Doc.UserDoc().userColor)}
-                        />
+                        <div ref={this._cropRef}>
+                            <IconButton
+                                tooltip="Click/Drag to create cropped image" //
+                                onPointerDown={this.cropDown}
+                                icon={<FontAwesomeIcon icon="image" />}
+                                color={StrCast(Doc.UserDoc().userColor)}
+                            />
+                        </div>
                     )}
                 </>
             ) : (
-- 
cgit v1.2.3-70-g09d2


From e477b31c4cb894fed2e5a4a65d62e54a1b2c824a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 5 Sep 2023 23:30:31 -0400
Subject: fixed dragging marquees on web boxes

---
 src/client/views/nodes/WebBox.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 5f891e9a0..00aaa3698 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -375,7 +375,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.rootDoc);
         MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
         e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale]);
-        if (word || !Object.keys(e.target as any).includes('className') || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
+        if (word || (e.target as any)?.className?.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
             setTimeout(
                 action(() => (this._marqueeing = undefined)),
                 100
-- 
cgit v1.2.3-70-g09d2


From e5bef3d971c9615f90b4e8dbdf9adc778ef578d3 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 6 Sep 2023 23:11:07 -0400
Subject: fixed reszing/dragging annotations over webBox

---
 src/client/views/nodes/WebBox.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 00aaa3698..61ff8afd3 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as WebRequest from 'web-request';
 import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
@@ -761,6 +761,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                     key={this._warning}
                     className="webBox-iframe"
                     ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
+                    style={{ pointerEvents: DocumentView.Interacting ? 'none' : undefined }}
                     src={url}
                     onLoad={this.iframeLoaded}
                     scrolling="no" // ugh.. on windows, I get an inner scroll bar for the iframe's body even though the scrollHeight should be set to the full height of the document.
-- 
cgit v1.2.3-70-g09d2


From df4f2c01db206e54a4ada7c9210d89dc56d48438 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 6 Sep 2023 23:14:48 -0400
Subject: from last

---
 src/client/views/nodes/WebBox.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 61ff8afd3..3acdc1883 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -761,7 +761,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                     key={this._warning}
                     className="webBox-iframe"
                     ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
-                    style={{ pointerEvents: DocumentView.Interacting ? 'none' : undefined }}
+                    style={{ pointerEvents: this._isAnyChildContentActive || DocumentView.Interacting ? 'none' : undefined }}
                     src={url}
                     onLoad={this.iframeLoaded}
                     scrolling="no" // ugh.. on windows, I get an inner scroll bar for the iframe's body even though the scrollHeight should be set to the full height of the document.
-- 
cgit v1.2.3-70-g09d2


From 8485c5430d7feb5eee9cf3e0374afe7fbf0e60cd Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 7 Sep 2023 10:04:27 -0400
Subject: fixed removing map pins to not reappear.  updated config anchors to
 not be added to annotations list.  fixed imageBox to not pass its configs on
 to its parent collection when focusing.

---
 src/client/documents/Documents.ts        |  1 +
 src/client/views/nodes/ImageBox.tsx      |  4 ++--
 src/client/views/nodes/MapBox/MapBox.tsx | 17 ++++++++++++-----
 src/client/views/nodes/PDFBox.tsx        |  9 ++++-----
 src/client/views/nodes/WebBox.tsx        |  2 +-
 5 files changed, 20 insertions(+), 13 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index bfb07325d..e413d4389 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -313,6 +313,7 @@ export class DocumentOptions {
     _isTimelineLabel?: BOOLt = new BoolInfo('is document a timeline label');
     _isLightbox?: BOOLt = new BoolInfo('whether a collection acts as a lightbox by opening lightbox links by hiding all other documents in collection besides link target');
 
+    mapPin?: DOCt = new DocInfo('pin associated with a config anchor', false);
     config_latitude?: NUMt = new NumInfo('latitude of a map', false);
     config_longitude?: NUMt = new NumInfo('longitude of map', false);
     config_map_zoom?: NUMt = new NumInfo('zoom of map', false);
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index a19cc3555..9eaebfc8c 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -97,7 +97,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
             });
         if (anchor) {
             if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
-            (addAsAnnotation || visibleAnchor) && this.addDocument(anchor);
+            addAsAnnotation && visibleAnchor && this.addDocument(anchor);
             PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: visibleAnchor ? false : true } }, this.rootDoc);
             return anchor;
         }
@@ -503,7 +503,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         this._marqueeing = undefined;
         this.props.select(false);
     };
-    focus = (anchor: Doc, options: DocFocusOptions) => this._ffref.current?.focus(anchor, options);
+    focus = (anchor: Doc, options: DocFocusOptions) => (anchor.type === DocumentType.CONFIG ? undefined : this._ffref.current?.focus(anchor, options));
 
     _ffref = React.createRef<CollectionFreeFormView>();
     savedAnnotations = () => this._savedAnnotations;
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 504e8bbb9..01810fa00 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -139,13 +139,19 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         return this.addDocument(doc, sidebarKey); // add to sidebar list
     };
 
+    removeMapDocument = (doc: Doc | Doc[], annotationKey?: string) => {
+        const docs = doc instanceof Doc ? [doc] : doc;
+        this.allAnnotations.filter(anno => docs.includes(DocCast(anno.mapPin))).forEach(anno => (anno.mapPin = undefined));
+        return this.removeDocument(doc, annotationKey, undefined);
+    };
+
     /**
      * Removing documents from the sidebar
      * @param doc
      * @param sidebarKey
      * @returns
      */
-    sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => this.removeDocument(doc, sidebarKey);
+    sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => this.removeMapDocument(doc, sidebarKey);
 
     /**
      * Toggle sidebar onclick the tiny comment button on the top right corner
@@ -326,7 +332,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             NumCast(longitude),
             false,
             [],
-            { map: map }
+            { title: map ?? `lat=${latitude},lng=${longitude}`, map: map }
             // ,'pushpinIDamongus'+ this.incrementer++
         );
         this.addDocument(pushpin, this.annotationKey);
@@ -451,11 +457,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             config_map_type: StrCast(this.dataDoc.map_type),
             config_map: StrCast((existingPin ?? this.selectedPin)?.map) || StrCast(this.dataDoc.map),
             layout_unrendered: true,
+            mapPin: existingPin ?? this.selectedPin,
+            annotationOn: this.rootDoc,
         });
         if (anchor) {
-            anchor.mapPin = existingPin ?? this.selectedPin;
             if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
-            /* addAsAnnotation &&*/ this.addDocument(anchor);
+            addAsAnnotation && false && this.addDocument(anchor); // only need to add visible annotations to doc, but all anchors are configs for now
             PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), map: true } }, this.rootDoc);
             return anchor;
         }
@@ -489,7 +496,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
      *   Removes pin from annotations
      */
     @action
-    removePushpin = (pinDoc: Doc) => this.removeDocument(pinDoc, this.annotationKey);
+    removePushpin = (pinDoc: Doc) => this.removeMapDocument(pinDoc, this.annotationKey);
 
     /*
      * Removes pushpin from map render
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 758b49655..6f9d96a33 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -243,14 +243,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 title: StrCast(this.rootDoc.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)),
                 annotationOn: this.rootDoc,
             });
-        const annoAnchor = this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations(), true);
-        const anchor = annoAnchor ?? docAnchor();
+        const visibleAnchor = this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations(), true);
+        const anchor = visibleAnchor ?? docAnchor();
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
         anchor.text_html = ele?.innerHTML;
-        if (addAsAnnotation || annoAnchor) {
-            this.addDocument(anchor);
-        }
+        addAsAnnotation && visibleAnchor && this.addDocument(anchor);
+
         return anchor;
     };
 
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 3acdc1883..d5b7b5dfe 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -341,7 +341,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
         anchor.text_html = ele?.innerHTML;
-        (addAsAnnotation || visibleAnchor) && this.addDocumentWrapper(anchor);
+        addAsAnnotation && visibleAnchor && this.addDocumentWrapper(anchor);
         return anchor;
     };
 
-- 
cgit v1.2.3-70-g09d2


From 6536508867969f8e9d191d0fd9e4dd0f43606bc0 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 13 Sep 2023 10:31:20 -0400
Subject: need to honor 'addAsAnnotation' flag getting anchors so that docs
 know when they are a target of config.

---
 src/client/views/DocumentButtonBar.tsx | 2 +-
 src/client/views/nodes/ImageBox.tsx    | 2 +-
 src/client/views/nodes/PDFBox.tsx      | 2 +-
 src/client/views/nodes/WebBox.tsx      | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 345135a1a..c1ec5b4a4 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -562,7 +562,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         const rootView = this.props.views()[0];
         const rootDoc = rootView?.rootDoc;
         if (rootDoc) {
-            const anchor = rootView.ComponentView?.getAnchor?.(false) ?? rootDoc;
+            const anchor = rootView.ComponentView?.getAnchor?.(true) ?? rootDoc;
             const trail = DocCast(anchor.presentationTrail) ?? Doc.MakeCopy(DocCast(Doc.UserDoc().emptyTrail), true);
             if (trail !== anchor.presentationTrail) {
                 DocUtils.MakeLink(anchor, trail, { link_relationship: 'link trail' });
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index d2508e7cf..1ab120af5 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -97,7 +97,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
             });
         if (anchor) {
             if (!addAsAnnotation) anchor.backgroundColor = 'transparent';
-            addAsAnnotation && visibleAnchor && this.addDocument(anchor);
+            addAsAnnotation && this.addDocument(anchor);
             PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), pannable: visibleAnchor ? false : true } }, this.rootDoc);
             return anchor;
         }
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5cec8fc24..39e27d15b 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -248,7 +248,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
         anchor.text_html = ele?.innerHTML;
-        addAsAnnotation && visibleAnchor && this.addDocument(anchor);
+        addAsAnnotation && this.addDocument(anchor);
 
         return anchor;
     };
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index d5b7b5dfe..27c19105f 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -341,7 +341,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
         anchor.text_html = ele?.innerHTML;
-        addAsAnnotation && visibleAnchor && this.addDocumentWrapper(anchor);
+        addAsAnnotation && this.addDocumentWrapper(anchor);
         return anchor;
     };
 
-- 
cgit v1.2.3-70-g09d2


From 0df1fc3fd85c1dea84dcaec5a934fc08f0da6832 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 4 Oct 2023 07:46:05 -0400
Subject: several fixes for webclips, linking to pdf/web, fonticon dropdowns.
 removed sliderbox. reduce uses of scriptContext

fixed web clipping annotations to be in correct spot and not to crash because of using a url that it doesn't have.
fixed pdf/web links to not use anchor from other end of link. because of sharing of GetAnchor global.
added a backup when presbox overwrites a doc's data field.
removed sliderBox.
fixed fontIcon dropdowns to not call click script twice.
removed scriptContext where it wasn't needed which is everywhere except TreeViews.
---
 src/client/documents/DocumentTypes.ts              |   3 +-
 src/client/documents/Documents.ts                  |   8 --
 src/client/util/CurrentUserUtils.ts                |   2 +-
 src/client/views/MainView.tsx                      |   2 -
 src/client/views/StyleProvider.tsx                 |   2 -
 .../views/collections/CollectionNoteTakingView.tsx |   1 -
 .../collections/CollectionStackedTimeline.tsx      |  37 +++-----
 .../views/collections/CollectionStackingView.tsx   |   1 -
 .../collectionSchema/CollectionSchemaView.tsx      |   1 -
 src/client/views/nodes/DocumentContentsView.tsx    |   2 -
 src/client/views/nodes/FontIconBox/FontIconBox.tsx |   1 -
 src/client/views/nodes/PDFBox.tsx                  |   2 +-
 src/client/views/nodes/SliderBox.scss              |  19 ----
 src/client/views/nodes/SliderBox.tsx               | 103 ---------------------
 src/client/views/nodes/WebBox.scss                 |   1 -
 src/client/views/nodes/WebBox.tsx                  |  80 +++++++++++-----
 src/client/views/nodes/trails/PresBox.tsx          |   7 +-
 src/client/views/pdf/PDFViewer.tsx                 |   5 +-
 18 files changed, 82 insertions(+), 195 deletions(-)
 delete mode 100644 src/client/views/nodes/SliderBox.scss
 delete mode 100644 src/client/views/nodes/SliderBox.tsx

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index f8d129e79..87010f770 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -30,14 +30,13 @@ export enum DocumentType {
     // special purpose wrappers that either take no data or are compositions of lower level types
     LINK = 'link',
     IMPORT = 'import',
-    SLIDER = 'slider',
     PRES = 'presentation',
     PRESELEMENT = 'preselement',
     COLOR = 'color',
     YOUTUBE = 'youtube',
     COMPARISON = 'comparison',
     GROUP = 'group',
-    PUSHPIN = "pushpin",
+    PUSHPIN = 'pushpin',
 
     SCRIPTDB = 'scriptdb', // database of scripts
     GROUPDB = 'groupdb', // database of groups
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f7ceef4f4..a79a62b57 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -54,7 +54,6 @@ import { PhysicsSimulationBox } from '../views/nodes/PhysicsBox/PhysicsSimulatio
 import { RecordingBox } from '../views/nodes/RecordingBox/RecordingBox';
 import { ScreenshotBox } from '../views/nodes/ScreenshotBox';
 import { ScriptingBox } from '../views/nodes/ScriptingBox';
-import { SliderBox } from '../views/nodes/SliderBox';
 import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
 import { PresBox } from '../views/nodes/trails/PresBox';
 import { PresElementBox } from '../views/nodes/trails/PresElementBox';
@@ -628,13 +627,6 @@ export namespace Docs {
                     options: {},
                 },
             ],
-            [
-                DocumentType.SLIDER,
-                {
-                    layout: { view: SliderBox, dataField: defaultDataKey },
-                    options: {},
-                },
-            ],
             [
                 DocumentType.PRES,
                 {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 2ea5972ee..cc8f72ddf 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -820,7 +820,7 @@ export class CurrentUserUtils {
     // When the user views one of these documents, it will be added to the sharing documents 'viewed' list field
     // The sharing document also stores the user's color value which helps distinguish shared documents from personal documents
     static setupSharedDocs(doc: Doc, sharingDocumentId: string) {
-        const dblClkScript = "{scriptContext.openLevel(documentView); addDocToList(scriptContext.props.treeView.props.Document, 'viewed', documentView.rootDoc);}";
+        const dblClkScript = "{scriptContext.openLevel(documentView); addDocToList(documentView.props.treeViewDoc, 'viewed', documentView.rootDoc);}";
         
         const sharedScripts = {  treeView_ChildDoubleClick: dblClkScript,  }
         const sharedDocOpts:DocumentOptions = {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index d6f5d63fe..0a3389fc2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -728,7 +728,6 @@ export class MainView extends React.Component {
                         PanelHeight={this.leftMenuFlyoutHeight}
                         renderDepth={0}
                         isContentActive={returnTrue}
-                        scriptContext={CollectionDockingView.Instance?.props.Document}
                         focus={emptyFunction}
                         whenChildContentsActiveChanged={emptyFunction}
                         bringToFront={emptyFunction}
@@ -766,7 +765,6 @@ export class MainView extends React.Component {
                     childFilters={returnEmptyFilter}
                     childFiltersByRanges={returnEmptyFilter}
                     searchFilterDocs={returnEmptyDoclist}
-                    scriptContext={this}
                 />
             </div>
         );
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index d7537bffb..8417a6f5b 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -21,7 +21,6 @@ import { InkingStroke } from './InkingStroke';
 import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
 import { FieldViewProps } from './nodes/FieldView';
 import { KeyValueBox } from './nodes/KeyValueBox';
-import { SliderBox } from './nodes/SliderBox';
 import './StyleProvider.scss';
 import React = require('react');
 import { PropertiesView } from './PropertiesView';
@@ -215,7 +214,6 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
                 case DocumentType.SCREENSHOT:
                 case DocumentType.VID:         docColor = docColor || (Colors.LIGHT_GRAY); break;
                 case DocumentType.COL:
-                    if (StrCast(Doc.LayoutField(doc)).includes(SliderBox.name)) break;
                     docColor = docColor || (Doc.IsSystem(doc)
                             ? SettingsManager.userBackgroundColor
                             : doc.annotationOn
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index a69049b59..c7ad80f11 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -269,7 +269,6 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
                 addDocTab={this.props.addDocTab}
                 bringToFront={returnFalse}
-                scriptContext={this.props.scriptContext}
                 pinToPres={this.props.pinToPres}
             />
         );
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index ad3160a08..c4650647c 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -58,9 +58,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
     @observable static SelectingRegion: CollectionStackedTimeline | undefined = undefined;
     @observable public static CurrentlyPlaying: DocumentView[];
 
-    static RangeScript: ScriptField;
     static LabelScript: ScriptField;
-    static RangePlayScript: ScriptField;
     static LabelPlayScript: ScriptField;
 
     private _timeline: HTMLDivElement | null = null; // ref to actual timeline div
@@ -114,25 +112,6 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         return this._zoomFactor;
     }
 
-    constructor(props: any) {
-        super(props);
-        // onClick play scripts
-        CollectionStackedTimeline.RangeScript =
-            CollectionStackedTimeline.RangeScript ||
-            ScriptField.MakeFunction(`scriptContext.clickAnchor(this, clientX)`, {
-                self: Doc.name,
-                scriptContext: 'any',
-                clientX: 'number',
-            })!;
-        CollectionStackedTimeline.RangePlayScript =
-            CollectionStackedTimeline.RangePlayScript ||
-            ScriptField.MakeFunction(`scriptContext.playOnClick(this, clientX)`, {
-                self: Doc.name,
-                scriptContext: 'any',
-                clientX: 'number',
-            })!;
-    }
-
     componentDidMount() {
         document.addEventListener('keydown', this.keyEvents, true);
     }
@@ -179,8 +158,19 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         return Math.max(this.clipStart, Math.min(this.clipEnd, (screen_delta / width) * this.clipDuration + this.clipStart));
     };
 
-    rangeClickScript = () => CollectionStackedTimeline.RangeScript;
-    rangePlayScript = () => CollectionStackedTimeline.RangePlayScript;
+    @computed get rangeClick() {
+        // prettier-ignore
+        return ScriptField.MakeFunction('stackedTimeline.clickAnchor(this, clientX)',
+            { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any }
+        )!;
+    }
+    @computed get rangePlay() {
+        // prettier-ignore
+        return ScriptField.MakeFunction('stackedTimeline.playOnClick(this, clientX)', 
+            { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any })!;
+    }
+    rangeClickScript = () => this.rangeClick;
+    rangePlayScript = () => this.rangePlay;
 
     // handles key events for for creating key anchors, scrubbing, exiting trim
     @action
@@ -835,7 +825,6 @@ class StackedTimelineAnchor extends React.Component<StackedTimelineAnchorProps>
                     hideResizeHandles={true}
                     bringToFront={emptyFunction}
                     contextMenuItems={this.contextMenuItems}
-                    scriptContext={this.props.stackedTimeline}
                 />
             ),
         };
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 36f8bc101..c43a9d2b8 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -361,7 +361,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
                 addDocTab={this.props.addDocTab}
                 bringToFront={returnFalse}
-                scriptContext={this.props.scriptContext}
                 pinToPres={this.props.pinToPres}
             />
         );
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index d2b61167e..f73c037f4 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -972,7 +972,6 @@ class CollectionSchemaViewDocs extends React.Component<CollectionSchemaViewDocsP
                                 hideDocumentButtonBar={true}
                                 hideLinkAnchors={true}
                                 layout_fitWidth={returnTrue}
-                                scriptContext={this}
                             />
                         </div>
                     );
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 8ac9d6804..e1de2fa76 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -41,7 +41,6 @@ import { PhysicsSimulationBox } from './PhysicsBox/PhysicsSimulationBox';
 import { RecordingBox } from './RecordingBox';
 import { ScreenshotBox } from './ScreenshotBox';
 import { ScriptingBox } from './ScriptingBox';
-import { SliderBox } from './SliderBox';
 import { PresBox } from './trails/PresBox';
 import { VideoBox } from './VideoBox';
 import { WebBox } from './WebBox';
@@ -240,7 +239,6 @@ export class DocumentContentsView extends React.Component<
                     FontIconBox,
                     LabelBox,
                     EquationBox,
-                    SliderBox,
                     FieldView,
                     CollectionFreeFormView,
                     CollectionDockingView,
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index 14a3d16ef..d2e1293da 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -240,7 +240,6 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                 text: typeof value === 'string' ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title),
                 val: value,
                 style: getStyle(value),
-                onClick: undoable(() => script.script.run({ this: this.layoutDoc, self: this.rootDoc, value }), value),
                 // shortcut: '#',
             }));
 
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 73a5be90a..cf44649a2 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -242,7 +242,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 title: StrCast(this.rootDoc.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)),
                 annotationOn: this.rootDoc,
             });
-        const visibleAnchor = this._pdfViewer?._getAnchor(this._pdfViewer.savedAnnotations(), true);
+        const visibleAnchor = this._pdfViewer?._getAnchor?.(this._pdfViewer.savedAnnotations(), true);
         const anchor = visibleAnchor ?? docAnchor();
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
diff --git a/src/client/views/nodes/SliderBox.scss b/src/client/views/nodes/SliderBox.scss
deleted file mode 100644
index 4206a368d..000000000
--- a/src/client/views/nodes/SliderBox.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-.sliderBox-outerDiv {
-    width: calc(100% - 14px);   // 14px accounts for handles that are at the max value of the slider that would extend outside the box
-    height: 100%;
-    border-radius: inherit;
-    display: flex;
-    flex-direction: column;
-    position: relative;
-    .slider-tracks {
-        top: 7px;
-        position: relative;
-    }
-    .slider-ticks {
-        position: relative;
-    }
-    .slider-handles {
-        top: 7px;
-        position: relative;
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/nodes/SliderBox.tsx b/src/client/views/nodes/SliderBox.tsx
deleted file mode 100644
index 430b20eb5..000000000
--- a/src/client/views/nodes/SliderBox.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import { runInAction } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider';
-import { NumCast, ScriptCast, StrCast } from '../../../fields/Types';
-import { ContextMenu } from '../ContextMenu';
-import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxBaseComponent } from '../DocComponent';
-import { ScriptBox } from '../ScriptBox';
-import { StyleProp } from '../StyleProvider';
-import { FieldView, FieldViewProps } from './FieldView';
-import { Handle, Tick, TooltipRail, Track } from './SliderBox-components';
-import './SliderBox.scss';
-
-@observer
-export class SliderBox extends ViewBoxBaseComponent<FieldViewProps>() {
-    public static LayoutString(fieldKey: string) {
-        return FieldView.LayoutString(SliderBox, fieldKey);
-    }
-
-    get minThumbKey() {
-        return this.fieldKey + '-minThumb';
-    }
-    get maxThumbKey() {
-        return this.fieldKey + '-maxThumb';
-    }
-    get minKey() {
-        return this.fieldKey + '-min';
-    }
-    get maxKey() {
-        return this.fieldKey + '-max';
-    }
-    specificContextMenu = (e: React.MouseEvent): void => {
-        const funcs: ContextMenuProps[] = [];
-        funcs.push({ description: 'Edit Thumb Change Script', icon: 'edit', event: (obj: any) => ScriptBox.EditButtonScript('On Thumb Change ...', this.props.Document, 'onThumbChange', obj.x, obj.y) });
-        ContextMenu.Instance.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' });
-    };
-    onChange = (values: readonly number[]) =>
-        runInAction(() => {
-            this.dataDoc[this.minThumbKey] = values[0];
-            this.dataDoc[this.maxThumbKey] = values[1];
-            ScriptCast(this.layoutDoc.onThumbChanged, null)?.script.run({
-                self: this.rootDoc,
-                scriptContext: this.props.scriptContext,
-                range: values,
-                this: this.layoutDoc,
-            });
-        });
-
-    render() {
-        const domain = [NumCast(this.layoutDoc[this.minKey]), NumCast(this.layoutDoc[this.maxKey])];
-        const defaultValues = [NumCast(this.dataDoc[this.minThumbKey]), NumCast(this.dataDoc[this.maxThumbKey])];
-        return domain[1] <= domain[0] ? null : (
-            <div className="sliderBox-outerDiv" onContextMenu={this.specificContextMenu} onPointerDown={e => e.stopPropagation()} style={{ boxShadow: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BoxShadow) }}>
-                <div
-                    className="sliderBox-mainButton"
-                    onContextMenu={this.specificContextMenu}
-                    style={{
-                        background: StrCast(this.layoutDoc.backgroundColor),
-                        color: StrCast(this.layoutDoc.color, 'black'),
-                        fontSize: StrCast(this.layoutDoc._text_fontSize),
-                        letterSpacing: StrCast(this.layoutDoc.letterSpacing),
-                    }}>
-                    <Slider mode={2} step={Math.min(1, 0.1 * (domain[1] - domain[0]))} domain={domain} rootStyle={{ position: 'relative', width: '100%' }} onChange={this.onChange} values={defaultValues}>
-                        <Rail>{railProps => <TooltipRail {...railProps} />}</Rail>
-                        <Handles>
-                            {({ handles, activeHandleID, getHandleProps }) => (
-                                <div className="slider-handles">
-                                    {handles.map((handle, i) => {
-                                        const value = i === 0 ? defaultValues[0] : defaultValues[1];
-                                        return (
-                                            <div title={String(value)}>
-                                                <Handle key={handle.id} handle={handle} domain={domain} isActive={handle.id === activeHandleID} getHandleProps={getHandleProps} />
-                                            </div>
-                                        );
-                                    })}
-                                </div>
-                            )}
-                        </Handles>
-                        <Tracks left={false} right={false}>
-                            {({ tracks, getTrackProps }) => (
-                                <div className="slider-tracks">
-                                    {tracks.map(({ id, source, target }) => (
-                                        <Track key={id} source={source} target={target} disabled={false} getTrackProps={getTrackProps} />
-                                    ))}
-                                </div>
-                            )}
-                        </Tracks>
-                        <Ticks count={5}>
-                            {({ ticks }) => (
-                                <div className="slider-ticks">
-                                    {ticks.map(tick => (
-                                        <Tick key={tick.id} tick={tick} count={ticks.length} format={(val: number) => val.toString()} />
-                                    ))}
-                                </div>
-                            )}
-                        </Ticks>
-                    </Slider>
-                </div>
-            </div>
-        );
-    }
-}
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index 75847c100..511c91da0 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -176,7 +176,6 @@
             width: 100%;
             height: 100%;
             transform-origin: top left;
-            overflow: auto;
 
             .webBox-iframe {
                 width: 100%;
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 27c19105f..d4ba7a48f 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -62,10 +62,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     private _searchRef = React.createRef<HTMLInputElement>();
     private _searchString = '';
     private _scrollTimer: any;
+    private _getAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
 
-    private get _getAnchor() {
-        return AnchorMenu.Instance?.GetAnchor;
-    }
     @observable private _webUrl = ''; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't want the src parameter to also change as that would cause an unnecessary re-render.
     @observable private _hackHide = false; // apparently changing the value of the 'sandbox' prop doesn't necessarily apply it to the active iframe.  so thisforces the ifrmae to be rebuilt when allowScripts is toggled
     @observable private _searching: boolean = false;
@@ -186,13 +184,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         this.props.setContentView?.(this); // this tells the DocumentView that this WebBox is the "content" of the document.  this allows the DocumentView to call WebBox relevant methods to configure the UI (eg, show back/forward buttons)
 
         runInAction(() => {
-            this._annotationKeySuffix = () => this._urlHash + '_annotations';
-            const reqdFuncs: { [key: string]: string } = {};
+            this._annotationKeySuffix = () => (this._urlHash ? this._urlHash + '_' : '') + 'annotations';
             // bcz: need to make sure that doc.data_annotations points to the currently active web page's annotations (this could/should be when the doc is created)
-            reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"])`;
-            reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"] = value`;
-            reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_sidebar"])`;
-            DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs);
+            if (this._url) {
+                const reqdFuncs: { [key: string]: string } = {};
+                reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"annotations"])`;
+                reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"annotations"] = value`;
+                reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"sidebar"])`;
+                DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs);
+            }
         });
         this._disposers.urlchange = reaction(
             () => WebCast(this.rootDoc.data),
@@ -264,14 +264,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             const clientRects = selRange.getClientRects();
             for (let i = 0; i < clientRects.length; i++) {
                 const rect = clientRects.item(i);
+                const mainrect = this._url ? { translateX: 0, translateY: 0, scale: 1 } : Utils.GetScreenTransform(this._mainCont.current);
                 if (rect && rect.width !== this._mainCont.current.clientWidth) {
                     const annoBox = document.createElement('div');
                     annoBox.className = 'marqueeAnnotator-annotationBox';
+                    const scale = this._url ? 1 : this.props.ScreenToLocalTransform().Scale;
                     // transforms the positions from screen onto the pdf div
-                    annoBox.style.top = (rect.top + this._mainCont.current.scrollTop).toString();
-                    annoBox.style.left = rect.left.toString();
-                    annoBox.style.width = rect.width.toString();
-                    annoBox.style.height = rect.height.toString();
+                    annoBox.style.top = ((rect.top - mainrect.translateY) * scale + (this._url ? this._mainCont.current.scrollTop : NumCast(this.layoutDoc.layout_scrollTop))).toString();
+                    annoBox.style.left = ((rect.left - mainrect.translateX) * scale).toString();
+                    annoBox.style.width = (rect.width * scale).toString();
+                    annoBox.style.height = (rect.height * scale).toString();
                     this._annotationLayer.current && MarqueeAnnotator.previewNewAnnotation(this._savedAnnotations, this._annotationLayer.current, annoBox, 1);
                 }
             }
@@ -340,7 +342,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             });
         PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.rootDoc);
         anchor.text = ele?.textContent ?? '';
-        anchor.text_html = ele?.innerHTML;
+        anchor.text_html = ele?.innerHTML ?? this._selectionText;
         addAsAnnotation && this.addDocumentWrapper(anchor);
         return anchor;
     };
@@ -362,12 +364,49 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 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._layout_scrollTop) * scale);
                 // Changing which document to add the annotation to (the currently selected WebBox)
-                GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash}_sidebar`);
+                GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash ? this._urlHash + '_' : ''}sidebar`);
                 GPTPopup.Instance.addDoc = this.sidebarAddDocument;
             }
         }
     };
     @action
+    webClipDown = (e: React.PointerEvent) => {
+        const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
+        const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale;
+        const word = getWordAtPoint(e.target, e.clientX, e.clientY);
+        this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.rootDoc);
+        MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
+        e.button !== 2 && (this._marqueeing = [e.clientX, e.clientY]);
+        if (word || (e.target as any)?.className?.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
+            e.stopPropagation();
+            setTimeout(
+                action(() => (this._marqueeing = undefined)),
+                100
+            ); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it.
+        } else {
+            this._isAnnotating = true;
+            this.props.select(false);
+            e.stopPropagation();
+            e.preventDefault();
+        }
+        document.addEventListener('pointerup', this.webClipUp);
+    };
+    webClipUp = (e: PointerEvent) => {
+        document.removeEventListener('pointerup', this.webClipUp);
+        this._getAnchor = AnchorMenu.Instance?.GetAnchor; // need to save AnchorMenu's getAnchor since a subsequent selection on another doc will overwrite this value
+        const sel = window.getSelection();
+        if (sel && !sel.isCollapsed) {
+            const selRange = sel.getRangeAt(0);
+            this._selectionText = sel.toString();
+            AnchorMenu.Instance.setSelectedText(sel.toString());
+            this._textAnnotationCreator = () => this.createTextAnnotation(sel, selRange);
+            AnchorMenu.Instance.jumpTo(e.clientX, e.clientY);
+            // Changing which document to add the annotation to (the currently selected WebBox)
+            GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash ? this._urlHash + '_' : ''}sidebar`);
+            GPTPopup.Instance.addDoc = this.sidebarAddDocument;
+        }
+    };
+    @action
     iframeDown = (e: PointerEvent) => {
         const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
         const scale = (this.props.NativeDimScaling?.() || 1) * mainContBounds.scale;
@@ -396,9 +435,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             ContextMenu.Instance.setIgnoreEvents(true);
         }
     };
-    isFirefox = () => {
-        return 'InstallTrigger' in window; // navigator.userAgent.indexOf("Chrome") !== -1;
-    };
+    isFirefox = () => 'InstallTrigger' in window; // navigator.userAgent.indexOf("Chrome") !== -1;
     iframeClick = () => this._iframeClick;
     iframeScaling = () => 1 / this.props.ScreenToLocalTransform().Scale;
 
@@ -722,10 +759,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         }
     };
     @action finishMarquee = (x?: number, y?: number, e?: PointerEvent) => {
+        this._getAnchor = AnchorMenu.Instance?.GetAnchor;
         this._marqueeing = undefined;
         this._isAnnotating = false;
         this._iframeClick = undefined;
-        const sel = this._iframe?.contentDocument?.getSelection();
+        const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
         if (sel?.empty) sel.empty(); // Chrome
         else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
         if (x !== undefined && y !== undefined) {
@@ -750,7 +788,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         );
         const field = this.rootDoc[this.props.fieldKey];
         if (field instanceof HtmlField) {
-            return <span className="webBox-htmlSpan" contentEditable onPointerDown={e => e.stopPropagation()} dangerouslySetInnerHTML={{ __html: field.html }} />;
+            return <span className="webBox-htmlSpan" ref={r => r && (this._scrollHeight = Number(getComputedStyle(r).height.replace('px', '')))} contentEditable onPointerDown={this.webClipDown} dangerouslySetInnerHTML={{ __html: field.html }} />;
         }
         if (field instanceof WebField) {
             const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl;
@@ -775,7 +813,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     }
 
     addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
-        (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.config_data = new WebField(this._url)));
+        this._url && (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.config_data = new WebField(this._url)));
         return this.addDocument(doc, annotationKey);
     };
 
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 2a3b232bd..383b400c8 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -465,7 +465,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
             const fkey = Doc.LayoutFieldKey(bestTarget);
             const setData = bestTargetView?.ComponentView?.setData;
             if (setData) setData(activeItem.config_data);
-            else Doc.GetProto(bestTarget)[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data;
+            else {
+                const current = Doc.GetProto(bestTarget)[fkey];
+                Doc.GetProto(bestTarget)[fkey + '_' + Date.now()] = current instanceof ObjectField ? current[Copy]() : current;
+                Doc.GetProto(bestTarget)[fkey] = activeItem.config_data instanceof ObjectField ? activeItem.config_data[Copy]() : activeItem.config_data;
+            }
             bestTarget[fkey + '_usePath'] = activeItem.config_usePath;
             setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10);
         }
@@ -2650,7 +2654,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
                                 removeDocument={returnFalse}
                                 dontRegisterView={true}
                                 focus={this.focusElement}
-                                scriptContext={this}
                                 ScreenToLocalTransform={this.getTransform}
                                 AddToMap={this.AddToMap}
                                 RemFromMap={this.RemFromMap}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 2a191477b..23dc084ad 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -82,9 +82,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
     private _ignoreScroll = false;
     private _initialScroll: { loc: Opt<number>; easeFunc: 'linear' | 'ease' | undefined } | undefined;
     private _forcedScroll = true;
-    get _getAnchor() {
-        return AnchorMenu.Instance?.GetAnchor;
-    }
+    _getAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
 
     selectionText = () => this._selectionText;
     selectionContent = () => this._selectionContent;
@@ -400,6 +398,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
 
     @action
     finishMarquee = (x?: number, y?: number) => {
+        this._getAnchor = AnchorMenu.Instance?.GetAnchor;
         this.isAnnotating = false;
         this._marqueeing = undefined;
         this._textSelecting = true;
-- 
cgit v1.2.3-70-g09d2


From 9e642f6957fcda77262f2ef32ec8e05a64fb13f2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 4 Oct 2023 08:04:05 -0400
Subject: using hard-light instead of multiply for blend mode of web clippings
 to better handle white text

---
 src/client/views/nodes/WebBox.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index d4ba7a48f..c4458be75 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1001,7 +1001,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 onPointerDown={this.onMarqueeDown}>
                 <div className="webBox-innerContent" style={{ height: (this._webPageHasBeenRendered && this._scrollHeight) || '100%', pointerEvents }}>
                     {this.content}
-                    {<div style={{ display: DragManager.docsBeingDragged.length ? 'none' : undefined, mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>}
+                    {<div style={{ display: DragManager.docsBeingDragged.length ? 'none' : undefined, mixBlendMode: this._url ? 'multiply' : 'hard-light' }}>{renderAnnotations(this.transparentFilter)}</div>}
                     {renderAnnotations(this.opaqueFilter)}
                     {this.annotationLayer}
                 </div>
-- 
cgit v1.2.3-70-g09d2


From a25c717b7ab09b0cf079d691e89f5a56781f2eeb Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 4 Oct 2023 08:07:15 -0400
Subject: from last

---
 src/client/views/nodes/WebBox.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c4458be75..e71a8fd5a 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -938,6 +938,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 style={{
                     transform: `scale(${this.zoomScaling()})  translate(${-NumCast(this.layoutDoc.freeform_panX)}px, ${-NumCast(this.layoutDoc.freeform_panY)}px)`,
                     height: Doc.NativeHeight(this.Document) || undefined,
+                    mixBlendMode: this._url ? 'multiply' : 'hard-light',
                 }}
                 ref={this._annotationLayer}>
                 {this.inlineTextAnnotations
@@ -1001,7 +1002,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 onPointerDown={this.onMarqueeDown}>
                 <div className="webBox-innerContent" style={{ height: (this._webPageHasBeenRendered && this._scrollHeight) || '100%', pointerEvents }}>
                     {this.content}
-                    {<div style={{ display: DragManager.docsBeingDragged.length ? 'none' : undefined, mixBlendMode: this._url ? 'multiply' : 'hard-light' }}>{renderAnnotations(this.transparentFilter)}</div>}
+                    {<div style={{ display: DragManager.docsBeingDragged.length ? 'none' : undefined, mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>}
                     {renderAnnotations(this.opaqueFilter)}
                     {this.annotationLayer}
                 </div>
-- 
cgit v1.2.3-70-g09d2


From bdfde9c6d25d778985e9956692e0d3ad201a335b Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 4 Oct 2023 08:20:22 -0400
Subject: from last -- test font color to determine which blend mode for
 clippings.

---
 src/Utils.ts                      |  2 +-
 src/client/views/nodes/WebBox.tsx | 21 ++++++++++++++++++---
 2 files changed, 19 insertions(+), 4 deletions(-)

(limited to 'src/client/views/nodes/WebBox.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 9b969081f..b5ca53a33 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -764,7 +764,7 @@ export function lightOrDark(color: any) {
     const col = DashColor(nonAlphaColor).rgb();
     const colsum = col.red() + col.green() + col.blue();
     if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return Colors.DARK_GRAY;
-    else return Colors.WHITE;
+    return Colors.WHITE;
 }
 
 export function getWordAtPoint(elem: any, x: number, y: number): string | undefined {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index e71a8fd5a..af20ff061 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -13,7 +13,7 @@ import { listSpec } from '../../../fields/Schema';
 import { Cast, ImageCast, NumCast, StrCast, WebCast } from '../../../fields/Types';
 import { ImageField, WebField } from '../../../fields/URLField';
 import { TraceMobx } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, getWordAtPoint, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, Utils } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager } from '../../util/DragManager';
@@ -777,6 +777,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         }
     };
 
+    @observable lighttext = false;
+
     @computed get urlContent() {
         setTimeout(
             action(() => {
@@ -788,7 +790,20 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         );
         const field = this.rootDoc[this.props.fieldKey];
         if (field instanceof HtmlField) {
-            return <span className="webBox-htmlSpan" ref={r => r && (this._scrollHeight = Number(getComputedStyle(r).height.replace('px', '')))} contentEditable onPointerDown={this.webClipDown} dangerouslySetInnerHTML={{ __html: field.html }} />;
+            return (
+                <span
+                    className="webBox-htmlSpan"
+                    ref={action((r: any) => {
+                        if (r) {
+                            this._scrollHeight = Number(getComputedStyle(r).height.replace('px', ''));
+                            this.lighttext = Array.from(r.children).some((c: any) => c instanceof HTMLElement && lightOrDark(getComputedStyle(c).color) !== Colors.WHITE);
+                        }
+                    })}
+                    contentEditable
+                    onPointerDown={this.webClipDown}
+                    dangerouslySetInnerHTML={{ __html: field.html }}
+                />
+            );
         }
         if (field instanceof WebField) {
             const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl;
@@ -938,7 +953,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 style={{
                     transform: `scale(${this.zoomScaling()})  translate(${-NumCast(this.layoutDoc.freeform_panX)}px, ${-NumCast(this.layoutDoc.freeform_panY)}px)`,
                     height: Doc.NativeHeight(this.Document) || undefined,
-                    mixBlendMode: this._url ? 'multiply' : 'hard-light',
+                    mixBlendMode: this._url || !this.lighttext ? 'multiply' : 'hard-light',
                 }}
                 ref={this._annotationLayer}>
                 {this.inlineTextAnnotations
-- 
cgit v1.2.3-70-g09d2

