diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 29 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 32 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss | 5 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 16 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 10 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 17 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 57 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValuePair.scss | 40 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValuePair.tsx | 47 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.scss | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 35 |
12 files changed, 170 insertions, 130 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 77f41105f..b00cefbf6 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -1,4 +1,4 @@ -import { computed } from "mobx"; +import { computed, trace } from "mobx"; import { observer } from "mobx-react"; import { KeyStore } from "../../../fields/KeyStore"; import { NumberField } from "../../../fields/NumberField"; @@ -6,28 +6,26 @@ import { Transform } from "../../util/Transform"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import React = require("react"); -import { thisExpression } from "babel-types"; +import { OmitKeys } from "../../../Utils"; +export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { + zoomFade: number; +} @observer -export class CollectionFreeFormDocumentView extends React.Component<DocumentViewProps> { +export class CollectionFreeFormDocumentView extends React.Component<CollectionFreeFormDocumentViewProps> { private _mainCont = React.createRef<HTMLDivElement>(); - constructor(props: DocumentViewProps) { + constructor(props: CollectionFreeFormDocumentViewProps) { super(props); } - get screenRect(): ClientRect | DOMRect { - if (this._mainCont.current) { - return this._mainCont.current.getBoundingClientRect(); - } - return new DOMRect(); - } @computed get transform(): string { - return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`; + return `scale(${this.props.ContentScaling()}, ${this.props.ContentScaling()}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px) scale(${this.zoom}, ${this.zoom}) `; } + @computed get zoom(): number { return 1 / this.props.Document.GetNumber(KeyStore.Zoom, 1); } @computed get zIndex(): number { return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } @computed get width(): number { return this.props.Document.Width(); } @computed get height(): number { return this.props.Document.Height(); } @@ -57,23 +55,28 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView getTransform = (): Transform => this.props.ScreenToLocalTransform() .translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)) - .scale(1 / this.contentScaling()) + .scale(1 / this.contentScaling()).scale(1 / this.zoom) @computed get docView() { - return <DocumentView {...this.props} + return <DocumentView {...this.docViewProps} ContentScaling={this.contentScaling} ScreenToLocalTransform={this.getTransform} PanelWidth={this.panelWidth} PanelHeight={this.panelHeight} />; } + @computed + get docViewProps(): DocumentViewProps { + return (OmitKeys(this.props, ['zoomFade'])); + } panelWidth = () => this.props.Document.GetBoolean(KeyStore.Minimized, false) ? 10 : this.props.PanelWidth(); panelHeight = () => this.props.Document.GetBoolean(KeyStore.Minimized, false) ? 10 : this.props.PanelHeight(); render() { return ( <div className="collectionFreeFormDocumentView-container" ref={this._mainCont} style={{ + opacity: this.props.zoomFade, transformOrigin: "left top", transform: this.transform, pointerEvents: "all", diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 5836da396..76f852601 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -23,7 +23,7 @@ import { HistogramBox } from "../../northstar/dash-nodes/HistogramBox"; import React = require("react"); import { Document } from "../../../fields/Document"; import { FieldViewProps } from "./FieldView"; -import { Without } from "../../../Utils"; +import { Without, OmitKeys } from "../../../Utils"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without<FieldViewProps, 'fieldKey'>; @@ -44,34 +44,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { CreateBindings(): JsxBindings { - let - { - Document, - isSelected, - select, - isTopMost, - selectOnLoad, - ScreenToLocalTransform, - addDocument, - removeDocument, - onActiveChanged, - parentActive: active, - } = this.props; - let bindings: JsxBindings = { - props: { - Document, - isSelected, - select, - isTopMost, - selectOnLoad, - ScreenToLocalTransform, - active, - onActiveChanged, - addDocument, - removeDocument, - focus, - } - }; + let bindings: JsxBindings = { props: OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive) }; + for (const key of this.layoutKeys) { bindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data } diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index a946ac1a8..5071c9440 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -1,6 +1,6 @@ @import "../globalCssVariables"; -.documentView-node { +.documentView-node .documentView-node-topMost { position: inherit; top: 0; left:0; @@ -28,6 +28,9 @@ height: calc(100% - 20px); } } +.documentView-node-topMost { + background: white; +} .minimized-box { height: 10px; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 4d7a85316..20592894f 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1,30 +1,32 @@ -import { action, computed, IReactionDisposer, reaction, runInAction, trace } from "mobx"; +import { action, computed, runInAction } from "mobx"; import { observer } from "mobx-react"; +import { BooleanField } from "../../../fields/BooleanField"; import { Document } from "../../../fields/Document"; import { Field, FieldWaiting, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { BooleanField } from "../../../fields/BooleanField"; import { TextField } from "../../../fields/TextField"; import { ServerUtils } from "../../../server/ServerUtil"; -import { Utils, emptyFunction } from "../../../Utils"; +import { emptyFunction, Utils } from "../../../Utils"; import { Documents } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; +import { undoBatch, UndoManager } from "../../util/UndoManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; +import { CollectionPDFView } from "../collections/CollectionPDFView"; +import { CollectionVideoView } from "../collections/CollectionVideoView"; import { CollectionView } from "../collections/CollectionView"; import { ContextMenu } from "../ContextMenu"; import { DocumentContentsView } from "./DocumentContentsView"; import "./DocumentView.scss"; import React = require("react"); -import { undoBatch, UndoManager } from "../../util/UndoManager"; export interface DocumentViewProps { - ContainingCollectionView: Opt<CollectionView>; + ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>; Document: Document; addDocument?: (doc: Document, allowDuplicates?: boolean) => boolean; removeDocument?: (doc: Document) => boolean; @@ -210,7 +212,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { } } fullScreenClicked = (e: React.MouseEvent): void => { - CollectionDockingView.Instance.OpenFullScreen(this.props.Document); + CollectionDockingView.Instance.OpenFullScreen((this.props.Document.GetPrototype() as Document).MakeDelegate()); ContextMenu.Instance.clearItems(); ContextMenu.Instance.addItem({ description: "Close Full Screen", @@ -423,7 +425,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { ); return ( <div - className="documentView-node" + className={`documentView-node${this.props.isTopMost ? "-topmost" : ""}`} ref={this._mainCont} style={{ background: backgroundcolor, diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 0037d7b28..ebd25f937 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,7 +1,7 @@ import React = require("react"); import { observer } from "mobx-react"; import { computed } from "mobx"; -import { Field, FieldWaiting, FieldValue } from "../../../fields/Field"; +import { Field, FieldWaiting, FieldValue, Opt } from "../../../fields/Field"; import { Document } from "../../../fields/Document"; import { TextField } from "../../../fields/TextField"; import { NumberField } from "../../../fields/NumberField"; @@ -19,7 +19,10 @@ import { ListField } from "../../../fields/ListField"; import { DocumentContentsView } from "./DocumentContentsView"; import { Transform } from "../../util/Transform"; import { KeyStore } from "../../../fields/KeyStore"; -import { returnFalse, emptyDocFunction } from "../../../Utils"; +import { returnFalse, emptyDocFunction, emptyFunction, returnOne } from "../../../Utils"; +import { CollectionView } from "../collections/CollectionView"; +import { CollectionPDFView } from "../collections/CollectionPDFView"; +import { CollectionVideoView } from "../collections/CollectionVideoView"; // @@ -29,6 +32,7 @@ import { returnFalse, emptyDocFunction } from "../../../Utils"; // export interface FieldViewProps { fieldKey: Key; + ContainingCollectionView: Opt<CollectionView | CollectionPDFView | CollectionVideoView>; Document: Document; isSelected: () => boolean; select: (isCtrlPressed: boolean) => void; @@ -89,7 +93,7 @@ export class FieldView extends React.Component<FieldViewProps> { isSelected={returnFalse} select={returnFalse} layoutKey={KeyStore.Layout} - ContainingCollectionView={undefined} + ContainingCollectionView={this.props.ContainingCollectionView} parentActive={this.props.active} onActiveChanged={this.props.onActiveChanged} /> ); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 7c4463b92..c380ef650 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -1,4 +1,4 @@ -import { action, IReactionDisposer, reaction } from "mobx"; +import { action, IReactionDisposer, reaction, trace, computed } from "mobx"; import { baseKeymap } from "prosemirror-commands"; import { history, redo, undo } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; @@ -20,6 +20,8 @@ import buildKeymap from "../../util/ProsemirrorKeymap"; import { TextField } from "../../../fields/TextField"; import { KeyStore } from "../../../fields/KeyStore"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; +import { MainOverlayTextBox } from "../MainOverlayTextBox"; +import { observer } from "mobx-react"; const { buildMenuItems } = require("prosemirror-example-setup"); const { menuBar } = require("prosemirror-menu"); @@ -102,7 +104,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte }; if (this.props.isOverlay) { - this._inputReactionDisposer = reaction(() => Main.Instance._textDoc && Main.Instance._textDoc.Id, + this._inputReactionDisposer = reaction(() => MainOverlayTextBox.Instance.TextDoc && MainOverlayTextBox.Instance.TextDoc.Id, () => { if (this._editorView) { this._editorView.destroy(); @@ -113,7 +115,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte ); } else { this._proxyReactionDisposer = reaction(() => this.props.isSelected(), - () => this.props.isSelected() && Main.Instance.SetTextDoc(this.props.Document, this.props.fieldKey, this._ref.current!, this.props.ScreenToLocalTransform())); + () => this.props.isSelected() && MainOverlayTextBox.Instance.SetTextDoc(this.props.Document, this.props.fieldKey, this._ref.current!, this.props.ScreenToLocalTransform())); } this._reactionDisposer = reaction( @@ -197,10 +199,10 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte onFocused = (e: React.FocusEvent): void => { if (!this.props.isOverlay) { - Main.Instance.SetTextDoc(this.props.Document, this.props.fieldKey, this._ref.current!, this.props.ScreenToLocalTransform()); + MainOverlayTextBox.Instance.SetTextDoc(this.props.Document, this.props.fieldKey, this._ref.current!, this.props.ScreenToLocalTransform()); } else { if (this._ref.current) { - this._ref.current.scrollTop = Main.Instance._textScroll; + this._ref.current.scrollTop = MainOverlayTextBox.Instance.TextScroll; } } } @@ -229,7 +231,9 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte } onPointerWheel = (e: React.WheelEvent): void => { - e.stopPropagation(); + if (this.props.isSelected()) { + e.stopPropagation(); + } } tooltipTextMenuPlugin() { @@ -260,6 +264,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte render() { return ( <div + style={{ overflowY: this.props.isSelected() || this.props.isOverlay ? "scroll" : "hidden" }} className={`formattedTextBox-cont`} onKeyDown={this.onKeyPress} onKeyPress={this.onKeyPress} diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 6b0a3a799..9bdbfbb5d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -11,23 +11,27 @@ import { FieldView, FieldViewProps } from './FieldView'; import "./ImageBox.scss"; import React = require("react"); import { Utils } from '../../../Utils'; +import { ListField } from '../../../fields/ListField'; +import { DragManager } from '../../util/DragManager'; +import { undoBatch } from '../../util/UndoManager'; +import { TextField } from '../../../fields/TextField'; +import { Document } from '../../../fields/Document'; @observer export class ImageBox extends React.Component<FieldViewProps> { public static LayoutString() { return FieldView.LayoutString(ImageBox); } - private _ref: React.RefObject<HTMLDivElement>; private _imgRef: React.RefObject<HTMLImageElement>; private _downX: number = 0; private _downY: number = 0; private _lastTap: number = 0; @observable private _photoIndex: number = 0; @observable private _isOpen: boolean = false; + private dropDisposer?: DragManager.DragDropDisposer; constructor(props: FieldViewProps) { super(props); - this._ref = React.createRef(); this._imgRef = React.createRef(); this.state = { photoIndex: 0, @@ -45,9 +49,43 @@ export class ImageBox extends React.Component<FieldViewProps> { componentDidMount() { } + protected createDropTarget = (ele: HTMLDivElement) => { + if (this.dropDisposer) { + this.dropDisposer(); + } + if (ele) { + this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } }); + } + } + componentWillUnmount() { } + + @undoBatch + drop = (e: Event, de: DragManager.DropEvent) => { + if (de.data instanceof DragManager.DocumentDragData) { + de.data.droppedDocuments.map(action((drop: Document) => { + let layout = drop.GetText(KeyStore.BackgroundLayout, ""); + if (layout.indexOf(ImageBox.name) !== -1) { + let imgData = this.props.Document.Get(KeyStore.Data); + if (imgData instanceof ImageField && imgData) { + this.props.Document.Set(KeyStore.Data, new ListField([imgData])); + } + let imgList = this.props.Document.GetList(KeyStore.Data, [] as any[]); + if (imgList) { + let field = drop.Get(KeyStore.Data); + if (field === FieldWaiting) { } + else if (field instanceof ImageField) imgList.push(field); + else if (field instanceof ListField) imgList.push(field.Data); + } + e.stopPropagation(); + } + })) + // de.data.removeDocument() bcz: need to implement + } + } + onPointerDown = (e: React.PointerEvent): void => { if (Date.now() - this._lastTap < 300) { if (e.buttons === 1) { @@ -70,8 +108,7 @@ export class ImageBox extends React.Component<FieldViewProps> { e.stopPropagation(); } - lightbox = (path: string) => { - const images = [path]; + lightbox = (images: string[]) => { if (this._isOpen) { return (<Lightbox mainSrc={images[this._photoIndex]} @@ -104,13 +141,15 @@ export class ImageBox extends React.Component<FieldViewProps> { render() { let field = this.props.Document.Get(this.props.fieldKey); - let path = field === FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : - field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif"; + let paths: string[] = ["http://www.cs.brown.edu/~bcz/face.gif"]; + if (field === FieldWaiting) paths = ["https://image.flaticon.com/icons/svg/66/66163.svg"]; + else if (field instanceof ImageField) paths = [field.Data.href]; + else if (field instanceof ListField) paths = field.Data.filter(val => val as ImageField).map(p => (p as ImageField).Data.href); let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 1); return ( - <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} onContextMenu={this.specificContextMenu}> - <img src={path} width={nativeWidth} alt="Image not found" ref={this._imgRef} onLoad={this.onLoad} /> - {this.lightbox(path)} + <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}> + <img src={paths[0]} width={nativeWidth} alt="Image not found" ref={this._imgRef} onLoad={this.onLoad} /> + {this.lightbox(paths)} </div>); } }
\ No newline at end of file diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 29e4af160..ddbec014b 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -26,12 +26,6 @@ export class KeyValueBox extends React.Component<FieldViewProps> { super(props); } - - - shouldComponentUpdate() { - return false; - } - @action onEnterKey = (e: React.KeyboardEvent): void => { if (e.key === 'Enter') { diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss index 04d002c7b..01701e02c 100644 --- a/src/client/views/nodes/KeyValuePair.scss +++ b/src/client/views/nodes/KeyValuePair.scss @@ -1,30 +1,28 @@ @import "../globalCssVariables"; -.container{ - width:100%; - height:100%; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; -} .keyValuePair-td-key { display:inline-block; - width: 50%; + .keyValuePair-td-key-container{ + width:100%; + height:100%; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: space-between; + .keyValuePair-td-key-delete{ + position: relative; + background-color: transparent; + color:red; + } + .keyValuePair-keyField { + width:100%; + text-align: center; + position: relative; + overflow: auto; + } + } } .keyValuePair-td-value { display:inline-block; - width: 50%; -} -.keyValuePair-keyField { - width:100%; - text-align: center; - position: relative; - overflow: auto; -} -.delete{ - position: relative; - background-color: transparent; - color:red; }
\ No newline at end of file diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 3e0b61c3d..5d69f23b2 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -1,18 +1,18 @@ -import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app -import "./KeyValueBox.scss"; -import "./KeyValuePair.scss"; -import React = require("react"); -import { FieldViewProps, FieldView } from './FieldView'; -import { Opt, Field } from '../../../fields/Field'; +import { action, observable } from 'mobx'; import { observer } from "mobx-react"; -import { observable, action } from 'mobx'; +import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app import { Document } from '../../../fields/Document'; +import { Field, Opt } from '../../../fields/Field'; import { Key } from '../../../fields/Key'; +import { emptyDocFunction, emptyFunction, returnFalse } from '../../../Utils'; import { Server } from "../../Server"; -import { EditableView } from "../EditableView"; import { CompileScript, ToField } from "../../util/Scripting"; import { Transform } from '../../util/Transform'; -import { returnFalse, emptyFunction, emptyDocFunction } from '../../../Utils'; +import { EditableView } from "../EditableView"; +import { FieldView, FieldViewProps } from './FieldView'; +import "./KeyValueBox.scss"; +import "./KeyValuePair.scss"; +import React = require("react"); // Represents one row in a key value plane @@ -25,28 +25,23 @@ export interface KeyValuePairProps { @observer export class KeyValuePair extends React.Component<KeyValuePairProps> { - @observable - private key: Opt<Key>; + @observable private key: Opt<Key>; constructor(props: KeyValuePairProps) { super(props); Server.GetField(this.props.fieldId, - action((field: Opt<Field>) => { - if (field) { - this.key = field as Key; - } - })); + action((field: Opt<Field>) => field instanceof Key && (this.key = field))); } render() { if (!this.key) { - return <tr><td>error</td><td></td></tr>; - + return <tr><td>error</td><td /></tr>; } let props: FieldViewProps = { Document: this.props.doc, + ContainingCollectionView: undefined, fieldKey: this.key, isSelected: returnFalse, select: emptyFunction, @@ -57,19 +52,17 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> { ScreenToLocalTransform: Transform.Identity, focus: emptyDocFunction, }; - let contents = ( - <FieldView {...props} /> - ); + let contents = <FieldView {...props} />; return ( <tr className={this.props.rowStyle}> <td className="keyValuePair-td-key" style={{ width: `${this.props.keyWidth}%` }}> - <div className="container"> - <button className="delete" onClick={() => { + <div className="keyValuePair-td-key-container"> + <button className="keyValuePair-td-key-delete" onClick={() => { let field = props.Document.Get(props.fieldKey); - if (field && field instanceof Field) { - props.Document.Set(props.fieldKey, undefined); - } - }}>X</button> + field && field instanceof Field && props.Document.Set(props.fieldKey, undefined); + }}> + X + </button> <div className="keyValuePair-keyField">{this.key.Name}</div> </div> </td> diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss index c73bc0c47..2ad1129a4 100644 --- a/src/client/views/nodes/WebBox.scss +++ b/src/client/views/nodes/WebBox.scss @@ -9,6 +9,12 @@ overflow: scroll; } +#webBox-htmlSpan { + position: absolute; + top:0; + left:0; +} + .webBox-button { padding : 0vw; border: none; diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 90ce72c41..1edb4d826 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -18,21 +18,40 @@ export class WebBox extends React.Component<FieldViewProps> { @computed get html(): string { return this.props.Document.GetHtml(KeyStore.Data, ""); } + _ignore = 0; + onPreWheel = (e: React.WheelEvent) => { + this._ignore = e.timeStamp; + } + onPrePointer = (e: React.PointerEvent) => { + this._ignore = e.timeStamp; + } + onPostPointer = (e: React.PointerEvent) => { + if (this._ignore !== e.timeStamp) { + e.stopPropagation(); + } + } + onPostWheel = (e: React.WheelEvent) => { + if (this._ignore !== e.timeStamp) { + e.stopPropagation(); + } + } render() { let field = this.props.Document.Get(this.props.fieldKey); let path = field === FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : field instanceof WebField ? field.Data.href : "https://crossorigin.me/" + "https://cs.brown.edu"; - let content = this.html ? - <span dangerouslySetInnerHTML={{ __html: this.html }}></span> : - <div style={{ width: "100%", height: "100%", position: "absolute" }}> - <iframe src={path} style={{ position: "absolute", width: "100%", height: "100%" }}></iframe> - {this.props.isSelected() ? (null) : <div style={{ width: "100%", height: "100%", position: "absolute" }} />} + let content = + <div style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}> + {this.html ? <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: this.html }} /> : + <iframe src={path} style={{ position: "absolute", width: "100%", height: "100%" }} />} </div>; return ( - <div className="webBox-cont" > - {content} - </div>); + <> + <div className="webBox-cont" > + {content} + </div> + {this.props.isSelected() ? (null) : <div onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} style={{ width: "100%", height: "100%", position: "absolute" }} />} + </>); } }
\ No newline at end of file |
