1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
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(<SummaryViewInternal
view={view}
getPos={getPos}
node={node}
/>, 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<ISummaryViewInternal>{
_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 (
<span
className={this._className}
onPointerDown={this.onPointerDownCollapsed}>
</span>
);
}
}
|