diff options
author | ab <abdullah_ahmed@brown.edu> | 2019-07-02 14:32:10 -0400 |
---|---|---|
committer | ab <abdullah_ahmed@brown.edu> | 2019-07-02 14:32:10 -0400 |
commit | bd03aebc435d07983d7100787b41028a3673fd98 (patch) | |
tree | 552b01e1abfc637edfb07e21525f9b18d5c41800 /src | |
parent | c2e03a9dfe8910a15ab1b8d3d2af77a5bb82a12d (diff) |
idk
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 62 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.tsx | 28 |
4 files changed, 84 insertions, 12 deletions
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index e72e3cf5e..36be0398c 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -596,7 +596,7 @@ export class TooltipTextMenu { return found; } - highlightSearchTerms = (terms: String[]) => { + public highlightSearchTerms = (terms: String[]) => { const doc = this.view.state.doc; const mark = this.view.state.schema.mark(this.view.state.schema.marks.search_highlight); doc.nodesBetween(0, doc.content.size, (node: ProsNode, pos: number, parent: ProsNode, index: number) => { @@ -616,7 +616,7 @@ export class TooltipTextMenu { }); } - unhighlightSearchTerms = () => { + public unhighlightSearchTerms = () => { const doc = this.view.state.doc; const mark = this.view.state.schema.mark(this.view.state.schema.marks.search_highlight); doc.nodesBetween(0, doc.content.size, (node: ProsNode, pos: number, parent: ProsNode, index: number) => { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 07cd43ce3..83d1917a2 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -1,11 +1,12 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faEdit, faSmile } from '@fortawesome/free-solid-svg-icons'; -import { action, IReactionDisposer, observable, reaction, runInAction, computed } from "mobx"; +import { action, IReactionDisposer, observable, reaction, runInAction, computed, Lambda } from "mobx"; import { observer } from "mobx-react"; import { baseKeymap } from "prosemirror-commands"; import { history } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { NodeType } from 'prosemirror-model'; +import { Node as ProsNode } from "prosemirror-model"; import { EditorState, Plugin, Transaction } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc, Opt } from "../../../new_fields/Doc"; @@ -33,6 +34,7 @@ import { Templates } from '../Templates'; import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); +import { For } from 'babel-types'; library.add(faEdit); library.add(faSmile); @@ -60,14 +62,16 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe public static LayoutString(fieldStr: string = "data") { return FieldView.LayoutString(FormattedTextBox, fieldStr); } + public static Instance: FormattedTextBox; private _ref: React.RefObject<HTMLDivElement>; private _outerdiv?: (dominus: HTMLElement) => void; private _proseRef?: HTMLDivElement; private _editorView: Opt<EditorView>; - private _toolTipTextMenu: TooltipTextMenu | undefined = undefined; + private static _toolTipTextMenu: TooltipTextMenu | undefined = undefined; private _applyingChange: boolean = false; private _linkClicked = ""; private _reactionDisposer: Opt<IReactionDisposer>; + private _searchReactionDisposer?: Lambda; private _proxyReactionDisposer: Opt<IReactionDisposer>; private dropDisposer?: DragManager.DragDropDisposer; public get CurrentDiv(): HTMLDivElement { return this._ref.current!; } @@ -97,8 +101,14 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe return ""; } + public static getToolTip() { + return this._toolTipTextMenu; + + } + constructor(props: FieldViewProps) { super(props); + FormattedTextBox.Instance = this; if (this.props.outer_div) { this._outerdiv = this.props.outer_div; } @@ -129,6 +139,42 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } + public highlightSearchTerms = (terms: String[]) => { + if (this._editorView) { + const doc = this._editorView.state.doc; + const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight); + doc.nodesBetween(0, doc.content.size, (node: ProsNode, pos: number, parent: ProsNode, index: number) => { + if (node.isLeaf && node.isText && node.text) { + let nodeText: String = node.text; + let tokens = nodeText.split(" "); + let start = pos; + tokens.forEach((word) => { + if (terms.includes(word) && this._editorView) { + this._editorView.dispatch(this._editorView.state.tr.addMark(start, start + word.length, mark).removeStoredMark(mark)); + } + else { + start += word.length + 1; + } + }); + } + }); + } + } + + public unhighlightSearchTerms = () => { + if (this._editorView) { + const doc = this._editorView.state.doc; + const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight); + doc.nodesBetween(0, doc.content.size, (node: ProsNode, pos: number, parent: ProsNode, index: number) => { + if (node.isLeaf && node.isText && node.text) { + if (node.marks.includes(mark) && this._editorView) { + this._editorView.dispatch(this._editorView.state.tr.removeMark(pos, pos + node.nodeSize, mark)); + } + } + }); + } + } + protected createDropTarget = (ele: HTMLDivElement) => { this._proseRef = ele; if (this.dropDisposer) { @@ -206,6 +252,12 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe }, { fireImmediately: true }); } + this._searchReactionDisposer = reaction(() => { + return StrCast(this.props.Document.search_string); + }, searchString => { + this.highlightSearchTerms([searchString]); + }); + this._reactionDisposer = reaction( () => { const field = this.dataDoc ? Cast(this.dataDoc[this.props.fieldKey], RichTextField) : undefined; @@ -266,7 +318,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe onPointerDown = (e: React.PointerEvent): void => { if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { e.stopPropagation(); - if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) { + if (FormattedTextBox._toolTipTextMenu && FormattedTextBox._toolTipTextMenu.tooltip) { //this._toolTipTextMenu.tooltip.style.opacity = "0"; } } @@ -301,7 +353,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } onPointerUp = (e: React.PointerEvent): void => { - if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) { + if (FormattedTextBox._toolTipTextMenu && FormattedTextBox._toolTipTextMenu.tooltip) { //this._toolTipTextMenu.tooltip.style.opacity = "1"; } if (e.buttons === 1 && this.props.isSelected() && !e.altKey) { @@ -341,7 +393,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe tooltipTextMenuPlugin() { let myprops = this.props; - let self = this; + let self = FormattedTextBox; return new Plugin({ view(_editorView) { return self._toolTipTextMenu = new TooltipTextMenu(_editorView, myprops); diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index dc21e4a3c..2582c0d94 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -192,7 +192,7 @@ export class SearchBox extends React.Component { </div> <div className="searchBox-results" style={this._resultsOpen ? { display: "flex" } : { display: "none" }}> {(this._results.length !== 0) ? ( - this._results.map(result => <SearchItem doc={result} key={result[Id]} />) + this._results.map(result => <SearchItem doc={result} query={this._searchString} key={result[Id]} />) ) : this._openNoResults ? (<div className="no-result">No Search Results</div>) : null} </div> diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index f4ea3ee09..d2e57c5ca 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -21,9 +21,14 @@ import { DocumentView } from "../nodes/DocumentView"; import { SearchBox } from "./SearchBox"; import "./SearchItem.scss"; import "./SelectorContextMenu.scss"; +import { RichTextField } from "../../../new_fields/RichTextField"; +import { FormattedTextBox } from "../nodes/FormattedTextBox"; +import { MarqueeView } from "../collections/collectionFreeForm/MarqueeView"; +import { SelectionManager } from "../../util/SelectionManager"; export interface SearchItemProps { doc: Doc; + query?: string; } library.add(faCaretUp); @@ -120,8 +125,8 @@ export class LinkContextMenu extends React.Component<LinkMenuProps> { return ( <div className="parents"> <p className="contexts">Anchors:</p> - <div className = "collection"><a onMouseEnter = {this.highlightDoc(this.props.doc1)} onMouseLeave = {this.unHighlightDoc(this.props.doc1)} onClick = {this.getOnClick(this.props.doc1)}>Doc 1: {this.props.doc2.title}</a></div> - <div><a onMouseEnter = {this.highlightDoc(this.props.doc2)} onMouseLeave = {this.unHighlightDoc(this.props.doc2)} onClick = {this.getOnClick(this.props.doc2)}>Doc 2: {this.props.doc1.title}</a></div> + <div className="collection"><a onMouseEnter={this.highlightDoc(this.props.doc1)} onMouseLeave={this.unHighlightDoc(this.props.doc1)} onClick={this.getOnClick(this.props.doc1)}>Doc 1: {this.props.doc2.title}</a></div> + <div><a onMouseEnter={this.highlightDoc(this.props.doc2)} onMouseLeave={this.unHighlightDoc(this.props.doc2)} onClick={this.getOnClick(this.props.doc2)}>Doc 2: {this.props.doc1.title}</a></div> </div> ) } @@ -135,10 +140,25 @@ export class SearchItem extends React.Component<SearchItemProps> { onClick = () => { DocumentManager.Instance.jumpToDocument(this.props.doc, false); + if (this.props.doc.data instanceof RichTextField) { + this.highlightTextBox(this.props.doc); + } } @observable _useIcons = true; @observable _displayDim = 50; + highlightTextBox = (doc: Doc) => { + if (this.props.query) { + doc.search_string = this.props.query; + // FormattedTextBox.Instance.highlightSearchTerms([this.props.query]); + } + else { + // FormattedTextBox.Instance.highlightSearchTerms(["hello"]); + doc.search_string = "hello"; + } + } + + @computed public get DocumentIcon() { let layoutresult = StrCast(this.props.doc.type); @@ -282,8 +302,8 @@ export class SearchItem extends React.Component<SearchItemProps> { </div> </div> <div className="searchBox-instances"> - {this.props.doc.type === DocTypes.LINK ? <LinkContextMenu doc1 = {Cast(this.props.doc.anchor1, Doc, new Doc())} doc2 = {Cast(this.props.doc.anchor2, Doc, new Doc())}/> : - <SelectorContextMenu {...this.props} /> } + {this.props.doc.type === DocTypes.LINK ? <LinkContextMenu doc1={Cast(this.props.doc.anchor1, Doc, new Doc())} doc2={Cast(this.props.doc.anchor2, Doc, new Doc())} /> : + <SelectorContextMenu {...this.props} />} </div> </div> ); |