From 38cee0f811b7e2686fd75516d33c0ebfa7e1a2a1 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 25 Aug 2020 00:05:25 -0400
Subject: added URL for web pages and fixed forward/backward in menu bar. 
 Fixed Go to reload web page.

---
 src/client/views/collections/CollectionMenu.tsx | 191 +++++++++++-------------
 1 file changed, 87 insertions(+), 104 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 3004176a0..80b4a3cd0 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -5,7 +5,7 @@ import { Tooltip } from "@material-ui/core";
 import { action, computed, Lambda, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { ColorState } from "react-color";
-import { Doc, DocListCast, Opt } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, Field } from "../../../fields/Doc";
 import { Document } from "../../../fields/documentSchemas";
 import { Id } from "../../../fields/FieldSymbols";
 import { InkTool } from "../../../fields/InkField";
@@ -404,6 +404,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
     onAliasButtonDown = (e: React.PointerEvent): void => {
         setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction);
     }
+
     @undoBatch
     onAliasButtonMoved = (e: PointerEvent) => {
         if (this._dragRef.current && this.selectedDoc) {
@@ -702,15 +703,14 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
             </div>;
     }
 
-    @action
     onUrlDrop = (e: React.DragEvent) => {
         const { dataTransfer } = e;
         const html = dataTransfer.getData("text/html");
         const uri = dataTransfer.getData("text/uri-list");
         const url = uri || html || this._url;
-        this._url = url.startsWith(window.location.origin) ?
+        const newurl = url.startsWith(window.location.origin) ?
             url.replace(window.location.origin, this._url.match(/http[s]?:\/\/[^\/]*/)?.[0] || "") : url;
-        this.submitURL();
+        this.submitURL(newurl);
         e.stopPropagation();
     }
     onUrlDragover = (e: React.DragEvent) => {
@@ -718,34 +718,45 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
     }
 
     @computed get _url() {
-        return this.selectedDoc ? Cast(this.selectedDoc.data, WebField, null)?.url.toString() : "hello";
+        return this.selectedDoc?.data instanceof WebField ? Cast(this.selectedDoc.data, WebField, null)?.url.toString() : Field.toString(this.selectedDoc?.data as Field);
     }
 
-    set _url(value) { this.selectedDoc && (this.selectedDoc.data = value); }
+    set _url(value) {
+        if (this.selectedDoc) {
+            Doc.GetProto(this.selectedDoc).data = new WebField(value);
+        }
+    }
 
     @action
-    submitURL = () => {
-        if (!this._url.startsWith("http")) this._url = "http://" + this._url;
+    submitURL = (url: string) => {
+        if (!url.startsWith("http")) url = "http://" + url;
         try {
-            const URLy = new URL(this._url);
-            const future = this.selectedDoc ? Cast(this.selectedDoc["data-future"], listSpec("string"), null) : null;
-            const history = this.selectedDoc ? Cast(this.selectedDoc["data-history"], listSpec("string"), null) : [];
-            const annos = this.selectedDoc ? DocListCast(this.selectedDoc["data-annotations"]) : undefined;
-            const url = this.selectedDoc ? Cast(this.selectedDoc.data, WebField, null)?.url.toString() : null;
-            if (url) {
-                if (history === undefined) {
-                    this.selectedDoc && (this.selectedDoc["data-history"] = new List<string>([url]));
-
+            const selectedDoc = this.selectedDoc;
+            if (selectedDoc) {
+                const URLy = new URL(url);
+                const future = Cast(selectedDoc["data-future"], listSpec("string"), null);
+                const history = Cast(selectedDoc["data-history"], listSpec("string"), null);
+                const annos = DocListCast(selectedDoc["data-annotations"]);
+                if (Field.toString(selectedDoc.data as Field) === Field.toString(new WebField(URLy))) {
+                    Doc.GetProto(selectedDoc).data = undefined;
+                    setTimeout(action(() => Doc.GetProto(selectedDoc).data = new WebField(URLy)), 0);
                 } else {
-                    history.push(url);
+                    if (url) {
+                        Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(this._url)] = new List<Doc>(annos);
+                        if (history === undefined) {
+                            selectedDoc["data-history"] = new List<string>([this._url]);
+                        } else {
+                            history.push(this._url);
+                        }
+                        future && (future.length = 0);
+                    }
+                    Doc.GetProto(selectedDoc).data = new WebField(URLy);
+                    const annots = Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(url)];
+                    Doc.GetProto(selectedDoc)["data-annotations"] = annots instanceof ObjectField ? ObjectField.MakeCopy(annots) : new List<Doc>([]);
                 }
-                future && (future.length = 0);
-                this.selectedDoc && (this.selectedDoc["data-" + this.urlHash(url)] = new List<Doc>(annos));
             }
-            this.selectedDoc && (this.selectedDoc.data = new WebField(URLy));
-            this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>([]));
         } catch (e) {
-            console.log("WebBox URL error:" + this._url);
+            console.log("WebBox URL error:" + url);
         }
     }
 
@@ -753,44 +764,41 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
         return s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0);
     }
 
-    toggleAnnotationMode = () => {
-        this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating;
-    }
-
-    @action
-    onURLChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-        this._url = e.target.value;
-    }
-
     onValueKeyDown = async (e: React.KeyboardEvent) => {
-        if (e.key === "Enter") {
-            this.submitURL();
-        }
+        e.key === "Enter" && this.submitURL(this._keyInput.current!.value);
         e.stopPropagation();
     }
 
     @action
     forward = () => {
-        const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null));
-        const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null);
-        if (future?.length) {
-            history?.push(this._url);
-            this.selectedDoc && (this.selectedDoc["data-annotations-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations"])));
-            this.selectedDoc && (this.selectedDoc.data = new WebField(new URL(this._url = future.pop()!)));
-            this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)])));
+        const selectedDoc = this.selectedDoc;
+        if (selectedDoc) {
+            const future = Cast(selectedDoc["data-future"], listSpec("string"), null);
+            const history = Cast(selectedDoc["data-history"], listSpec("string"), null);
+            if (future?.length) {
+                history?.push(this._url);
+                Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(selectedDoc["data-annotations"]));
+                const newurl = future.pop()!;
+                Doc.GetProto(selectedDoc).data = new WebField(new URL(this._url = newurl));
+                Doc.GetProto(selectedDoc)["data-annotations"] = new List<Doc>(DocListCast(selectedDoc["data-annotations-" + this.urlHash(newurl)]));
+            }
         }
     }
 
     @action
     back = () => {
-        const future = this.selectedDoc && (Cast(this.selectedDoc["data-future"], listSpec("string"), null));
-        const history = this.selectedDoc && Cast(this.selectedDoc["data-history"], listSpec("string"), null);
-        if (history?.length) {
-            if (future === undefined) this.selectedDoc && (this.selectedDoc["data-future"] = new List<string>([this._url]));
-            else future.push(this._url);
-            this.selectedDoc && (this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations"])));
-            this.selectedDoc && (this.selectedDoc.data = new WebField(new URL(this._url = history.pop()!)));
-            this.selectedDoc && (this.selectedDoc["data-annotations"] = new List<Doc>(DocListCast(this.selectedDoc["data-annotations" + "-" + this.urlHash(this._url)])));
+        const selectedDoc = this.selectedDoc;
+        if (selectedDoc) {
+            const future = Cast(selectedDoc["data-future"], listSpec("string"), null);
+            const history = Cast(selectedDoc["data-history"], listSpec("string"), null);
+            if (history?.length) {
+                if (future === undefined) selectedDoc["data-future"] = new List<string>([this._url]);
+                else future.push(this._url);
+                Doc.GetProto(selectedDoc)["data-annotations-" + this.urlHash(this._url)] = new List<Doc>(DocListCast(selectedDoc["data-annotations"]));
+                const newurl = history.pop()!;
+                Doc.GetProto(selectedDoc).data = new WebField(new URL(this._url = newurl));
+                Doc.GetProto(selectedDoc)["data-annotations"] = new List<Doc>(DocListCast(selectedDoc["data-annotations-" + this.urlHash(newurl)]));
+            }
         }
     }
 
@@ -798,56 +806,31 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
 
     @computed get urlEditor() {
         return (
-            <div className="webBox-urlEditor"
+            <div className="webBox-buttons"
                 onDrop={this.onUrlDrop}
-                onDragOver={this.onUrlDragover} style={{ top: 0 }}>
-                <div className="urlEditor">
-                    <div className="editorBase">
-                        <div className="webBox-buttons"
-                            onDrop={this.onUrlDrop}
-                            onDragOver={this.onUrlDragover} style={{ display: "flex" }}>
-                            <div className="webBox-freeze" title={"Annotate"}
-                                style={{ background: this.props.docView.layoutDoc.isAnnotating ? "lightBlue" : "gray" }}
-                                onClick={this.toggleAnnotationMode} >
-                                <FontAwesomeIcon icon="pen" size={"2x"} />
-                            </div>
-                            <div className="webBox-freeze" title={"Select"}
-                                style={{ background: !this.props.docView.layoutDoc.isAnnotating ? "lightBlue" : "gray" }}
-                                onClick={this.toggleAnnotationMode} >
-                                <FontAwesomeIcon icon={"mouse-pointer"} size={"2x"} />
-                            </div>
-                            <input className="webpage-urlInput"
-                                placeholder="ENTER URL"
-                                value={this._url}
-                                onDrop={this.onUrlDrop}
-                                onDragOver={this.onUrlDragover}
-                                onChange={this.onURLChange}
-                                onKeyDown={this.onValueKeyDown}
-                                onClick={(e) => {
-                                    this._keyInput.current!.select();
-                                    e.stopPropagation();
-                                }}
-                                ref={this._keyInput}
-                            />
-                            <div style={{
-                                display: "flex",
-                                flexDirection: "row",
-                                justifyContent: "space-between",
-                                maxWidth: "120px",
-                            }}>
-                                <button className="submitUrl" onClick={this.submitURL}
-                                    onDragOver={this.onUrlDragover} onDrop={this.onUrlDrop}>
-                                    GO
-                                </button>
-                                <button className="submitUrl" onClick={this.back}>
-                                    <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
-                                </button>
-                                <button className="submitUrl" onClick={this.forward}>
-                                    <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
-                                </button>
-                            </div>
-                        </div>
-                    </div>
+                onDragOver={this.onUrlDragover} style={{ display: "flex" }}>
+                <input className="webpage-urlInput"
+                    placeholder="ENTER URL"
+                    defaultValue={this._url}
+                    onDrop={this.onUrlDrop}
+                    onDragOver={this.onUrlDragover}
+                    onKeyDown={this.onValueKeyDown}
+                    onClick={(e) => {
+                        this._keyInput.current!.select();
+                        e.stopPropagation();
+                    }}
+                    ref={this._keyInput}
+                />
+                <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", maxWidth: "250px", }}>
+                    <button className="submitUrl" onClick={() => this.submitURL(this._keyInput.current!.value)} onDragOver={this.onUrlDragover} onDrop={this.onUrlDrop}>
+                        GO
+                    </button>
+                    <button className="submitUrl" onClick={this.back}>
+                        <FontAwesomeIcon icon="caret-left" size="lg"></FontAwesomeIcon>
+                    </button>
+                    <button className="submitUrl" onClick={this.forward}>
+                        <FontAwesomeIcon icon="caret-right" size="lg"></FontAwesomeIcon>
+                    </button>
                 </div>
             </div>
         );
@@ -884,20 +867,20 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu
                 </Tooltip> : null}
 
                 {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) :
-                    <Tooltip key="hypothesis" title={<div className="dash-tooltip">Use Hypothesis</div>} placement="bottom">
+                    <Tooltip key="hypothesis" title={<div className="dash-tooltip">Toggle between native iframe and annotation modes</div>} placement="bottom">
                         <button className={"antimodeMenu-button"} key="hypothesis"
                             style={{
-                                backgroundColor: !this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined,
+                                backgroundColor: this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined,
                                 borderRight: "1px solid gray"
                             }}
                             onClick={() => this.props.docView.layoutDoc.isAnnotating = !this.props.docView.layoutDoc.isAnnotating}>
-                            <FontAwesomeIcon icon={["fab", "hire-a-helper"]} size={"lg"} />
+                            <FontAwesomeIcon icon={"edit"} size="lg" />    {/* ["fab", "hire-a-helper"]} size={"lg"} /> */}
                         </button>
                     </Tooltip>
                 }
-                {/* {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) :
+                {!this.props.isOverlay || this.document.type !== DocumentType.WEB || this.isText || this.props.isDoc ? (null) :
                     this.urlEditor
-                } */}
+                }
                 {!this.isText ?
                     <>
                         {this.drawButtons}
-- 
cgit v1.2.3-70-g09d2

