import { IReactionDisposer, observable, computed, action } from "mobx"; import { Fragment, Node, Slice } from "prosemirror-model"; import { TextSelection } from "prosemirror-state"; import * as ReactDOM from 'react-dom'; import React = require("react"); // import { dom } from "@fortawesome/fontawesome-svg-core"; // import { observer } from "mobx-react"; export class SummaryView { _fieldWrapper: HTMLDivElement; // container for label constructor(node: any, view: any, getPos: any) { console.log("You are here") this._fieldWrapper = document.createElement("div"); this._fieldWrapper.style.fontWeight = "bold"; this._fieldWrapper.style.position = "relative"; this._fieldWrapper.style.display = "inline-block"; const js = node.toJSON; node.toJSON = function () { return js.apply(this, arguments); }; console.log("rendering new SummaryViewInternal") ReactDOM.render(, this._fieldWrapper); (this as any).dom = this._fieldWrapper; } selectNode() { } deselectNode() { } destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); } } interface ISummaryViewInternal { node: any; view: any; getPos: any; } export class SummaryViewInternal extends React.Component{ _className: any; _view: any; _reactionDisposer: IReactionDisposer | undefined; constructor(props: ISummaryViewInternal) { super(props); this._className = this.className(this.props.node.attrs.visibility); this._view = this.props.view; this.onPointerDownCollapsed = this.onPointerDownCollapsed.bind(this); this.updateSummarizedText = this.updateSummarizedText.bind(this); } componentWillUnmount() { this._reactionDisposer?.(); } className(visible: boolean) { return "formattedTextBox-summarizer" + (visible ? "" : "-collapsed"); } onPointerDownCollapsed(e: any) { const visible = !this.props.node.attrs.visibility; const attrs = { ...this.props.node.attrs, visibility: visible }; let textSelection = TextSelection.create(this.props.view.state.doc, this.props.getPos() + 1); if (!visible) { // update summarized text and save in attrs textSelection = this.updateSummarizedText(this.props.getPos() + 1); attrs.text = textSelection.content(); attrs.textslice = attrs.text.toJSON(); } this.props.view.dispatch(this.props.view.state.tr. setSelection(textSelection). // select the current summarized text (or where it will be if its collapsed) replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : this.props.node.attrs.text). // collapse/expand it setNodeMarkup(this.props.getPos(), undefined, attrs)); // update the attrs e.preventDefault(); e.stopPropagation(); this._className = this.className(visible); } updateSummarizedText(start?: any) { const mtype = this.props.view.state.schema.marks.summarize; const mtypeInc = this.props.view.state.schema.marks.summarizeInclusive; let endPos = start; const visited = new Set(); for (let i: number = start + 1; i < this.props.view.state.doc.nodeSize - 1; i++) { let skip = false; this.props.view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => { if (node.isLeaf && !visited.has(node) && !skip) { if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) { visited.add(node); endPos = i + node.nodeSize - 1; } else skip = true; } }); } return TextSelection.create(this.props.view.state.doc, start, endPos); } render() { return ( ); } }