From b6d021af3968c4f066bc0644a74e195226e6e6f1 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 13 Sep 2023 21:42:23 -0400
Subject: added margin and grid gap ui for notetaking view.  fixed notetakeing
 view dividers to be active only when they should be.  same for
 multirow/multicol dividers.

---
 .../views/collections/CollectionNoteTakingView.tsx | 35 +++++++++++-----------
 1 file changed, 18 insertions(+), 17 deletions(-)

(limited to 'src/client/views/collections/CollectionNoteTakingView.tsx')

diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 53a42d2a6..a69049b59 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,10 +1,10 @@
 import React = require('react');
 import { CursorProperty } from 'csstype';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, trace } from 'mobx';
 import { observer } from 'mobx-react';
 import { Doc, Field, Opt } from '../../../fields/Doc';
 import { DocData, Height, Width } from '../../../fields/DocSymbols';
-import { Id } from '../../../fields/FieldSymbols';
+import { Copy, Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { listSpec } from '../../../fields/Schema';
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
@@ -93,7 +93,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     // we use availableWidth to convert from a percentage to a pixel count.
     @computed get availableWidth() {
         const numDividers = this.numGroupColumns - 1;
-        return this.maxColWidth - numDividers * this.DividerWidth;
+        return this.maxColWidth - numDividers * this.DividerWidth - 2 * NumCast(this.layoutDoc.xMargin);
     }
 
     // children is passed as a prop to the NoteTakingField, which uses this function
@@ -216,7 +216,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         return this.props.styleProvider?.(doc, props, property);
     };
 
-    isContentActive = () => this.props.isSelected() || this.props.isContentActive();
+    isContentActive = () => this.props.isContentActive();
 
     blockPointerEventsWhenDragging = () => (this.docsDraggedRowCol.length ? 'none' : undefined);
     // getDisplayDoc returns the rules for displaying a document in this view (ie. DocumentView)
@@ -521,6 +521,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                         this.observer.observe(ref);
                     }
                 }}
+                PanelWidth={this.props.PanelWidth}
                 select={this.props.select}
                 addDocument={this.addDocument}
                 chromeHidden={this.chromeHidden}
@@ -589,6 +590,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         const rightHeader = this.colHeaderData[colIndex + 1];
         leftHeader.setWidth(leftHeader.width + movementX / this.availableWidth);
         rightHeader.setWidth(rightHeader.width - movementX / this.availableWidth);
+        const headers = Cast(this.dataDoc[this.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null);
+        headers.splice(headers.indexOf(leftHeader), 1, leftHeader[Copy]());
     };
 
     // renderedSections returns a list of all of the JSX elements used (columns and dividers). If the view
@@ -596,17 +599,15 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     // allows the user to adjust the column widths.
     @computed get renderedSections() {
         TraceMobx();
-        const entries = Array.from(this.Sections.entries());
-        const sections = entries;
-        const eles: JSX.Element[] = [];
-        for (let i = 0; i < sections.length; i++) {
-            const col = this.sectionNoteTaking(sections[i][0], sections[i][1]);
-            eles.push(col);
-            if (i < sections.length - 1) {
-                eles.push(<CollectionNoteTakingViewDivider key={`divider${i}`} index={i} setColumnStartXCoords={this.setColumnStartXCoords} xMargin={this.xMargin} />);
-            }
-        }
-        return eles;
+        const sections = Array.from(this.Sections.entries());
+        return sections.map((sec, i) => (
+            <>
+                {this.sectionNoteTaking(sec[0], sec[1])}
+                {i === sections.length - 1 ? null : ( //
+                    <CollectionNoteTakingViewDivider key={`divider${i}`} isContentActive={this.isContentActive} index={i} setColumnStartXCoords={this.setColumnStartXCoords} xMargin={this.xMargin} />
+                )}
+            </>
+        ));
     }
 
     @computed get nativeWidth() {
@@ -621,7 +622,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     }
 
     @computed get backgroundEvents() {
-        return this.props.isContentActive() === false ? 'none' : undefined;
+        return this.isContentActive() === false ? 'none' : undefined;
     }
 
     observer: any;
@@ -636,7 +637,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 style={{
                     overflowY: this.props.isContentActive() ? 'auto' : 'hidden',
                     background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
-                    pointerEvents: this.backgroundEvents ? 'all' : undefined,
+                    pointerEvents: this.backgroundEvents,
                 }}
                 onScroll={action(e => (this._scroll = e.currentTarget.scrollTop))}
                 onPointerLeave={action(e => (this.docsDraggedRowCol.length = 0))}
-- 
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/collections/CollectionNoteTakingView.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

