tinymce_plugins_spellchecker.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. import {
  2. __commonJS
  3. } from "./chunk-2LSFTFF7.js";
  4. // node_modules/.pnpm/tinymce@5.10.7/node_modules/tinymce/plugins/spellchecker/plugin.js
  5. var require_plugin = __commonJS({
  6. "node_modules/.pnpm/tinymce@5.10.7/node_modules/tinymce/plugins/spellchecker/plugin.js"() {
  7. (function() {
  8. "use strict";
  9. var Cell = function(initial) {
  10. var value = initial;
  11. var get2 = function() {
  12. return value;
  13. };
  14. var set = function(v) {
  15. value = v;
  16. };
  17. return {
  18. get: get2,
  19. set
  20. };
  21. };
  22. var global$3 = tinymce.util.Tools.resolve("tinymce.PluginManager");
  23. var hasProPlugin = function(editor) {
  24. if (editor.hasPlugin("tinymcespellchecker", true)) {
  25. if (typeof window.console !== "undefined" && window.console.log) {
  26. window.console.log("Spell Checker Pro is incompatible with Spell Checker plugin! Remove 'spellchecker' from the 'plugins' option.");
  27. }
  28. return true;
  29. } else {
  30. return false;
  31. }
  32. };
  33. var hasOwnProperty = Object.hasOwnProperty;
  34. var isEmpty = function(r) {
  35. for (var x in r) {
  36. if (hasOwnProperty.call(r, x)) {
  37. return false;
  38. }
  39. }
  40. return true;
  41. };
  42. var global$2 = tinymce.util.Tools.resolve("tinymce.util.Tools");
  43. var global$1 = tinymce.util.Tools.resolve("tinymce.util.URI");
  44. var global = tinymce.util.Tools.resolve("tinymce.util.XHR");
  45. var fireSpellcheckStart = function(editor) {
  46. return editor.fire("SpellcheckStart");
  47. };
  48. var fireSpellcheckEnd = function(editor) {
  49. return editor.fire("SpellcheckEnd");
  50. };
  51. var getLanguages = function(editor) {
  52. var defaultLanguages = "English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr_FR,German=de,Italian=it,Polish=pl,Portuguese=pt_BR,Spanish=es,Swedish=sv";
  53. return editor.getParam("spellchecker_languages", defaultLanguages);
  54. };
  55. var getLanguage = function(editor) {
  56. var defaultLanguage = editor.getParam("language", "en");
  57. return editor.getParam("spellchecker_language", defaultLanguage);
  58. };
  59. var getRpcUrl = function(editor) {
  60. return editor.getParam("spellchecker_rpc_url");
  61. };
  62. var getSpellcheckerCallback = function(editor) {
  63. return editor.getParam("spellchecker_callback");
  64. };
  65. var getSpellcheckerWordcharPattern = function(editor) {
  66. var defaultPattern = new RegExp('[^\\s!"#$%&()*+,-./:;<=>?@[\\]^_{|}`§©«®±¶·¸»¼½¾¿×÷¤”“„    ]+', "g");
  67. return editor.getParam("spellchecker_wordchar_pattern", defaultPattern);
  68. };
  69. var isContentEditableFalse = function(node) {
  70. return node && node.nodeType === 1 && node.contentEditable === "false";
  71. };
  72. var DomTextMatcher = function(node, editor) {
  73. var m, matches = [];
  74. var dom = editor.dom;
  75. var blockElementsMap = editor.schema.getBlockElements();
  76. var hiddenTextElementsMap = editor.schema.getWhiteSpaceElements();
  77. var shortEndedElementsMap = editor.schema.getShortEndedElements();
  78. var createMatch = function(m2, data) {
  79. if (!m2[0]) {
  80. throw new Error("findAndReplaceDOMText cannot handle zero-length matches");
  81. }
  82. return {
  83. start: m2.index,
  84. end: m2.index + m2[0].length,
  85. text: m2[0],
  86. data
  87. };
  88. };
  89. var getText = function(node2) {
  90. if (node2.nodeType === 3) {
  91. return node2.data;
  92. }
  93. if (hiddenTextElementsMap[node2.nodeName] && !blockElementsMap[node2.nodeName]) {
  94. return "";
  95. }
  96. if (isContentEditableFalse(node2)) {
  97. return "\n";
  98. }
  99. var txt = "";
  100. if (blockElementsMap[node2.nodeName] || shortEndedElementsMap[node2.nodeName]) {
  101. txt += "\n";
  102. }
  103. if (node2 = node2.firstChild) {
  104. do {
  105. txt += getText(node2);
  106. } while (node2 = node2.nextSibling);
  107. }
  108. return txt;
  109. };
  110. var stepThroughMatches = function(node2, matches2, replaceFn) {
  111. var startNode, endNode, startNodeIndex, endNodeIndex, innerNodes = [], atIndex = 0, curNode = node2, matchLocation, matchIndex = 0;
  112. matches2 = matches2.slice(0);
  113. matches2.sort(function(a, b) {
  114. return a.start - b.start;
  115. });
  116. matchLocation = matches2.shift();
  117. out:
  118. while (true) {
  119. if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName] || isContentEditableFalse(curNode)) {
  120. atIndex++;
  121. }
  122. if (curNode.nodeType === 3) {
  123. if (!endNode && curNode.length + atIndex >= matchLocation.end) {
  124. endNode = curNode;
  125. endNodeIndex = matchLocation.end - atIndex;
  126. } else if (startNode) {
  127. innerNodes.push(curNode);
  128. }
  129. if (!startNode && curNode.length + atIndex > matchLocation.start) {
  130. startNode = curNode;
  131. startNodeIndex = matchLocation.start - atIndex;
  132. }
  133. atIndex += curNode.length;
  134. }
  135. if (startNode && endNode) {
  136. curNode = replaceFn({
  137. startNode,
  138. startNodeIndex,
  139. endNode,
  140. endNodeIndex,
  141. innerNodes,
  142. match: matchLocation.text,
  143. matchIndex
  144. });
  145. atIndex -= endNode.length - endNodeIndex;
  146. startNode = null;
  147. endNode = null;
  148. innerNodes = [];
  149. matchLocation = matches2.shift();
  150. matchIndex++;
  151. if (!matchLocation) {
  152. break;
  153. }
  154. } else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) {
  155. if (!isContentEditableFalse(curNode)) {
  156. curNode = curNode.firstChild;
  157. continue;
  158. }
  159. } else if (curNode.nextSibling) {
  160. curNode = curNode.nextSibling;
  161. continue;
  162. }
  163. while (true) {
  164. if (curNode.nextSibling) {
  165. curNode = curNode.nextSibling;
  166. break;
  167. } else if (curNode.parentNode !== node2) {
  168. curNode = curNode.parentNode;
  169. } else {
  170. break out;
  171. }
  172. }
  173. }
  174. };
  175. var genReplacer = function(callback) {
  176. var makeReplacementNode = function(fill, matchIndex) {
  177. var match = matches[matchIndex];
  178. if (!match.stencil) {
  179. match.stencil = callback(match);
  180. }
  181. var clone = match.stencil.cloneNode(false);
  182. clone.setAttribute("data-mce-index", "" + matchIndex);
  183. if (fill) {
  184. clone.appendChild(dom.doc.createTextNode(fill));
  185. }
  186. return clone;
  187. };
  188. return function(range) {
  189. var before;
  190. var after;
  191. var parentNode;
  192. var startNode = range.startNode;
  193. var endNode = range.endNode;
  194. var matchIndex = range.matchIndex;
  195. var doc = dom.doc;
  196. if (startNode === endNode) {
  197. var node_1 = startNode;
  198. parentNode = node_1.parentNode;
  199. if (range.startNodeIndex > 0) {
  200. before = doc.createTextNode(node_1.data.substring(0, range.startNodeIndex));
  201. parentNode.insertBefore(before, node_1);
  202. }
  203. var el = makeReplacementNode(range.match, matchIndex);
  204. parentNode.insertBefore(el, node_1);
  205. if (range.endNodeIndex < node_1.length) {
  206. after = doc.createTextNode(node_1.data.substring(range.endNodeIndex));
  207. parentNode.insertBefore(after, node_1);
  208. }
  209. node_1.parentNode.removeChild(node_1);
  210. return el;
  211. }
  212. before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex));
  213. after = doc.createTextNode(endNode.data.substring(range.endNodeIndex));
  214. var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex);
  215. for (var i = 0, l = range.innerNodes.length; i < l; ++i) {
  216. var innerNode = range.innerNodes[i];
  217. var innerEl = makeReplacementNode(innerNode.data, matchIndex);
  218. innerNode.parentNode.replaceChild(innerEl, innerNode);
  219. }
  220. var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex);
  221. parentNode = startNode.parentNode;
  222. parentNode.insertBefore(before, startNode);
  223. parentNode.insertBefore(elA, startNode);
  224. parentNode.removeChild(startNode);
  225. parentNode = endNode.parentNode;
  226. parentNode.insertBefore(elB, endNode);
  227. parentNode.insertBefore(after, endNode);
  228. parentNode.removeChild(endNode);
  229. return elB;
  230. };
  231. };
  232. var unwrapElement = function(element) {
  233. var parentNode = element.parentNode;
  234. while (element.childNodes.length > 0) {
  235. parentNode.insertBefore(element.childNodes[0], element);
  236. }
  237. parentNode.removeChild(element);
  238. };
  239. var hasClass = function(elm) {
  240. return elm.className.indexOf("mce-spellchecker-word") !== -1;
  241. };
  242. var getWrappersByIndex = function(index) {
  243. var elements = node.getElementsByTagName("*"), wrappers = [];
  244. index = typeof index === "number" ? "" + index : null;
  245. for (var i = 0; i < elements.length; i++) {
  246. var element = elements[i], dataIndex = element.getAttribute("data-mce-index");
  247. if (dataIndex !== null && dataIndex.length && hasClass(element)) {
  248. if (dataIndex === index || index === null) {
  249. wrappers.push(element);
  250. }
  251. }
  252. }
  253. return wrappers;
  254. };
  255. var indexOf = function(match) {
  256. var i = matches.length;
  257. while (i--) {
  258. if (matches[i] === match) {
  259. return i;
  260. }
  261. }
  262. return -1;
  263. };
  264. function filter(callback) {
  265. var filteredMatches = [];
  266. each(function(match, i) {
  267. if (callback(match, i)) {
  268. filteredMatches.push(match);
  269. }
  270. });
  271. matches = filteredMatches;
  272. return this;
  273. }
  274. function each(callback) {
  275. for (var i = 0, l = matches.length; i < l; i++) {
  276. if (callback(matches[i], i) === false) {
  277. break;
  278. }
  279. }
  280. return this;
  281. }
  282. function wrap(callback) {
  283. if (matches.length) {
  284. stepThroughMatches(node, matches, genReplacer(callback));
  285. }
  286. return this;
  287. }
  288. function find(regex, data) {
  289. if (text && regex.global) {
  290. while (m = regex.exec(text)) {
  291. matches.push(createMatch(m, data));
  292. }
  293. }
  294. return this;
  295. }
  296. function unwrap(match) {
  297. var i;
  298. var elements = getWrappersByIndex(match ? indexOf(match) : null);
  299. i = elements.length;
  300. while (i--) {
  301. unwrapElement(elements[i]);
  302. }
  303. return this;
  304. }
  305. var matchFromElement = function(element) {
  306. return matches[element.getAttribute("data-mce-index")];
  307. };
  308. var elementFromMatch = function(match) {
  309. return getWrappersByIndex(indexOf(match))[0];
  310. };
  311. function add(start, length, data) {
  312. matches.push({
  313. start,
  314. end: start + length,
  315. text: text.substr(start, length),
  316. data
  317. });
  318. return this;
  319. }
  320. var rangeFromMatch = function(match) {
  321. var wrappers = getWrappersByIndex(indexOf(match));
  322. var rng = editor.dom.createRng();
  323. rng.setStartBefore(wrappers[0]);
  324. rng.setEndAfter(wrappers[wrappers.length - 1]);
  325. return rng;
  326. };
  327. var replace = function(match, text2) {
  328. var rng = rangeFromMatch(match);
  329. rng.deleteContents();
  330. if (text2.length > 0) {
  331. rng.insertNode(editor.dom.doc.createTextNode(text2));
  332. }
  333. return rng;
  334. };
  335. function reset() {
  336. matches.splice(0, matches.length);
  337. unwrap();
  338. return this;
  339. }
  340. var text = getText(node);
  341. return {
  342. text,
  343. matches,
  344. each,
  345. filter,
  346. reset,
  347. matchFromElement,
  348. elementFromMatch,
  349. find,
  350. add,
  351. wrap,
  352. unwrap,
  353. replace,
  354. rangeFromMatch,
  355. indexOf
  356. };
  357. };
  358. var getTextMatcher = function(editor, textMatcherState) {
  359. if (!textMatcherState.get()) {
  360. var textMatcher = DomTextMatcher(editor.getBody(), editor);
  361. textMatcherState.set(textMatcher);
  362. }
  363. return textMatcherState.get();
  364. };
  365. var defaultSpellcheckCallback = function(editor, pluginUrl, currentLanguageState) {
  366. return function(method, text, doneCallback, errorCallback) {
  367. var data = {
  368. method,
  369. lang: currentLanguageState.get()
  370. };
  371. var postData = "";
  372. data[method === "addToDictionary" ? "word" : "text"] = text;
  373. global$2.each(data, function(value, key) {
  374. if (postData) {
  375. postData += "&";
  376. }
  377. postData += key + "=" + encodeURIComponent(value);
  378. });
  379. global.send({
  380. url: new global$1(pluginUrl).toAbsolute(getRpcUrl(editor)),
  381. type: "post",
  382. content_type: "application/x-www-form-urlencoded",
  383. data: postData,
  384. success: function(result) {
  385. var parseResult = JSON.parse(result);
  386. if (!parseResult) {
  387. var message = editor.translate("Server response wasn't proper JSON.");
  388. errorCallback(message);
  389. } else if (parseResult.error) {
  390. errorCallback(parseResult.error);
  391. } else {
  392. doneCallback(parseResult);
  393. }
  394. },
  395. error: function() {
  396. var message = editor.translate("The spelling service was not found: (") + getRpcUrl(editor) + editor.translate(")");
  397. errorCallback(message);
  398. }
  399. });
  400. };
  401. };
  402. var sendRpcCall = function(editor, pluginUrl, currentLanguageState, name, data, successCallback, errorCallback) {
  403. var userSpellcheckCallback = getSpellcheckerCallback(editor);
  404. var spellCheckCallback = userSpellcheckCallback ? userSpellcheckCallback : defaultSpellcheckCallback(editor, pluginUrl, currentLanguageState);
  405. spellCheckCallback.call(editor.plugins.spellchecker, name, data, successCallback, errorCallback);
  406. };
  407. var spellcheck = function(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState) {
  408. if (finish(editor, startedState, textMatcherState)) {
  409. return;
  410. }
  411. var errorCallback = function(message) {
  412. editor.notificationManager.open({
  413. text: message,
  414. type: "error"
  415. });
  416. editor.setProgressState(false);
  417. finish(editor, startedState, textMatcherState);
  418. };
  419. var successCallback = function(data) {
  420. markErrors(editor, startedState, textMatcherState, lastSuggestionsState, data);
  421. };
  422. editor.setProgressState(true);
  423. sendRpcCall(editor, pluginUrl, currentLanguageState, "spellcheck", getTextMatcher(editor, textMatcherState).text, successCallback, errorCallback);
  424. editor.focus();
  425. };
  426. var checkIfFinished = function(editor, startedState, textMatcherState) {
  427. if (!editor.dom.select("span.mce-spellchecker-word").length) {
  428. finish(editor, startedState, textMatcherState);
  429. }
  430. };
  431. var addToDictionary = function(editor, pluginUrl, startedState, textMatcherState, currentLanguageState, word, spans) {
  432. editor.setProgressState(true);
  433. sendRpcCall(editor, pluginUrl, currentLanguageState, "addToDictionary", word, function() {
  434. editor.setProgressState(false);
  435. editor.dom.remove(spans, true);
  436. checkIfFinished(editor, startedState, textMatcherState);
  437. }, function(message) {
  438. editor.notificationManager.open({
  439. text: message,
  440. type: "error"
  441. });
  442. editor.setProgressState(false);
  443. });
  444. };
  445. var ignoreWord = function(editor, startedState, textMatcherState, word, spans, all) {
  446. editor.selection.collapse();
  447. if (all) {
  448. global$2.each(editor.dom.select("span.mce-spellchecker-word"), function(span) {
  449. if (span.getAttribute("data-mce-word") === word) {
  450. editor.dom.remove(span, true);
  451. }
  452. });
  453. } else {
  454. editor.dom.remove(spans, true);
  455. }
  456. checkIfFinished(editor, startedState, textMatcherState);
  457. };
  458. var finish = function(editor, startedState, textMatcherState) {
  459. var bookmark = editor.selection.getBookmark();
  460. getTextMatcher(editor, textMatcherState).reset();
  461. editor.selection.moveToBookmark(bookmark);
  462. textMatcherState.set(null);
  463. if (startedState.get()) {
  464. startedState.set(false);
  465. fireSpellcheckEnd(editor);
  466. return true;
  467. }
  468. };
  469. var getElmIndex = function(elm) {
  470. var value = elm.getAttribute("data-mce-index");
  471. if (typeof value === "number") {
  472. return "" + value;
  473. }
  474. return value;
  475. };
  476. var findSpansByIndex = function(editor, index) {
  477. var spans = [];
  478. var nodes = global$2.toArray(editor.getBody().getElementsByTagName("span"));
  479. if (nodes.length) {
  480. for (var i = 0; i < nodes.length; i++) {
  481. var nodeIndex = getElmIndex(nodes[i]);
  482. if (nodeIndex === null || !nodeIndex.length) {
  483. continue;
  484. }
  485. if (nodeIndex === index.toString()) {
  486. spans.push(nodes[i]);
  487. }
  488. }
  489. }
  490. return spans;
  491. };
  492. var markErrors = function(editor, startedState, textMatcherState, lastSuggestionsState, data) {
  493. var hasDictionarySupport = !!data.dictionary;
  494. var suggestions = data.words;
  495. editor.setProgressState(false);
  496. if (isEmpty(suggestions)) {
  497. var message = editor.translate("No misspellings found.");
  498. editor.notificationManager.open({
  499. text: message,
  500. type: "info"
  501. });
  502. startedState.set(false);
  503. return;
  504. }
  505. lastSuggestionsState.set({
  506. suggestions,
  507. hasDictionarySupport
  508. });
  509. var bookmark = editor.selection.getBookmark();
  510. getTextMatcher(editor, textMatcherState).find(getSpellcheckerWordcharPattern(editor)).filter(function(match) {
  511. return !!suggestions[match.text];
  512. }).wrap(function(match) {
  513. return editor.dom.create("span", {
  514. "class": "mce-spellchecker-word",
  515. "aria-invalid": "spelling",
  516. "data-mce-bogus": 1,
  517. "data-mce-word": match.text
  518. });
  519. });
  520. editor.selection.moveToBookmark(bookmark);
  521. startedState.set(true);
  522. fireSpellcheckStart(editor);
  523. };
  524. var get = function(editor, startedState, lastSuggestionsState, textMatcherState, currentLanguageState) {
  525. var getWordCharPattern = function() {
  526. return getSpellcheckerWordcharPattern(editor);
  527. };
  528. var markErrors$1 = function(data) {
  529. markErrors(editor, startedState, textMatcherState, lastSuggestionsState, data);
  530. };
  531. return {
  532. getTextMatcher: textMatcherState.get,
  533. getWordCharPattern,
  534. markErrors: markErrors$1,
  535. getLanguage: currentLanguageState.get
  536. };
  537. };
  538. var register$1 = function(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState) {
  539. editor.addCommand("mceSpellCheck", function() {
  540. spellcheck(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState);
  541. });
  542. };
  543. var __assign = function() {
  544. __assign = Object.assign || function __assign2(t) {
  545. for (var s, i = 1, n = arguments.length; i < n; i++) {
  546. s = arguments[i];
  547. for (var p in s)
  548. if (Object.prototype.hasOwnProperty.call(s, p))
  549. t[p] = s[p];
  550. }
  551. return t;
  552. };
  553. return __assign.apply(this, arguments);
  554. };
  555. var spellcheckerEvents = "SpellcheckStart SpellcheckEnd";
  556. var buildMenuItems = function(listName, languageValues) {
  557. var items = [];
  558. global$2.each(languageValues, function(languageValue) {
  559. items.push({
  560. selectable: true,
  561. text: languageValue.name,
  562. data: languageValue.value
  563. });
  564. });
  565. return items;
  566. };
  567. var getItems = function(editor) {
  568. return global$2.map(getLanguages(editor).split(","), function(langPair) {
  569. var langPairs = langPair.split("=");
  570. return {
  571. name: langPairs[0],
  572. value: langPairs[1]
  573. };
  574. });
  575. };
  576. var register = function(editor, pluginUrl, startedState, textMatcherState, currentLanguageState, lastSuggestionsState) {
  577. var languageMenuItems = buildMenuItems("Language", getItems(editor));
  578. var startSpellchecking = function() {
  579. spellcheck(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState);
  580. };
  581. var buttonArgs = {
  582. tooltip: "Spellcheck",
  583. onAction: startSpellchecking,
  584. icon: "spell-check",
  585. onSetup: function(buttonApi) {
  586. var setButtonState = function() {
  587. buttonApi.setActive(startedState.get());
  588. };
  589. editor.on(spellcheckerEvents, setButtonState);
  590. return function() {
  591. editor.off(spellcheckerEvents, setButtonState);
  592. };
  593. }
  594. };
  595. var splitButtonArgs = __assign(__assign({}, buttonArgs), {
  596. type: "splitbutton",
  597. select: function(value) {
  598. return value === currentLanguageState.get();
  599. },
  600. fetch: function(callback) {
  601. var items = global$2.map(languageMenuItems, function(languageItem) {
  602. return {
  603. type: "choiceitem",
  604. value: languageItem.data,
  605. text: languageItem.text
  606. };
  607. });
  608. callback(items);
  609. },
  610. onItemAction: function(splitButtonApi, value) {
  611. currentLanguageState.set(value);
  612. }
  613. });
  614. if (languageMenuItems.length > 1) {
  615. editor.ui.registry.addSplitButton("spellchecker", splitButtonArgs);
  616. } else {
  617. editor.ui.registry.addToggleButton("spellchecker", buttonArgs);
  618. }
  619. editor.ui.registry.addToggleMenuItem("spellchecker", {
  620. text: "Spellcheck",
  621. icon: "spell-check",
  622. onSetup: function(menuApi) {
  623. menuApi.setActive(startedState.get());
  624. var setMenuItemCheck = function() {
  625. menuApi.setActive(startedState.get());
  626. };
  627. editor.on(spellcheckerEvents, setMenuItemCheck);
  628. return function() {
  629. editor.off(spellcheckerEvents, setMenuItemCheck);
  630. };
  631. },
  632. onAction: startSpellchecking
  633. });
  634. };
  635. var ignoreAll = true;
  636. var getSuggestions = function(editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState, word, spans) {
  637. var items = [];
  638. var suggestions = lastSuggestionsState.get().suggestions[word];
  639. global$2.each(suggestions, function(suggestion) {
  640. items.push({
  641. text: suggestion,
  642. onAction: function() {
  643. editor.insertContent(editor.dom.encode(suggestion));
  644. editor.dom.remove(spans);
  645. checkIfFinished(editor, startedState, textMatcherState);
  646. }
  647. });
  648. });
  649. var hasDictionarySupport = lastSuggestionsState.get().hasDictionarySupport;
  650. if (hasDictionarySupport) {
  651. items.push({ type: "separator" });
  652. items.push({
  653. text: "Add to dictionary",
  654. onAction: function() {
  655. addToDictionary(editor, pluginUrl, startedState, textMatcherState, currentLanguageState, word, spans);
  656. }
  657. });
  658. }
  659. items.push.apply(items, [
  660. { type: "separator" },
  661. {
  662. text: "Ignore",
  663. onAction: function() {
  664. ignoreWord(editor, startedState, textMatcherState, word, spans);
  665. }
  666. },
  667. {
  668. text: "Ignore all",
  669. onAction: function() {
  670. ignoreWord(editor, startedState, textMatcherState, word, spans, ignoreAll);
  671. }
  672. }
  673. ]);
  674. return items;
  675. };
  676. var setup = function(editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState) {
  677. var update = function(element) {
  678. var target = element;
  679. if (target.className === "mce-spellchecker-word") {
  680. var spans = findSpansByIndex(editor, getElmIndex(target));
  681. if (spans.length > 0) {
  682. var rng = editor.dom.createRng();
  683. rng.setStartBefore(spans[0]);
  684. rng.setEndAfter(spans[spans.length - 1]);
  685. editor.selection.setRng(rng);
  686. return getSuggestions(editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState, target.getAttribute("data-mce-word"), spans);
  687. }
  688. } else {
  689. return [];
  690. }
  691. };
  692. editor.ui.registry.addContextMenu("spellchecker", { update });
  693. };
  694. function Plugin() {
  695. global$3.add("spellchecker", function(editor, pluginUrl) {
  696. if (hasProPlugin(editor) === false) {
  697. var startedState = Cell(false);
  698. var currentLanguageState = Cell(getLanguage(editor));
  699. var textMatcherState = Cell(null);
  700. var lastSuggestionsState = Cell(null);
  701. register(editor, pluginUrl, startedState, textMatcherState, currentLanguageState, lastSuggestionsState);
  702. setup(editor, pluginUrl, lastSuggestionsState, startedState, textMatcherState, currentLanguageState);
  703. register$1(editor, pluginUrl, startedState, textMatcherState, lastSuggestionsState, currentLanguageState);
  704. return get(editor, startedState, lastSuggestionsState, textMatcherState, currentLanguageState);
  705. }
  706. });
  707. }
  708. Plugin();
  709. })();
  710. }
  711. });
  712. // node_modules/.pnpm/tinymce@5.10.7/node_modules/tinymce/plugins/spellchecker/index.js
  713. require_plugin();
  714. //# sourceMappingURL=tinymce_plugins_spellchecker.js.map