diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/EquationBox.tsx | 26 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 16 | ||||
| -rw-r--r-- | src/client/views/nodes/KeyValueBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/LinkAnchorBox.tsx | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBoxRenderer.js | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/button/FontIconBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FootnoteView.tsx | 72 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 12 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/RichTextMenu.tsx | 15 | ||||
| -rw-r--r-- | src/client/views/nodes/trails/PresBox.tsx | 6 |
12 files changed, 95 insertions, 66 deletions
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 453bdac8e..e5913d997 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -162,6 +162,7 @@ width: 100%; height: 100%; border-radius: inherit; + white-space: normal; .documentView-styleContentWrapper { width: 100%; diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index c279341cc..163c5a9ed 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -21,6 +21,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() { public static SelectOnLoad: string = ''; _ref: React.RefObject<EquationEditor> = React.createRef(); componentDidMount() { + this.props.setContentView?.(this); if (EquationBox.SelectOnLoad === this.rootDoc[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) { this.props.select(false); @@ -78,14 +79,13 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() { if (e.key === 'Backspace' && !this.dataDoc.text) this.props.removeDocument?.(this.rootDoc); }; @undoBatch - onChange = (str: string) => { - this.dataDoc.text = str; + onChange = (str: string) => (this.dataDoc.text = str); + + updateSize = () => { const style = this._ref.current && getComputedStyle(this._ref.current.element.current); - if (style) { - const _height = Number(style.height.replace('px', '')); - const _width = Number(style.width.replace('px', '')); - this.layoutDoc._width = Math.max(35, _width); - this.layoutDoc._height = Math.max(25, _height); + if (style?.width.endsWith('px') && style?.height.endsWith('px')) { + this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', ''))); + this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', ''))); } }; render() { @@ -93,16 +93,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() { const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1); return ( <div - ref={r => { - r instanceof HTMLDivElement && - new ResizeObserver( - action((entries: any) => { - if (entries[0].contentBoxSize[0].inlineSize) { - this.rootDoc._width = entries[0].contentBoxSize[0].inlineSize; - } - }) - ).observe(r); - }} + ref={r => this.updateSize()} className="equationBox-cont" onPointerDown={e => !e.ctrlKey && e.stopPropagation()} style={{ @@ -110,6 +101,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() { width: 'fit-content', // `${100 / scale}%`, height: `${100 / scale}%`, pointerEvents: !this.props.isSelected() ? 'none' : undefined, + fontSize: StrCast(this.rootDoc._fontSize), }} onKeyDown={e => e.stopPropagation()}> <EquationEditor ref={this._ref} value={this.dataDoc.text || 'x'} spaceBehavesLikeTab={true} onChange={this.onChange} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" /> diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index e2ecca0b6..bdd99528b 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -26,12 +26,13 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComp import { MarqueeAnnotator } from '../MarqueeAnnotator'; import { AnchorMenu } from '../pdf/AnchorMenu'; import { StyleProp } from '../StyleProvider'; +import { DocFocusOptions, DocumentViewProps } from './DocumentView'; import { FaceRectangles } from './FaceRectangles'; import { FieldView, FieldViewProps } from './FieldView'; import './ImageBox.scss'; -import React = require('react'); import { PresBox } from './trails'; -import { DocFocusOptions, DocumentViewProps } from './DocumentView'; +import React = require('react'); +import Color = require('color'); export const pageSchema = createSchema({ googlePhotosUrl: 'string', @@ -345,8 +346,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp @computed get content() { TraceMobx(); - const srcpath = this.paths[0]; - const fadepath = this.paths.lastElement(); + const col = Color(this.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor)); + const srcpath = !col.alpha() ? '' : this.paths[0]; + const fadepath = !col.alpha() ? '' : this.paths.lastElement(); const { nativeWidth, nativeHeight, nativeOrientation } = this.nativeSize; const rotation = NumCast(this.dataDoc[this.fieldKey + '-rotation']); const aspect = rotation % 180 ? nativeHeight / nativeWidth : 1; @@ -364,7 +366,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp return ( <div className="imageBox-cont" key={this.layoutDoc[Id]} ref={this.createDropTarget} onPointerDown={this.marqueeDown}> - <div className="imageBox-fader" style={{ overflow: Array.from(this.props.docViewPath?.()).slice(-1)[0].fitWidth ? 'auto' : undefined }}> + <div className="imageBox-fader" style={{ opacity: col.alpha(), overflow: Array.from(this.props.docViewPath?.()).slice(-1)[0].fitWidth ? 'auto' : undefined }}> <img key="paths" src={srcpath} style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} /> {fadepath === srcpath ? null : ( <div @@ -408,6 +410,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp ); } }; + getScrollHeight = () => this.nativeSize.nativeHeight; @action finishMarquee = () => { this._getAnchor = AnchorMenu.Instance?.GetAnchor; @@ -434,6 +437,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp height: this.props.PanelWidth() ? undefined : `100%`, pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined, borderRadius, + overflow: 'auto', }}> <CollectionFreeFormView {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit} @@ -444,7 +448,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp isAnnotationOverlay={true} annotationLayerHostsContent={true} PanelWidth={this.props.PanelWidth} - PanelHeight={this.props.PanelHeight} + PanelHeight={this.props.fitWidth ? '100%' : this.props.PanelHeight} ScreenToLocalTransform={this.screenToLocalTransform} select={emptyFunction} NativeDimScaling={returnOne} diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 18c5b81ec..60417430f 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -66,7 +66,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> { value = eq ? value.substr(1) : value; const dubEq = value.startsWith(':=') ? 'computed' : value.startsWith(';=') ? 'script' : false; value = dubEq ? value.substr(2) : value; - const options: ScriptOptions = { addReturn: true, params: { this: Doc.name, self: Doc.name, _last_: 'any', _readOnly_: 'boolean' }, editable: false }; + const options: ScriptOptions = { addReturn: true, typecheck: false, params: { this: Doc.name, self: Doc.name, _last_: 'any', _readOnly_: 'boolean' }, editable: false }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq }; diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index e89076c1f..eba9e281d 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -101,6 +101,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() { left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`, top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`, transform: `scale(${anchorScale})`, + cursor: 'grab', }} /> ); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index acf4fe4b0..d0d638e98 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -981,7 +981,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps } return this.props.styleProvider?.(doc, props, property); }; - pointerEvents = () => (!this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none'); + pointerEvents = () => (!this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance?.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none'); annotationPointerEvents = () => (this._isAnnotating || SnappingManager.GetIsDragging() || Doc.ActiveTool !== InkTool.None ? 'all' : 'none'); render() { const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js index cebb94d86..20554b858 100644 --- a/src/client/views/nodes/WebBoxRenderer.js +++ b/src/client/views/nodes/WebBoxRenderer.js @@ -216,7 +216,9 @@ var ForeignHtmlRenderer = function (styleSheets) { } const styleElem = document.createElement('style'); - styleElem.innerHTML = cssStyles.replace('>', '>').replace('<', '<'); + styleElem.innerHTML = + '#mw-sidebar-checkbox ~ .vector-main-menu-container { display: none !important; } ' + // hack to prevent wikipedia menu from appearing + cssStyles.replace('>', '>').replace('<', '<'); const styleElemString = new XMLSerializer().serializeToString(styleElem).replace(/>/g, '>').replace(/</g, '<'); diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index 1de29f806..9d67283a0 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -90,7 +90,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { static GetRecognizeGestures() { return BoolCast(Doc.UserDoc()._recognizeGestures); } - static SetRecognizeGesturs(show: boolean) { + static SetRecognizeGestures(show: boolean) { Doc.UserDoc()._recognizeGestures = show; } @@ -133,7 +133,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { @computed get numberButton() { const numBtnType: string = StrCast(this.rootDoc.numBtnType); const numScript = ScriptCast(this.rootDoc.script); - const setValue = (value: number) => numScript?.script.run({ value, _readOnly_: false }); + const setValue = (value: number) => UndoManager.RunInBatch(() => numScript?.script.run({ value, _readOnly_: false }), 'set num value'); // Script for checking the outcome of the toggle const checkResult: number = numScript?.script.run({ value: 0, _readOnly_: true }).result || 0; diff --git a/src/client/views/nodes/formattedText/FootnoteView.tsx b/src/client/views/nodes/formattedText/FootnoteView.tsx index 1683cc972..531a60297 100644 --- a/src/client/views/nodes/formattedText/FootnoteView.tsx +++ b/src/client/views/nodes/formattedText/FootnoteView.tsx @@ -1,10 +1,10 @@ -import { EditorView } from "prosemirror-view"; -import { EditorState } from "prosemirror-state"; -import { keymap } from "prosemirror-keymap"; -import { baseKeymap, toggleMark } from "prosemirror-commands"; -import { schema } from "./schema_rts"; -import { redo, undo } from "prosemirror-history"; -import { StepMap } from "prosemirror-transform"; +import { EditorView } from 'prosemirror-view'; +import { EditorState } from 'prosemirror-state'; +import { keymap } from 'prosemirror-keymap'; +import { baseKeymap, toggleMark } from 'prosemirror-commands'; +import { schema } from './schema_rts'; +import { redo, undo } from 'prosemirror-history'; +import { StepMap } from 'prosemirror-transform'; export class FootnoteView { innerView: any; @@ -20,38 +20,39 @@ export class FootnoteView { this.getPos = getPos; // The node's representation in the editor (empty, for now) - this.dom = document.createElement("footnote"); + this.dom = document.createElement('footnote'); - this.dom.addEventListener("pointerup", this.toggle, true); + this.dom.addEventListener('pointerup', this.toggle, true); // These are used when the footnote is selected this.innerView = null; } selectNode() { - this.dom.classList.add("ProseMirror-selectednode"); + this.dom.classList.add('ProseMirror-selectednode'); if (!this.innerView) this.open(); } deselectNode() { - this.dom.classList.remove("ProseMirror-selectednode"); + this.dom.classList.remove('ProseMirror-selectednode'); if (this.innerView) this.close(); } open() { // Append a tooltip to the outer node - const tooltip = this.dom.appendChild(document.createElement("div")); - tooltip.className = "footnote-tooltip"; + const tooltip = this.dom.appendChild(document.createElement('div')); + tooltip.className = 'footnote-tooltip'; // And put a sub-ProseMirror into that this.innerView = new EditorView(tooltip, { // You can use any node as an editor document state: EditorState.create({ doc: this.node, - plugins: [keymap(baseKeymap), - keymap({ - "Mod-z": () => undo(this.outerView.state, this.outerView.dispatch), - "Mod-y": () => redo(this.outerView.state, this.outerView.dispatch), - "Mod-b": toggleMark(schema.marks.strong) - }), + plugins: [ + keymap(baseKeymap), + keymap({ + 'Mod-z': () => undo(this.outerView.state, this.outerView.dispatch), + 'Mod-y': () => redo(this.outerView.state, this.outerView.dispatch), + 'Mod-b': toggleMark(schema.marks.strong), + }), // new Plugin({ // view(newView) { // // TODO -- make this work with RichTextMenu @@ -59,7 +60,6 @@ export class FootnoteView { // } // }) ], - }), // This is the magic part dispatchTransaction: this.dispatchInner.bind(this), @@ -69,36 +69,39 @@ export class FootnoteView { // footnote is node-selected (and thus DOM-selected) when // the parent editor is focused. e.stopPropagation(); - document.addEventListener("pointerup", this.ignore, true); + document.addEventListener('pointerup', this.ignore, true); if (this.outerView.hasFocus()) this.innerView.focus(); - }) as any - } + }) as any, + }, }); setTimeout(() => this.innerView?.docView.setSelection(0, 0, this.innerView.root, true), 0); } ignore = (e: PointerEvent) => { e.stopPropagation(); - document.removeEventListener("pointerup", this.ignore, true); - } + document.removeEventListener('pointerup', this.ignore, true); + }; toggle = () => { + console.log('TOGGLE'); if (this.innerView) this.close(); else this.open(); - } + }; close() { + console.log('CLOSE'); this.innerView?.destroy(); this.innerView = null; - this.dom.textContent = ""; + this.dom.textContent = ''; } dispatchInner(tr: any) { const { state, transactions } = this.innerView.state.applyTransaction(tr); this.innerView.updateState(state); - if (!tr.getMeta("fromOutside")) { - const outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1); + if (!tr.getMeta('fromOutside')) { + const outerTr = this.outerView.state.tr, + offsetMap = StepMap.offset(this.getPos() + 1); for (const transaction of transactions) { for (const step of transaction.steps) { outerTr.step(step.map(offsetMap)); @@ -117,11 +120,11 @@ export class FootnoteView { if (start !== null) { let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); const overlap = start - Math.min(endA, endB); - if (overlap > 0) { endA += overlap; endB += overlap; } - this.innerView.dispatch( - state.tr - .replace(start, endB, node.slice(start, endA)) - .setMeta("fromOutside", true)); + if (overlap > 0) { + endA += overlap; + endB += overlap; + } + this.innerView.dispatch(state.tr.replace(start, endB, node.slice(start, endA)).setMeta('fromOutside', true)); } } return true; @@ -139,4 +142,3 @@ export class FootnoteView { return true; } } - diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 8407eee96..619c59f0e 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1611,7 +1611,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps @action onBlur = (e: any) => { if (this.ProseRef?.children[0] !== e.nativeEvent.target) return; - this.autoLink(); + if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) { + const stordMarks = this._editorView?.state.storedMarks?.slice(); + this.autoLink(); + if (this._editorView?.state.tr) { + const tr = stordMarks?.reduce((tr, m) => { + tr.addStoredMark(m); + return tr; + }, this._editorView.state.tr); + tr && this._editorView.dispatch(tr); + } + } FormattedTextBox.Focused === this && (FormattedTextBox.Focused = undefined); if (RichTextMenu.Instance?.view === this._editorView && !this.props.isSelected(true)) { RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined); diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 6c6d26af5..b70da2e5e 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -20,6 +20,7 @@ import { FormattedTextBox } from './FormattedTextBox'; import { updateBullets } from './ProsemirrorExampleTransfer'; import './RichTextMenu.scss'; import { schema } from './schema_rts'; +import { EquationBox } from '../EquationBox'; const { toggleMark } = require('prosemirror-commands'); @observer @@ -97,6 +98,16 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { @computed get textAlign() { return this._activeAlignment; } + _disposer: IReactionDisposer | undefined; + componentDidMount() { + this._disposer = reaction( + () => SelectionManager.Views(), + views => this.updateMenu(undefined, undefined, undefined) + ); + } + componentWillUnmount() { + this._disposer?.(); + } @action public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any) { @@ -206,6 +217,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { m.type === state.schema.marks.pFontSize && activeSizes.add(m.attrs.fontSize); m.type === state.schema.marks.marker && activeHighlights.add(String(m.attrs.highlight)); }); + } else if (SelectionManager.Views().some(dv => dv.ComponentView instanceof EquationBox)) { + SelectionManager.Views().forEach(dv => StrCast(dv.rootDoc._fontSize) && activeSizes.add(StrCast(dv.rootDoc._fontSize))); } return { activeFamilies: Array.from(activeFamilies), activeSizes: Array.from(activeSizes), activeColors: Array.from(activeColors), activeHighlights: Array.from(activeHighlights) }; } @@ -328,6 +341,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true); this.view.focus(); } + } else if (SelectionManager.Views().some(dv => dv.ComponentView instanceof EquationBox)) { + SelectionManager.Views().forEach(dv => (dv.rootDoc._fontSize = fontSize)); } else Doc.UserDoc()._fontSize = fontSize; this.updateMenu(this.view, undefined, this.props); }; diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index ff05dcdcb..427911bd3 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -687,7 +687,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { * directly at start. * @param startIndex: index that the presentation will start at */ + @action startPresentation = (startIndex: number) => { + PresBox.Instance = this; clearTimeout(this._presTimer); if (this.childDocs.length) { this.layoutDoc.presStatus = PresStatus.Autoplay; @@ -2048,7 +2050,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { </div> <Tooltip title={<div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? 'Pause' : 'Autoplay'}</div>}> <div className="presPanel-button" onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => this.startOrPause(true), false, false)}> - <FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} /> + <FontAwesomeIcon color={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'red' : undefined} icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? 'pause' : 'play'} /> </div> </Tooltip> <div @@ -2122,7 +2124,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() { @action startOrPause = (makeActive = true) => { makeActive && this.updateCurrentPresentation(); - if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startPresentation(this.itemIndex); + if (!this.layoutDoc.presStatus || this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startPresentation(this.itemIndex); else this.pauseAutoPres(); }; |
