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 : []);