···1+// ok so. we need plain text to parse markup from, but
2+// this is a "rich text" editor with paragraphs and other unimaginable things
3+// so, we have to convert the contents to plain text, but
4+// also need to convert indexes into the plaintext string, BACK
5+// into indexes into the rich text, for applying the decorations
6+export class EditorPlaintext {
7+ constructor(node) {
8+ let text = ""
9+ let decor_index = 0
10+ // indexes converts an index in our raw string -> index for inline decor
11+ let indexes = [[0,0]]
12+ function recurse(node, islast=false) {
13+ if (node.type.name=='doc') {
14+ let content = node.content.content
15+ for (let i=0; i<content.length; i++)
16+ recurse(content[i], i==content.length-1)
17+ } else if (node.type.name=='paragraph') {
18+ let content = node.content.content
19+ for (let i=0; i<content.length; i++)
20+ recurse(content[i])
21+ if (!islast) {
22+ text += '\n'
23+ decor_index += 2 // why 2? no idea.
24+ indexes.push([text.length,decor_index])
25+ }
26+ } else if (node.type.name=='hardBreak') {
27+ text += "\n"
28+ decor_index += 1 // i assume ?
29+ indexes.push([text.length,decor_index])
30+ } else if (node.type.name=='text') {
31+ text += node.text
32+ decor_index += node.text.length
33+ } else if (node.type.name=='mention') {
34+ text += `@${node.attrs?.id || ''}`
35+ decor_index += 1 // ?
36+ indexes.push([text.length,decor_index])
37+ }
38+ }
39+ recurse(node)
40+ this.text = text
41+ this.indexes = indexes
42+ }
43+ index(index) {
44+ let i
45+ for (i=0; i<this.indexes.length; i++) {
46+ if (this.indexes[i][0]>index)
47+ break
48+ }
49+ let [real_index, decor_index] = this.indexes[i-1]
50+ let offset = index - real_index
51+ return decor_index + offset + 1 // egh
52+ }
53+}