From 0b38b0629496973d6c4571208710096deb91b7d7 Mon Sep 17 00:00:00 2001 From: srichman333 Date: Fri, 24 Nov 2023 17:59:13 -0500 Subject: merge --- .../views/nodes/formattedText/DashDocView.tsx | 8 ++- .../views/nodes/formattedText/DashFieldView.tsx | 1 + .../nodes/formattedText/FormattedTextBox.scss | 2 + .../views/nodes/formattedText/FormattedTextBox.tsx | 80 ++++++++++++---------- .../views/nodes/formattedText/RichTextMenu.tsx | 12 ++-- src/client/views/nodes/formattedText/marks_rts.ts | 8 +-- src/client/views/nodes/formattedText/nodes_rts.ts | 1 - 7 files changed, 60 insertions(+), 52 deletions(-) (limited to 'src/client/views/nodes/formattedText') diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index c5167461b..e8b9a98b7 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -5,7 +5,7 @@ import * as ReactDOM from 'react-dom/client'; import { Doc } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, returnFalse, Utils } from '../../../../Utils'; +import { emptyFunction, returnFalse, returnTrue, Utils } from '../../../../Utils'; import { DocServer } from '../../../DocServer'; import { Docs, DocUtils } from '../../../documents/Documents'; import { Transform } from '../../../util/Transform'; @@ -177,6 +177,7 @@ export class DashDocViewInternal extends React.Component { }; componentWillUnmount = () => Object.values(this._disposers).forEach(disposer => disposer?.()); + isContentActive = () => this.props.tbox.props.isSelected() || this.props.tbox.isAnyChildContentActive?.(); render() { return !this._dashDoc || !this._finalLayout || this.props.hidden ? null : ( @@ -190,6 +191,7 @@ export class DashDocViewInternal extends React.Component { display: 'inline-block', left: 0, top: 0, + pointerEvents: this.isContentActive() ? undefined : 'none', }} onPointerLeave={this.onPointerLeave} onPointerEnter={this.onPointerEnter} @@ -203,7 +205,7 @@ export class DashDocViewInternal extends React.Component { rootSelected={returnFalse} //{this._textBox.props.isSelected} removeDocument={this.removeDoc} isDocumentActive={returnFalse} - isContentActive={emptyFunction} + isContentActive={this.isContentActive} styleProvider={this._textBox.props.styleProvider} docViewPath={this._textBox.props.docViewPath} ScreenToLocalTransform={this.getDocTransform} @@ -213,7 +215,7 @@ export class DashDocViewInternal extends React.Component { PanelWidth={this._finalLayout[Width]} PanelHeight={this._finalLayout[Height]} focus={this.outerFocus} - whenChildContentsActiveChanged={returnFalse} + whenChildContentsActiveChanged={this.props.tbox.whenChildContentsActiveChanged} bringToFront={emptyFunction} dontRegisterView={false} childFilters={this.props.tbox?.props.childFilters} diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index d5ad128fe..0a64c8062 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -177,6 +177,7 @@ export class DashFieldViewInternal extends React.Component {this.props.hideKey ? null : ( diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 818c0cbe7..717efd5a9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -49,6 +49,7 @@ audiotag:hover { transition: opacity 1s; width: 100%; position: relative; + transform-origin: left top; top: 0; left: 0; } @@ -89,6 +90,7 @@ audiotag:hover { bottom: 0; width: 11; height: 11; + cursor: default; } .formattedTextBox-outer { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 41b1c59b0..b65c440d1 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,6 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; +import { setCORS } from 'google-translate-api-browser'; import { isEqual } from 'lodash'; import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; @@ -14,7 +15,7 @@ import { EditorView } from 'prosemirror-view'; import { BsMarkdownFill } from 'react-icons/bs'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, Height, UpdatingFromServer, Width } from '../../../../fields/DocSymbols'; +import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; @@ -52,6 +53,7 @@ import { AnchorMenu } from '../../pdf/AnchorMenu'; import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup'; import { SidebarAnnos } from '../../SidebarAnnos'; import { StyleProp } from '../../StyleProvider'; +import { media_state } from '../AudioBox'; import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { LinkDocPreview } from '../LinkDocPreview'; @@ -71,8 +73,6 @@ import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; import applyDevTools = require('prosemirror-dev-tools'); import React = require('react'); -import { media_state } from '../AudioBox'; -import { setCORS } from 'google-translate-api-browser'; // setting up cors-anywhere server address const translate = setCORS('http://cors-anywhere.herokuapp.com/'); export const GoogleRef = 'googleDocId'; @@ -93,6 +93,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent(); private _sidebarTagRef = React.createRef(); private _ref: React.RefObject = React.createRef(); @@ -315,7 +316,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this.getAnchor(true), targetCreator), e.pageX, e.pageY); }); const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); - this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); + this.props.isSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); + let ele: Opt = undefined; + try { + const contents = window.getSelection()?.getRangeAt(0).cloneContents(); + if (contents) { + ele = document.createElement('div'); + ele.append(contents); + } + this._selectionHTML = ele?.innerHTML; + } catch (e) {} }; dispatchTransaction = (tx: Transaction) => { @@ -434,10 +444,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent (tr = this.hyperlinkTerm(tr, term, newAutoLinks))); + Doc.MyPublishedDocs.forEach(term => (tr = this.hyperlinkTerm(tr, term, newAutoLinks))); tr = tr.setSelection(isNodeSel && false ? new NodeSelection(tr.doc.resolve(f)) : new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t))); this._editorView?.dispatch(tr); - // this.prepareForTyping(); } oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.rootDoc).forEach(LinkManager.Instance.deleteLink); }; @@ -460,7 +469,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent 40 ? '...' : '')).trim(); if (str.startsWith('@') && str.length > 1) { - Doc.AddDocToList(Doc.MyPublishedDocs, undefined, this.rootDoc); + Doc.AddToMyPublished(this.rootDoc); } } } @@ -487,9 +496,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent m.type.name === schema.marks.autoLinkAnchor.name)?.attrs.allAnchors ?? [])); - const link = editorView.state.schema.marks.autoLinkAnchor.create({ allAnchors, title: 'auto term', location: 'add:right' }); + const link = editorView.state.schema.marks.autoLinkAnchor.create({ allAnchors, title: 'auto term' }); tr = tr.addMark(pos, pos + node.nodeSize, link); } }); @@ -579,8 +589,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { + const defaultSidebar = 250; const prevWidth = 1 - this.sidebarWidth() / Number(getComputedStyle(this._ref.current!).width.replace('px', '')); if (preview) this._showSidebar = true; else { this.layoutDoc[this.SidebarKey + '_freeform_scale_max'] = 1; - this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? '50%' : '0%') !== '0%'; + this.layoutDoc._layout_showSidebar = + (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(defaultSidebar / (NumCast(this.layoutDoc._width) + defaultSidebar)) * 100}%` : '0%') !== '0%'; } - this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) * prevWidth); + this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) + defaultSidebar : Math.max(20, NumCast(this.layoutDoc._width) * prevWidth); }; sidebarDown = (e: React.PointerEvent) => { const batch = UndoManager.StartBatch('toggle sidebar'); @@ -733,7 +745,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent (this.layoutDoc._layout_noSidebar = !this.layoutDoc._layout_noSidebar), icon: !this.Document._layout_noSidebar ? 'eye-slash' : 'eye', }); - uicontrols.push({ + appearanceItems.push({ description: (this.Document._layout_enableAltContentUI ? 'Hide' : 'Show') + ' Alt Content UI', event: () => (this.layoutDoc._layout_enableAltContentUI = !this.layoutDoc._layout_enableAltContentUI), icon: !this.Document._layout_enableAltContentUI ? 'eye-slash' : 'eye', }); - !Doc.noviceMode && uicontrols.push({ description: 'Show Highlights...', noexpand: true, subitems: highlighting, icon: 'hand-point-right' }); + !Doc.noviceMode && appearanceItems.push({ description: 'Show Highlights...', noexpand: true, subitems: highlighting, icon: 'hand-point-right' }); !Doc.noviceMode && - uicontrols.push({ + appearanceItems.push({ description: 'Broadcast Message', event: () => DocServer.GetRefField('rtfProto').then(proto => proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.rootDoc[this.fieldKey], RichTextField)?.Text)), icon: 'expand-arrows-alt', }); - cm.addItem({ description: 'UI Controls...', subitems: uicontrols, icon: 'asterisk' }); - const appearance = cm.findByDescription('Appearance...'); - const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : []; appearanceItems.push({ description: 'Change Style...', noexpand: true, subitems: changeItems, icon: 'external-link-alt' }); // this.rootDoc.isTemplateDoc && appearanceItems.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.rootDoc), icon: "eye" }); @@ -909,7 +919,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent self.props.isSelected(true) && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); + runInAction(() => self.props.isSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); return new RichTextMenuPlugin({ editorProps: this.props }); }, }); @@ -1613,7 +1624,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent node that wraps the hyerlink while (target && !target.dataset?.targethrefs) target = target.parentElement; FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true'); - if (pcords && pcords.inside > 0 && state.doc.nodeAt(pcords.inside)?.type === state.schema.nodes.dashDoc) { - return; - } } }; @action onDoubleClick = (e: React.MouseEvent): void => { FormattedTextBoxComment.textBox = this; - if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar e.stopPropagation(); // if the text box is selected, then it consumes all click events @@ -1661,7 +1669,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { @@ -2067,7 +2075,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { // finds font sizes and families in selection getActiveAlignment() { - if (this.view && this.TextView?.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) { @@ -194,7 +194,7 @@ export class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveListStyle() { - if (this.view && this.TextView?.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = 0; i < path.length; i += 3) { if (path[i].type === this.view.state.schema.nodes.ordered_list) { @@ -214,7 +214,7 @@ export class RichTextMenu extends AntimodeMenu { const activeSizes = new Set(); const activeColors = new Set(); const activeHighlights = new Set(); - if (this.view && this.TextView?.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected()) { const state = this.view.state; const pos = this.view.state.selection.$from; const marks: Mark[] = [...(state.storedMarks ?? [])]; @@ -249,7 +249,7 @@ export class RichTextMenu extends AntimodeMenu { //finds all active marks on selection in given group getActiveMarksOnSelection() { let activeMarks: MarkType[] = []; - if (!this.view || !this.TextView?.props.isSelected(true)) return activeMarks; + if (!this.view || !this.TextView?.props.isSelected()) return activeMarks; const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript]; if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type); @@ -286,7 +286,7 @@ export class RichTextMenu extends AntimodeMenu { } destroy() { - !this.TextView?.props.isSelected(true) && this.fadeOut(true); + !this.TextView?.props.isSelected() && this.fadeOut(true); } @action @@ -443,7 +443,7 @@ export class RichTextMenu extends AntimodeMenu { } align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => { - if (this.TextView?.props.isSelected(true)) { + if (this.TextView?.props.isSelected()) { var tr = view.state.tr; view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => { if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) { diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts index 6f07588b3..4faef26e2 100644 --- a/src/client/views/nodes/formattedText/marks_rts.ts +++ b/src/client/views/nodes/formattedText/marks_rts.ts @@ -28,7 +28,6 @@ export const marks: { [index: string]: MarkSpec } = { autoLinkAnchor: { attrs: { allAnchors: { default: [] as { href: string; title: string; anchorId: string }[] }, - location: { default: null }, title: { default: null }, }, inclusive: false, @@ -37,7 +36,6 @@ export const marks: { [index: string]: MarkSpec } = { tag: 'a[href]', getAttrs(dom: any) { return { - location: dom.getAttribute('location'), title: dom.getAttribute('title'), }; }, @@ -46,7 +44,7 @@ export const marks: { [index: string]: MarkSpec } = { toDOM(node: any) { const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), ''); const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), ''); - return ['a', { class: anchorids, 'data-targethrefs': targethrefs, 'data-noPreview': 'true', 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, location: node.attrs.location, style: `background: lightBlue` }, 0]; + return ['a', { class: anchorids, 'data-targethrefs': targethrefs, /*'data-noPreview': 'true', */ 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, style: `background: lightBlue` }, 0]; }, }, noAutoLinkAnchor: { @@ -73,7 +71,6 @@ export const marks: { [index: string]: MarkSpec } = { linkAnchor: { attrs: { allAnchors: { default: [] as { href: string; title: string; anchorId: string }[] }, - location: { default: null }, title: { default: null }, noPreview: { default: false }, docref: { default: false }, // flags whether the linked text comes from a document within Dash. If so, an attribution label is appended after the text @@ -84,7 +81,6 @@ export const marks: { [index: string]: MarkSpec } = { tag: 'a[href]', getAttrs(dom: any) { return { - location: dom.getAttribute('location'), title: dom.getAttribute('title'), noPreview: dom.getAttribute('noPreview'), }; @@ -108,7 +104,7 @@ export const marks: { [index: string]: MarkSpec } = { node.attrs.title, ], ] - : ['a', { class: anchorids, 'data-targethrefs': targethrefs, title: node.attrs.title, 'data-noPreview': node.attrs.noPreview, location: node.attrs.location, style: `text-decoration: underline; cursor: default` }, 0]; + : ['a', { class: anchorids, 'data-targethrefs': targethrefs, title: node.attrs.title, 'data-noPreview': node.attrs.noPreview, style: `text-decoration: underline; cursor: default` }, 0]; }, }, diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index f27fb18e2..4cd2cee52 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -212,7 +212,6 @@ export const nodes: { [index: string]: NodeSpec } = { alt: { default: null }, title: { default: null }, float: { default: 'left' }, - location: { default: 'add:right' }, docId: { default: '' }, }, group: 'inline', -- cgit v1.2.3-70-g09d2