diff options
| author | Mohammad Amoush <47069173+mamoush34@users.noreply.github.com> | 2020-01-19 15:15:53 +0300 |
|---|---|---|
| committer | Mohammad Amoush <47069173+mamoush34@users.noreply.github.com> | 2020-01-19 15:15:53 +0300 |
| commit | 7683e1fbb53fe683c0d04e537d89fb53d768e852 (patch) | |
| tree | d81eebcd5a129550a49fdfc852b8bb6220907a1a /src/client/views/DocumentDecorations.tsx | |
| parent | f4382d73eec75f7d7f4bfe6eae3fb1efa128a021 (diff) | |
| parent | aff9cc02750eb032ade98d77cf9ff45677063fc8 (diff) | |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into webcam_mohammad
Diffstat (limited to 'src/client/views/DocumentDecorations.tsx')
| -rw-r--r-- | src/client/views/DocumentDecorations.tsx | 201 |
1 files changed, 96 insertions, 105 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 719a0203b..bacbcaa97 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -24,6 +24,10 @@ import { DocumentView } from "./nodes/DocumentView"; import { FieldView } from "./nodes/FieldView"; import { IconBox } from "./nodes/IconBox"; import React = require("react"); +import { DocumentType } from '../documents/DocumentTypes'; +import { ScriptField } from '../../new_fields/ScriptField'; +import { render } from 'react-dom'; +import RichTextMenu from '../util/RichTextMenu'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -55,11 +59,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> private _iconDoc?: Doc = undefined; private _resizeUndo?: UndoManager.Batch; private _radiusDown = [0, 0]; + @observable private _accumulatedTitle = ""; @observable private _minimizedX = 0; @observable private _minimizedY = 0; - @observable private _title: string = ""; + @observable private _titleControlString: string = "#title"; @observable private _edtingTitle = false; - @observable private _fieldKey = "title"; @observable private _hidden = false; @observable private _opacity = 1; @observable private _removeIcon = false; @@ -68,8 +72,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @observable public pushIcon: IconProp = "arrow-alt-circle-up"; @observable public pullIcon: IconProp = "arrow-alt-circle-down"; @observable public pullColor: string = "white"; - @observable public isAnimatingFetch = false; - @observable public isAnimatingPulse = false; @observable public openHover = false; @observable private addedCloseCalls: CloseCall[] = []; @@ -78,39 +80,43 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> super(props); DocumentDecorations.Instance = this; this._keyinput = React.createRef(); - reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this._edtingTitle = false); + reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this.titleBlur(false)); } - addCloseCall = (handler: CloseCall) => { - const currentOffset = this.addedCloseCalls.length - 1; - this.addedCloseCalls.push((toBeDeleted: DocumentView[]) => { - this.addedCloseCalls.splice(currentOffset, 1); - handler(toBeDeleted); - }); - } + @action titleChanged = (event: any) => this._accumulatedTitle = event.target.value; + + titleBlur = undoBatch(action((commit: boolean) => { + this._edtingTitle = false; + if (commit) { + if (this._accumulatedTitle.startsWith("#") || this._accumulatedTitle.startsWith("=")) { + this._titleControlString = this._accumulatedTitle; + } else if (this._titleControlString.startsWith("#")) { + const selectionTitleFieldKey = this._titleControlString.substring(1); + selectionTitleFieldKey === "title" && (SelectionManager.SelectedDocuments()[0].props.Document.customTitle = !this._accumulatedTitle.startsWith("-")); + selectionTitleFieldKey && SelectionManager.SelectedDocuments().forEach(d => + Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, typeof d.props.Document[selectionTitleFieldKey] === "number" ? +this._accumulatedTitle : this._accumulatedTitle, true) + ); + } + } + })); - @action titleChanged = (event: any) => { this._title = event.target.value; }; - @action titleBlur = () => { this._edtingTitle = false; }; @action titleEntered = (e: any) => { - var key = e.keyCode || e.which; + const key = e.keyCode || e.which; // enter pressed if (key === 13) { - var text = e.target.value; - if (text[0] === '#') { - this._fieldKey = text.slice(1, text.length); - this._title = this.selectionTitle; - } else if (text.startsWith("::")) { - let targetID = text.slice(2, text.length); - let promoteDoc = SelectionManager.SelectedDocuments()[0]; + const text = e.target.value; + if (text.startsWith("::")) { + const targetID = text.slice(2, text.length); + const promoteDoc = SelectionManager.SelectedDocuments()[0]; DocUtils.Publish(promoteDoc.props.Document, targetID, promoteDoc.props.addDocument, promoteDoc.props.removeDocument); } else if (text.startsWith(">")) { - let fieldTemplateView = SelectionManager.SelectedDocuments()[0]; + const fieldTemplateView = SelectionManager.SelectedDocuments()[0]; SelectionManager.DeselectAll(); - let fieldTemplate = fieldTemplateView.props.Document; - let containerView = fieldTemplateView.props.ContainingCollectionView; - let docTemplate = fieldTemplateView.props.ContainingCollectionDoc; + const fieldTemplate = fieldTemplateView.props.Document; + const containerView = fieldTemplateView.props.ContainingCollectionView; + const docTemplate = fieldTemplateView.props.ContainingCollectionDoc; if (containerView && docTemplate) { - let metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length); + const metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length); if (metaKey !== containerView.props.fieldKey && containerView.props.DataDoc) { const fd = fieldTemplate.data; fd instanceof ObjectField && (Doc.GetProto(containerView.props.DataDoc)[metaKey] = ObjectField.MakeCopy(fd)); @@ -118,24 +124,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> fieldTemplate.title = metaKey; Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate)); if (text.startsWith(">>")) { - Doc.GetProto(docTemplate).layout = StrCast(fieldTemplateView.props.Document.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`); - } - } - } - else { - if (SelectionManager.SelectedDocuments().length > 0) { - SelectionManager.SelectedDocuments()[0].props.Document.customTitle = true; - let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey]; - if (typeof field === "number") { - SelectionManager.SelectedDocuments().forEach(d => { - let doc = d.props.Document.proto ? d.props.Document.proto : d.props.Document; - doc[this._fieldKey] = +this._title; - }); - } else { - SelectionManager.SelectedDocuments().forEach(d => { - let doc = d.props.Document.proto ? d.props.Document.proto : d.props.Document; - doc[this._fieldKey] = this._title; - }); + Doc.GetProto(docTemplate).layout = StrCast(fieldTemplateView.props.Document.layout).replace(/fieldKey={'[^']*'}/, `fieldKey={"${metaKey}"}`); } } } @@ -160,38 +149,37 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } @action onTitleUp = (e: PointerEvent): void => { if (Math.abs(e.clientX - this._downX) < 4 || Math.abs(e.clientY - this._downY) < 4) { - this._title = this.selectionTitle; + !this._edtingTitle && (this._accumulatedTitle = this._titleControlString.startsWith("#") ? this.selectionTitle : this._titleControlString); this._edtingTitle = true; + setTimeout(() => this._keyinput.current!.focus(), 0); } document.removeEventListener("pointermove", this.onTitleMove); document.removeEventListener("pointerup", this.onTitleUp); this.onBackgroundUp(e); } - @observable _forceUpdate = 0; - _lastBox = { x: 0, y: 0, r: 0, b: 0 }; @computed get Bounds(): { x: number, y: number, b: number, r: number } { - let x = this._forceUpdate; - this._lastBox = SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { + return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { if (documentView.props.renderDepth === 0 || Doc.AreProtosEqual(documentView.props.Document, CurrentUserUtils.UserDocument)) { return bounds; } - let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse(); - if (transform.TranslateX === 0 && transform.TranslateY === 0) { - setTimeout(action(() => this._forceUpdate++), 0); // bcz: fix CollectionStackingView's getTransform() somehow...without this, resizing things in the library view, for instance, show the wrong bounds - return this._lastBox; - } - + const transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse(); var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); + if (documentView.props.Document.type === DocumentType.LINK) { + const rect = documentView.ContentDiv!.getElementsByClassName("docuLinkBox-cont")[0].getBoundingClientRect(); + sptX = rect.left; + sptY = rect.top; + bptX = rect.right; + bptY = rect.bottom; + } return { x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y), r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) }; }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); - return this._lastBox; } onBackgroundDown = (e: React.PointerEvent): void => { @@ -204,8 +192,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @action onBackgroundMove = (e: PointerEvent): void => { - let dragDocView = SelectionManager.SelectedDocuments()[0]; - let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); + const dragDocView = SelectionManager.SelectedDocuments()[0]; + const dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0); dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top); dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument; @@ -216,8 +204,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> document.removeEventListener("pointerup", this.onBackgroundUp); document.removeEventListener("pointermove", this.onTitleMove); document.removeEventListener("pointerup", this.onTitleUp); - DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(docView => docView.ContentDiv!), dragData, e.x, e.y, { - handlers: { dragComplete: action(() => this._hidden = this.Interacting = false) }, + DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(documentView => documentView.ContentDiv!), dragData, e.x, e.y, { + dragComplete: action(e => this._hidden = this.Interacting = false), hideSource: true }); e.stopPropagation(); @@ -251,13 +239,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> e.stopPropagation(); if (e.button === 0) { const recent = Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc) as Doc; - const selectedDocuments = SelectionManager.SelectedDocuments(); - selectedDocuments.map(dv => { + const selected = SelectionManager.SelectedDocuments().slice(); + SelectionManager.DeselectAll(); + selected.map(dv => { recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true); dv.props.removeDocument && dv.props.removeDocument(dv.props.Document); }); - this.addedCloseCalls.forEach(handler => handler(selectedDocuments)); - SelectionManager.DeselectAll(); document.removeEventListener("pointermove", this.onCloseMove); document.removeEventListener("pointerup", this.onCloseUp); } @@ -270,8 +257,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this._downX = e.pageX; this._downY = e.pageY; this._removeIcon = false; - let selDoc = SelectionManager.SelectedDocuments()[0]; - let selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); + const selDoc = SelectionManager.SelectedDocuments()[0]; + const selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); this._minimizedX = selDocPos[0] + 12; this._minimizedY = selDocPos[1] + 12; document.removeEventListener("pointermove", this.onMinimizeMove); @@ -286,12 +273,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> e.stopPropagation(); if (Math.abs(e.pageX - this._downX) > Utils.DRAG_THRESHOLD || Math.abs(e.pageY - this._downY) > Utils.DRAG_THRESHOLD) { - let selDoc = SelectionManager.SelectedDocuments()[0]; - let selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); - let snapped = Math.abs(e.pageX - selDocPos[0]) < 20 && Math.abs(e.pageY - selDocPos[1]) < 20; + const selDoc = SelectionManager.SelectedDocuments()[0]; + const selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); + const snapped = Math.abs(e.pageX - selDocPos[0]) < 20 && Math.abs(e.pageY - selDocPos[1]) < 20; this._minimizedX = snapped ? selDocPos[0] + 4 : e.clientX; this._minimizedY = snapped ? selDocPos[1] - 18 : e.clientY; - let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); + const selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); if (selectedDocs.length > 1) { this._iconDoc = this._iconDoc ? this._iconDoc : this.createIcon(SelectionManager.SelectedDocuments(), CollectionView.LayoutString("")); @@ -309,15 +296,15 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (e.button === 0) { document.removeEventListener("pointermove", this.onMinimizeMove); document.removeEventListener("pointerup", this.onMinimizeUp); - let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); + const selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd); if (this._iconDoc && selectedDocs.length === 1 && this._removeIcon) { selectedDocs[0].props.removeDocument && selectedDocs[0].props.removeDocument(this._iconDoc); } if (!this._removeIcon && selectedDocs.length === 1) { // if you click on the top-left button when just 1 doc is selected, then collapse it. not sure why we don't do it for multiple selections this.getIconDoc(selectedDocs[0]).then(async icon => { - let minimizedDoc = await Cast(selectedDocs[0].props.Document.minimizedDoc, Doc); + const minimizedDoc = await Cast(selectedDocs[0].props.Document.minimizedDoc, Doc); if (minimizedDoc) { - let scrpt = selectedDocs[0].props.ScreenToLocalTransform().scale(selectedDocs[0].props.ContentScaling()).inverse().transformPoint( + const scrpt = selectedDocs[0].props.ScreenToLocalTransform().scale(selectedDocs[0].props.ContentScaling()).inverse().transformPoint( NumCast(minimizedDoc.x) - NumCast(selectedDocs[0].Document.x), NumCast(minimizedDoc.y) - NumCast(selectedDocs[0].Document.y)); SelectionManager.DeselectAll(); DocumentManager.Instance.animateBetweenPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs)); @@ -331,8 +318,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @undoBatch @action createIcon = (selected: DocumentView[], layoutString: string): Doc => { - let doc = selected[0].props.Document; - let iconDoc = Docs.Create.IconDocument(layoutString); + const doc = selected[0].props.Document; + const iconDoc = Docs.Create.IconDocument(layoutString); iconDoc.isButton = true; IconBox.AutomaticTitle(iconDoc); @@ -348,7 +335,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } @action public getIconDoc = async (docView: DocumentView): Promise<Doc | undefined> => { - let doc = docView.props.Document; + const doc = docView.props.Document; let iconDoc: Doc | undefined = await Cast(doc.minimizedDoc, Doc); if (!iconDoc || !DocumentManager.Instance.getDocumentView(iconDoc)) { @@ -358,8 +345,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return iconDoc; } moveIconDoc(iconDoc: Doc) { - let selView = SelectionManager.SelectedDocuments()[0]; - let where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()). + const selView = SelectionManager.SelectedDocuments()[0]; + const where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()). transformPoint(this._minimizedX - 12, this._minimizedY - 12); iconDoc.x = where[0] + NumCast(selView.props.Document.x); iconDoc.y = where[1] + NumCast(selView.props.Document.y); @@ -384,8 +371,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> dist = dist < 3 ? 0 : dist; let usingRule = false; SelectionManager.SelectedDocuments().map(dv => { - let ruleProvider = dv.props.ruleProvider; - let heading = NumCast(dv.props.Document.heading); + const ruleProvider = dv.props.ruleProvider; + const heading = NumCast(dv.props.Document.heading); ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`); usingRule = usingRule || (ruleProvider && heading ? true : false); }); @@ -433,8 +420,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let dX = 0, dY = 0, dW = 0, dH = 0; - let moveX = e.clientX - this._lastX; // e.movementX; - let moveY = e.clientY - this._lastY; // e.movementY; + const moveX = e.clientX - this._lastX; // e.movementX; + const moveY = e.clientY - this._lastY; // e.movementY; this._lastX = e.clientX; this._lastY = e.clientY; @@ -477,20 +464,20 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> break; } - SelectionManager.SelectedDocuments().forEach(element => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) { - let doc = PositionDocument(element.props.Document); - let layoutDoc = PositionDocument(Doc.Layout(element.props.Document)); + const doc = PositionDocument(element.props.Document); + const layoutDoc = PositionDocument(Doc.Layout(element.props.Document)); let nwidth = layoutDoc.nativeWidth || 0; let nheight = layoutDoc.nativeHeight || 0; - let width = (layoutDoc.width || 0); - let height = (layoutDoc.height || (nheight / nwidth * width)); - let scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling(); - let actualdW = Math.max(width + (dW * scale), 20); - let actualdH = Math.max(height + (dH * scale), 20); + const width = (layoutDoc.width || 0); + const height = (layoutDoc.height || (nheight / nwidth * width)); + const scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling(); + const actualdW = Math.max(width + (dW * scale), 20); + const actualdH = Math.max(height + (dH * scale), 20); doc.x = (doc.x || 0) + dX * (actualdW - width); doc.y = (doc.y || 0) + dY * (actualdH - height); - let fixedAspect = e.ctrlKey || (!layoutDoc.ignoreAspect && nwidth && nheight); + const fixedAspect = e.ctrlKey || (!layoutDoc.ignoreAspect && nwidth && nheight); if (fixedAspect && e.ctrlKey && layoutDoc.ignoreAspect) { layoutDoc.ignoreAspect = false; layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0; @@ -523,7 +510,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> dH && layoutDoc.autoHeight && (layoutDoc.autoHeight = false); } } - }); + })); } @action @@ -543,13 +530,14 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @computed get selectionTitle(): string { if (SelectionManager.SelectedDocuments().length === 1) { - let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey]; - if (typeof field === "string") { - return field; + const selected = SelectionManager.SelectedDocuments()[0]; + if (this._titleControlString.startsWith("=")) { + return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })!.script.run({ this: selected.props.Document }, console.log).result?.toString() || ""; } - else if (typeof field === "number") { - return field.toString(); + if (this._titleControlString.startsWith("#")) { + return selected.props.Document[this._titleControlString.substring(1)]?.toString() || "-unset-"; } + return this._accumulatedTitle; } else if (SelectionManager.SelectedDocuments().length > 1) { return "-multiple-"; } @@ -563,18 +551,19 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } } public showTextBar = () => { - if (this.TextBar) { - TooltipTextMenu.Toolbar && Array.from(this.TextBar.childNodes).indexOf(TooltipTextMenu.Toolbar) === -1 && this.TextBar.appendChild(TooltipTextMenu.Toolbar); + if (this.TextBar && TooltipTextMenu.Toolbar && Array.from(this.TextBar.childNodes).indexOf(TooltipTextMenu.Toolbar) === -1) { + this.TextBar.appendChild(TooltipTextMenu.Toolbar); } } render() { - var bounds = this.Bounds; - let seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; - if (bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { + const bounds = this.Bounds; + const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; + if (SelectionManager.GetIsDragging() || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { return (null); } - let minimizeIcon = ( + const minimizeIcon = ( <div className="documentDecorations-minimizeButton" onPointerDown={this.onMinimizeDown}> + {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} {SelectionManager.SelectedDocuments().length === 1 ? IconBox.DocumentIcon(StrCast(SelectionManager.SelectedDocuments()[0].props.Document.layout, "...")) : "..."} </div>); @@ -608,8 +597,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> }}> {minimizeIcon} + {/* <RichTextMenu /> */} + {this._edtingTitle ? - <input ref={this._keyinput} className="title" type="text" name="dynbox" value={this._title} onBlur={this.titleBlur} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> : + <input ref={this._keyinput} className="title" type="text" name="dynbox" value={this._accumulatedTitle} onBlur={e => this.titleBlur(true)} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> : <div className="title" onPointerDown={this.onTitleDown} ><span>{`${this.selectionTitle}`}</span></div>} <div className="documentDecorations-closeButton" title="Close Document" onPointerDown={this.onCloseDown}> <FontAwesomeIcon className="documentdecorations-times" icon={faTimes} size="lg" /> |
