1import { hoverTooltip } from '@codemirror/view';
2import jsdoc from '../../doc.json';
3import { Autocomplete, getSynonymDoc } from './autocomplete.mjs';
4
5const getDocLabel = (doc) => doc.name || doc.longname;
6
7let ctrlDown = false;
8
9if (typeof window !== 'undefined') {
10  // Record Control key event to trigger or block the tooltip depending on the state
11  window.addEventListener(
12    'keyup',
13    function (e) {
14      if (e.key == 'Control') {
15        ctrlDown = false;
16      }
17    },
18    true,
19  );
20
21  window.addEventListener(
22    'keydown',
23    function (e) {
24      if (e.key == 'Control') {
25        ctrlDown = true;
26      }
27    },
28    true,
29  );
30}
31
32export const strudelTooltip = hoverTooltip(
33  (view, pos, side) => {
34    // Word selection from CodeMirror Hover Tooltip example https://codemirror.net/examples/tooltip/#hover-tooltips
35    if (!ctrlDown) {
36      return null;
37    }
38    let { from, to, text } = view.state.doc.lineAt(pos);
39    let start = pos,
40      end = pos;
41    while (start > from && /\w/.test(text[start - from - 1])) {
42      start--;
43    }
44    while (end < to && /\w/.test(text[end - from])) {
45      end++;
46    }
47    if ((start == pos && side < 0) || (end == pos && side > 0)) {
48      return null;
49    }
50    let word = text.slice(start - from, end - from);
51    // Get entry from Strudel documentation
52    let entry = jsdoc.docs.filter((doc) => getDocLabel(doc) === word)[0];
53    if (!entry) {
54      // Try for synonyms
55      const doc = jsdoc.docs.filter((doc) => doc.synonyms && doc.synonyms.includes(word))[0];
56      if (!doc) {
57        return null;
58      }
59      entry = getSynonymDoc(doc, word);
60    }
61
62    return {
63      pos: start,
64      end,
65      above: false,
66      arrow: true,
67      create(view) {
68        let dom = document.createElement('div');
69        dom.className = 'strudel-tooltip';
70        const ac = Autocomplete(entry);
71        dom.appendChild(ac);
72        return { dom };
73      },
74    };
75  },
76  { hoverTime: 10 },
77);
78
79export const isTooltipEnabled = (on) => (on ? strudelTooltip : []);