{"version":3,"sources":["https://lively-kernel.org/lively4/swd21-event-sourcing/src/external/codemirror-spellcheck.js"],"names":["Typo","focalStorage","getSuggestionBox","startSpellCheck","saveIgnoreDict","loadIgnoreDict","loadDictLang","current","loadDict","dictionaries","name","aff","dic","Promise","resolve","affData","fetch","then","r","text","wordsData","dictionary","lang","lively4url","spellCheckKey","getItem","dict","setItem","ignoreDict","cm","typo","rx_word","spellcheckOverlay","removeOverlay","token","stream","state","ch","peek","word","includes","next","test","check","addOverlay","box","document","getElementById","remove","sbox","lively","removeEventListener","getWrapperElement","addEventListener","e","target","classList","contains","preventDefault","stopPropagation","suggest","sboxShow","items","x","y","hourglass","selwidget","children","isSafari","navigator","vendor","indexOf","userAgent","match","separator","length","options","forEach","s","indexInParent","slice","call","parentElement","innerHTML","fontSize","window","getComputedStyle","getPropertyValue","style","size","value","cmrect","getBoundingClientRect","left","top","offsetHeight","body","scrollTop","widgetRect","right","width","bottom","height","sboxHide","createElement","zIndex","id","position","multiple","appendChild","innerText","codeMirror","screenPos","pageX","pageY","tokenRect","start","coordsChar","end","cmpos","line","results","all","push","onmouseout","related","relatedTarget","tagName","onchange","correction","setOption","maxHighlightLength","replaceRange","focus","setCursor"],"mappings":"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","file":"codemirror-spellcheck.js","sourcesContent":["import Typo from \"src/external/typo.js\"\nimport focalStorage from \"src/external/focalStorage.js\"\n\nexport var dictionaries = {}\n\nexport async function loadDict(name, aff, dic) {\n  if (!dictionaries[name]) {\n    dictionaries[name] = new Promise(async resolve => {\n      var affData = await fetch(aff).then(r => r.text())\n      var wordsData = await fetch(dic).then(r => r.text())\n      var dictionary = new Typo( name, affData, wordsData);\t\n      resolve(dictionary)\n    })\n  }   \n  return dictionaries[name]\n}\n\nexport function current() {\n  return loadDictLang(\"en_US\")\n}\n\nexport function loadDictLang(lang=\"en_US\") {\n  return loadDict(\n    lang,\n    lively4url + `/src/external/dicts/${lang}.aff`,\n    lively4url + `/src/external/dicts/${lang}.dic`)  \n}\n\n\ncurrent()\n\n// copied from kofifus/ Codemirror spellchecker with typo corrections\n// https://gist.github.com/kofifus/4b2f79cadc871a29439d919692099406\n\n\nvar spellCheckKey = \"SpellcheckIngoreWords\"\nasync function loadIgnoreDict() {\n  return (await focalStorage.getItem(spellCheckKey)) || {};\n}\n\nasync function saveIgnoreDict(dict) { \n  return (await focalStorage.setItem(spellCheckKey, dict));\n}\n\nexport var ignoreDict\n\nexport async  function startSpellCheck(cm, typo) {\n  // console.log(\"start spellcheck \" + typo.dictionary)\n  \n\tif (!cm || !typo) return; // sanity\n\n\t// ignoreDict = {}; // dictionary of ignored words\n  if (!ignoreDict ) {\n    ignoreDict = await loadIgnoreDict()\n  }\n  \n\t// Define what separates a word\n\tvar rx_word = '!\\'\\\"#$%&()*+,-./:;<=>?@[\\\\]^_`{|}~ ';\n\n  if (cm.spellcheckOverlay) {\n    // console.log(\"remove spellcheck overlay\")\n    cm.removeOverlay(\"spellcheck\");\n  }\n  \n\tcm.spellcheckOverlay = {\n    name: \"spellcheck\",\n\t\ttoken: function(stream, state) {\n      \n\t\t\tvar ch = stream.peek();\n\t\t\tvar word = \"\";\n\t\t\tif (rx_word.includes(ch) || ch === '\\uE000' || ch === '\\uE001') {\n\t\t\t\tstream.next();\n\t\t\t\treturn null;\n\t\t\t}\n      \n      while ((ch = stream.peek()) && !rx_word.includes(ch)) {\n\t\t\t\tword += ch;\n\t\t\t\tstream.next();\n\t\t\t}\n      // cm.doc.findMarksAt(\n      // var cm = that.editor\n      \n      \n\t\t\tif (!/[a-zöäüß]/i.test(word)) return null; // no letters\n\t\t\t\n      // console.log(\"w\", word, \"stream \", stream)\n      // var token = cm.getTokenAt(cm.doc.posFromIndex(stream.pos))\n      // console.log(\"w\", word, \"type \", token.type)\n      // if (token.type && token.type.match(\"url\")) return null; \n\n      if (ignoreDict && ignoreDict[word]) return null;\n      // console.log(\"check \" + word + \" in \" + typo.dictionary + \" \" + typo.check(word))\n\t\t\tif (!typo.check(word)) return \"spell-error\"; // CSS class: cm-spell-error\n\t\t}\n\t}\n\tcm.addOverlay(cm.spellcheckOverlay);\n\n  \n  var box = document.getElementById('suggestBox');\n  if (box) box.remove()\n  \n\t// initialize the suggestion box\n\tvar sbox = getSuggestionBox(typo);\n  // console.log(\"register context menu spell checker\")\n  lively.removeEventListener(\"spellcheck\", cm.getWrapperElement(), \"contextmenu\")\n\tlively.addEventListener(\"spellcheck\", cm.getWrapperElement(), \"contextmenu\", e => {\n    if (!e.target.classList.contains('cm-spell-error')) return      \n    e.preventDefault();\n\t  e.stopPropagation();  \n\t\tsbox.suggest(cm, e);\n\t\treturn false;\n\t});\n}\n\nexport function getSuggestionBox(typo) {\n\tfunction sboxShow(cm, sbox, items, x, y, hourglass) {\n    // console.log(\"get suggestion box \" + typo.dictionary)\n\t\tlet selwidget = sbox.children[0];\n\n\t\tvar isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 &&  navigator.userAgent && !navigator.userAgent.match('CriOS');\n\t\tlet separator=(!isSafari && (hourglass || items.length>0)); // separator line does not work well on safari\n\n\t\tlet options = '';\n\t\titems.forEach(s => options += '<option value=\"' + s + '\">' + s + '</option>');\n\t\tif (hourglass) options += '<option disabled=\"disabled\">&nbsp;&nbsp;&nbsp;&#8987;</option>';\n\t\tif (separator) options += '<option style=\"min-height:1px; max-height:1px; padding:0; background-color: #000000;\" disabled>&nbsp;</option>';\n\t\toptions += `<option value=\"##ignoreall##\">Ignore&nbsp;all&nbsp;${typo.dictionary}</option>`;\n\n\t\tlet indexInParent=[].slice.call(selwidget.parentElement.children).indexOf(selwidget);\n\t\tselwidget.innerHTML=options;\n\t\tselwidget=selwidget.parentElement.children[indexInParent];\n\t\t\n\t\tlet fontSize=window.getComputedStyle(cm.getWrapperElement(), null).getPropertyValue('font-size');\n\t\tselwidget.style.fontSize=fontSize;\n\t\tselwidget.size = selwidget.length;\n\t\tif (separator) selwidget.size--;\n\t\tselwidget.value = -1;\n\n\t\t// position widget inside cm\n\t\tlet cmrect = cm.getWrapperElement().getBoundingClientRect();\n    sbox.style.left = x + 'px';\n\t\tsbox.style.top = ((y - sbox.offsetHeight / 2) - document.body.parentElement.scrollTop) + 'px';\n\t\tlet widgetRect = sbox.getBoundingClientRect();\n\t\tif (widgetRect.top < cmrect.top) sbox.style.top = (cmrect.top + 2) + 'px';\n\t\tif (widgetRect.right > cmrect.right) sbox.style.left = (cmrect.right - widgetRect.width - 2) + 'px';\n\t\tif (widgetRect.bottom > cmrect.bottom) sbox.style.top = (cmrect.bottom - widgetRect.height - 2) + 'px';\n  \n\t}\n\n\tfunction sboxHide(sbox) {\n\t\tsbox.style.top = sbox.style.left = '-1000px';\n\t\t// typo.suggest(); // disable any running suggeations search\n\t}\n\n\t// create suggestions widget\n\tlet sbox = document.getElementById('suggestBox');\n\tif (!sbox) {\n\t\tsbox = document.createElement('div');\n\t\tsbox.style.zIndex = 100000;\n\t\tsbox.id = 'suggestBox';\n\t\tsbox.style.position = 'fixed';\n\t\tsboxHide(sbox);\n\n\t\tlet selwidget = document.createElement('select');\n\t\tselwidget.multiple = 'yes';\n\t\tsbox.appendChild(selwidget);\n\n\t\tsbox.suggest = (async (cm, e) => { // e is the event from cm contextmenu event\n\t\t\tif (!e.target.classList.contains('cm-spell-error')) return false; // not on typo\n\n\t\t\tlet token = e.target.innerText;\n\t\t\tif (!token) return false; // sanity\n\n\t\t\t// save cm instance, token, token coordinates in sbox\n\t\t\tsbox.codeMirror = cm;\n\t\t\tsbox.token = token;\n\t\t\tsbox.screenPos={ x: e.pageX, y: e.pageY }\n\t\t\tlet tokenRect = e.target.getBoundingClientRect();\n\t\t\tlet start=cm.coordsChar({left: tokenRect.left+1, top: tokenRect.top+1});\n\t\t\tlet end=cm.coordsChar({left: tokenRect.right-1, top: tokenRect.top+1});\n\t\t\tsbox.cmpos={ line: start.line, start: start.ch, end: end.ch};\n\n\t\t\t// show hourglass\n\t\t\t// sboxShow(cm, sbox, [], e.pageX, e.pageY, true);\n      \n\t\t\tvar results = [];\n\t\n      // async \n\t\t\ttypo.suggest(token, null, all => {\n\t\t\t\t//console.log('done');\n\t\t\t\tsboxShow(cm, sbox, results, e.pageX, e.pageY);\n\t\t\t}, next => {\n\t\t\t\t//console.log('found '+next);\n\t\t\t\tresults.push(next);\n\t\t\t\tsboxShow(cm, sbox, results, e.pageX, e.pageY, true);\n\t\t\t});\n\n\t\t\t// non async \n\t\t\t// sboxShow(cm, sbox, typo.suggest(token), e.pageX, e.pageY);\n\n\t\t\te.preventDefault();\n\n\t\t\treturn false;\n\t\t});\n\n\t\tsbox.onmouseout = (e => {\n\t\t\tlet related=(e.relatedTarget ? e.relatedTarget.tagName : null);\n\t\t\tif (related!=='SELECT' && related!=='OPTION') sboxHide(sbox)\n\t\t});\n\n\t\tselwidget.onchange = (e => {\n\t\t\tsboxHide(sbox)\n\t\t\tlet cm = sbox.codeMirror, correction = e.target.value;\n\t\t\tif (correction == '##ignoreall##') {\n        \n\t\t\t\tignoreDict[sbox.token] = true;\n        saveIgnoreDict(ignoreDict);\n\t\t\t\tcm.setOption('maxHighlightLength', (--cm.options.maxHighlightLength) + 1); // ugly hack to rerun overlays\n\t\t\t} else {\n\t\t\t\tcm.replaceRange(correction, { line: sbox.cmpos.line, ch: sbox.cmpos.start}, { line: sbox.cmpos.line, ch: sbox.cmpos.end});\n\t\t\t\tcm.focus();\n\t\t\t\tcm.setCursor({line: sbox.cmpos.line, ch: sbox.cmpos.start+correction.length});\n\t\t\t}\n\t\t});\n\n\t\tdocument.body.appendChild(sbox);\n\t}\n\n\treturn sbox;\n}"]}