plugin.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /**
  2. * Copyright (c) Tiny Technologies, Inc. All rights reserved.
  3. * Licensed under the LGPL or a commercial license.
  4. * For LGPL see License.txt in the project root for license information.
  5. * For commercial licenses see https://www.tiny.cloud/
  6. *
  7. * Version: 5.0.1 (2019-02-21)
  8. */
  9. (function () {
  10. var wordcount = (function () {
  11. 'use strict';
  12. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  13. var global$1 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
  14. var __assign = function () {
  15. __assign = Object.assign || function __assign(t) {
  16. for (var s, i = 1, n = arguments.length; i < n; i++) {
  17. s = arguments[i];
  18. for (var p in s)
  19. if (Object.prototype.hasOwnProperty.call(s, p))
  20. t[p] = s[p];
  21. }
  22. return t;
  23. };
  24. return __assign.apply(this, arguments);
  25. };
  26. var regExps = {
  27. aletter: '[A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05F3\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u10a0-\u10c5\u10d0-\u10fa\u10fc\u1100-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1a00-\u1a16\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bc0-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u24B6-\u24E9\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2d00-\u2d25\u2d30-\u2d65\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005\u303b\u303c\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790\ua791\ua7a0-\ua7a9\ua7fa-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uffa0-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]',
  28. midnumlet: '[-\'\\.\u2018\u2019\u2024\uFE52\uFF07\uFF0E]',
  29. midletter: '[:\xB7\xB7\u05F4\u2027\uFE13\uFE55\uFF1A]',
  30. midnum: '[\xB1+*/,;;\u0589\u060C\u060D\u066C\u07F8\u2044\uFE10\uFE14\uFE50\uFE54\uFF0C\uFF1B]',
  31. numeric: '[0-9\u0660-\u0669\u066B\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\uaa50-\uaa59\uabf0-\uabf9]',
  32. cr: '\\r',
  33. lf: '\\n',
  34. newline: '[\x0B\f\x85\u2028\u2029]',
  35. extend: '[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f\u109a-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b6-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u192b\u1930-\u193b\u19b0-\u19c0\u19c8\u19c9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f\u1b00-\u1b04\u1b34-\u1b44\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1baa\u1be6-\u1bf3\u1c24-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\uA672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe3-\uabea\uabec\uabed\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]',
  36. format: '[\xAD\u0600-\u0603\u06DD\u070F\u17b4\u17b5\u200E\u200F\u202A-\u202E\u2060-\u2064\u206A-\u206F\uFEFF\uFFF9-\uFFFB]',
  37. katakana: '[\u3031-\u3035\u309B\u309C\u30A0-\u30fa\u30fc-\u30ff\u31f0-\u31ff\u32D0-\u32FE\u3300-\u3357\uff66-\uff9d]',
  38. extendnumlet: '[=_\u203f\u2040\u2054\ufe33\ufe34\ufe4d-\ufe4f\uff3f\u2200-\u22FF<>]',
  39. punctuation: '[!-#%-*,-\\/:;?@\\[-\\]_{}\xA1\xAB\xB7\xBB\xBF;\xB7\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1361-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u3008\u3009\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30\u2E31\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uff3f\uFF5B\uFF5D\uFF5F-\uFF65]'
  40. };
  41. var characterIndices = {
  42. ALETTER: 0,
  43. MIDNUMLET: 1,
  44. MIDLETTER: 2,
  45. MIDNUM: 3,
  46. NUMERIC: 4,
  47. CR: 5,
  48. LF: 6,
  49. NEWLINE: 7,
  50. EXTEND: 8,
  51. FORMAT: 9,
  52. KATAKANA: 10,
  53. EXTENDNUMLET: 11,
  54. AT: 12,
  55. OTHER: 13
  56. };
  57. var SETS = [
  58. new RegExp(regExps.aletter),
  59. new RegExp(regExps.midnumlet),
  60. new RegExp(regExps.midletter),
  61. new RegExp(regExps.midnum),
  62. new RegExp(regExps.numeric),
  63. new RegExp(regExps.cr),
  64. new RegExp(regExps.lf),
  65. new RegExp(regExps.newline),
  66. new RegExp(regExps.extend),
  67. new RegExp(regExps.format),
  68. new RegExp(regExps.katakana),
  69. new RegExp(regExps.extendnumlet),
  70. new RegExp('@')
  71. ];
  72. var EMPTY_STRING = '';
  73. var PUNCTUATION = new RegExp('^' + regExps.punctuation + '$');
  74. var WHITESPACE = /^\s+$/;
  75. var constant = function (value) {
  76. return function () {
  77. return value;
  78. };
  79. };
  80. var identity = function (x) {
  81. return x;
  82. };
  83. var never = constant(false);
  84. var always = constant(true);
  85. var never$1 = never;
  86. var always$1 = always;
  87. var none = function () {
  88. return NONE;
  89. };
  90. var NONE = function () {
  91. var eq = function (o) {
  92. return o.isNone();
  93. };
  94. var call = function (thunk) {
  95. return thunk();
  96. };
  97. var id = function (n) {
  98. return n;
  99. };
  100. var noop = function () {
  101. };
  102. var nul = function () {
  103. return null;
  104. };
  105. var undef = function () {
  106. return undefined;
  107. };
  108. var me = {
  109. fold: function (n, s) {
  110. return n();
  111. },
  112. is: never$1,
  113. isSome: never$1,
  114. isNone: always$1,
  115. getOr: id,
  116. getOrThunk: call,
  117. getOrDie: function (msg) {
  118. throw new Error(msg || 'error: getOrDie called on none.');
  119. },
  120. getOrNull: nul,
  121. getOrUndefined: undef,
  122. or: id,
  123. orThunk: call,
  124. map: none,
  125. ap: none,
  126. each: noop,
  127. bind: none,
  128. flatten: none,
  129. exists: never$1,
  130. forall: always$1,
  131. filter: none,
  132. equals: eq,
  133. equals_: eq,
  134. toArray: function () {
  135. return [];
  136. },
  137. toString: constant('none()')
  138. };
  139. if (Object.freeze)
  140. Object.freeze(me);
  141. return me;
  142. }();
  143. var typeOf = function (x) {
  144. if (x === null)
  145. return 'null';
  146. var t = typeof x;
  147. if (t === 'object' && Array.prototype.isPrototypeOf(x))
  148. return 'array';
  149. if (t === 'object' && String.prototype.isPrototypeOf(x))
  150. return 'string';
  151. return t;
  152. };
  153. var isType = function (type) {
  154. return function (value) {
  155. return typeOf(value) === type;
  156. };
  157. };
  158. var isFunction = isType('function');
  159. var map = function (xs, f) {
  160. var len = xs.length;
  161. var r = new Array(len);
  162. for (var i = 0; i < len; i++) {
  163. var x = xs[i];
  164. r[i] = f(x, i, xs);
  165. }
  166. return r;
  167. };
  168. var slice = Array.prototype.slice;
  169. var from = isFunction(Array.from) ? Array.from : function (x) {
  170. return slice.call(x);
  171. };
  172. var SETS$1 = SETS;
  173. var OTHER = characterIndices.OTHER;
  174. var getType = function (char) {
  175. var type = OTHER;
  176. var setsLength = SETS$1.length;
  177. for (var j = 0; j < setsLength; ++j) {
  178. var set = SETS$1[j];
  179. if (set && set.test(char)) {
  180. type = j;
  181. break;
  182. }
  183. }
  184. return type;
  185. };
  186. var memoize = function (func) {
  187. var cache = {};
  188. return function (char) {
  189. if (cache[char]) {
  190. return cache[char];
  191. } else {
  192. var result = func(char);
  193. cache[char] = result;
  194. return result;
  195. }
  196. };
  197. };
  198. var classify = function (characters) {
  199. var memoized = memoize(getType);
  200. return map(characters, memoized);
  201. };
  202. var isWordBoundary = function (map, index) {
  203. var prevType;
  204. var type = map[index];
  205. var nextType = map[index + 1];
  206. var nextNextType;
  207. if (index < 0 || index > map.length - 1 && index !== 0) {
  208. return false;
  209. }
  210. if (type === characterIndices.ALETTER && nextType === characterIndices.ALETTER) {
  211. return false;
  212. }
  213. nextNextType = map[index + 2];
  214. if (type === characterIndices.ALETTER && (nextType === characterIndices.MIDLETTER || nextType === characterIndices.MIDNUMLET || nextType === characterIndices.AT) && nextNextType === characterIndices.ALETTER) {
  215. return false;
  216. }
  217. prevType = map[index - 1];
  218. if ((type === characterIndices.MIDLETTER || type === characterIndices.MIDNUMLET || nextType === characterIndices.AT) && nextType === characterIndices.ALETTER && prevType === characterIndices.ALETTER) {
  219. return false;
  220. }
  221. if ((type === characterIndices.NUMERIC || type === characterIndices.ALETTER) && (nextType === characterIndices.NUMERIC || nextType === characterIndices.ALETTER)) {
  222. return false;
  223. }
  224. if ((type === characterIndices.MIDNUM || type === characterIndices.MIDNUMLET) && nextType === characterIndices.NUMERIC && prevType === characterIndices.NUMERIC) {
  225. return false;
  226. }
  227. if (type === characterIndices.NUMERIC && (nextType === characterIndices.MIDNUM || nextType === characterIndices.MIDNUMLET) && nextNextType === characterIndices.NUMERIC) {
  228. return false;
  229. }
  230. if (type === characterIndices.EXTEND || type === characterIndices.FORMAT || prevType === characterIndices.EXTEND || prevType === characterIndices.FORMAT || nextType === characterIndices.EXTEND || nextType === characterIndices.FORMAT) {
  231. return false;
  232. }
  233. if (type === characterIndices.CR && nextType === characterIndices.LF) {
  234. return false;
  235. }
  236. if (type === characterIndices.NEWLINE || type === characterIndices.CR || type === characterIndices.LF) {
  237. return true;
  238. }
  239. if (nextType === characterIndices.NEWLINE || nextType === characterIndices.CR || nextType === characterIndices.LF) {
  240. return true;
  241. }
  242. if (type === characterIndices.KATAKANA && nextType === characterIndices.KATAKANA) {
  243. return false;
  244. }
  245. if (nextType === characterIndices.EXTENDNUMLET && (type === characterIndices.ALETTER || type === characterIndices.NUMERIC || type === characterIndices.KATAKANA || type === characterIndices.EXTENDNUMLET)) {
  246. return false;
  247. }
  248. if (type === characterIndices.EXTENDNUMLET && (nextType === characterIndices.ALETTER || nextType === characterIndices.NUMERIC || nextType === characterIndices.KATAKANA)) {
  249. return false;
  250. }
  251. if (type === characterIndices.AT) {
  252. return false;
  253. }
  254. return true;
  255. };
  256. var EMPTY_STRING$1 = EMPTY_STRING;
  257. var WHITESPACE$1 = WHITESPACE;
  258. var PUNCTUATION$1 = PUNCTUATION;
  259. var isProtocol = function (str) {
  260. return str === 'http' || str === 'https';
  261. };
  262. var findWordEnd = function (characters, startIndex) {
  263. var i;
  264. for (i = startIndex; i < characters.length; i++) {
  265. if (WHITESPACE$1.test(characters[i])) {
  266. break;
  267. }
  268. }
  269. return i;
  270. };
  271. var findUrlEnd = function (characters, startIndex) {
  272. var endIndex = findWordEnd(characters, startIndex + 1);
  273. var peakedWord = characters.slice(startIndex + 1, endIndex).join(EMPTY_STRING$1);
  274. return peakedWord.substr(0, 3) === '://' ? endIndex : startIndex;
  275. };
  276. var findWords = function (chars, sChars, characterMap, options) {
  277. var words = [];
  278. var word = [];
  279. for (var i = 0; i < characterMap.length; ++i) {
  280. word.push(chars[i]);
  281. if (isWordBoundary(characterMap, i)) {
  282. var ch = sChars[i];
  283. if ((options.includeWhitespace || !WHITESPACE$1.test(ch)) && (options.includePunctuation || !PUNCTUATION$1.test(ch))) {
  284. var startOfWord = i - word.length + 1;
  285. var endOfWord = i + 1;
  286. var str = sChars.slice(startOfWord, endOfWord).join(EMPTY_STRING$1);
  287. if (isProtocol(str)) {
  288. var endOfUrl = findUrlEnd(sChars, i);
  289. var url = chars.slice(endOfWord, endOfUrl);
  290. Array.prototype.push.apply(word, url);
  291. i = endOfUrl;
  292. }
  293. words.push(word);
  294. }
  295. word = [];
  296. }
  297. }
  298. return words;
  299. };
  300. var getDefaultOptions = function () {
  301. return {
  302. includeWhitespace: false,
  303. includePunctuation: false
  304. };
  305. };
  306. var getWords = function (chars, extract, options) {
  307. options = __assign({}, getDefaultOptions(), options);
  308. var filteredChars = [];
  309. var extractedChars = [];
  310. for (var i = 0; i < chars.length; i++) {
  311. var ch = extract(chars[i]);
  312. if (ch !== '\uFEFF') {
  313. filteredChars.push(chars[i]);
  314. extractedChars.push(ch);
  315. }
  316. }
  317. var characterMap = classify(extractedChars);
  318. return findWords(filteredChars, extractedChars, characterMap, options);
  319. };
  320. var getWords$1 = getWords;
  321. var getText = function (node, schema) {
  322. var blockElements = schema.getBlockElements();
  323. var shortEndedElements = schema.getShortEndedElements();
  324. var whiteSpaceElements = schema.getWhiteSpaceElements();
  325. var isSeparator = function (node) {
  326. return blockElements[node.nodeName] || shortEndedElements[node.nodeName] || whiteSpaceElements[node.nodeName];
  327. };
  328. var txt = '';
  329. var treeWalker = new global$1(node, node);
  330. while (node = treeWalker.next()) {
  331. if (node.nodeType === 3) {
  332. txt += node.data;
  333. } else if (txt.length !== 0 && isSeparator(node)) {
  334. txt += ' ';
  335. }
  336. }
  337. return txt;
  338. };
  339. var getTextContent = function (editor) {
  340. return editor.removed ? '' : getText(editor.getBody(), editor.schema);
  341. };
  342. var getCount = function (textContent) {
  343. return {
  344. words: getWords$1(textContent.split(''), identity).length,
  345. characters: textContent.length,
  346. charactersNoSpace: textContent.replace(/\s/g, '').length
  347. };
  348. };
  349. var getEditorWordcount = function (editor) {
  350. return getCount(getTextContent(editor));
  351. };
  352. var getSelectionWordcount = function (editor) {
  353. var selectedText = getText(editor.selection.getRng().cloneContents(), editor.schema);
  354. return editor.selection.isCollapsed() ? getCount('') : getCount(selectedText);
  355. };
  356. var get = function (editor) {
  357. var getCount = function () {
  358. return getEditorWordcount(editor).words;
  359. };
  360. return { getCount: getCount };
  361. };
  362. var global$2 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  363. var fireWordCountUpdate = function (editor, wordCount) {
  364. editor.fire('wordCountUpdate', { wordCount: wordCount });
  365. };
  366. var updateCount = function (editor) {
  367. var wordCount = getEditorWordcount(editor);
  368. fireWordCountUpdate(editor, wordCount);
  369. };
  370. var setup = function (editor) {
  371. var debouncedUpdate = global$2.debounce(function () {
  372. return updateCount(editor);
  373. }, 300);
  374. editor.on('init', function () {
  375. updateCount(editor);
  376. global$2.setEditorTimeout(editor, function () {
  377. editor.on('setcontent beforeaddundo undo redo keyup', debouncedUpdate);
  378. }, 0);
  379. });
  380. };
  381. var open = function (editor) {
  382. var documentCount = getEditorWordcount(editor);
  383. var selectionCount = getSelectionWordcount(editor);
  384. editor.windowManager.open({
  385. title: 'Word Count',
  386. body: {
  387. type: 'panel',
  388. items: [{
  389. type: 'table',
  390. header: [
  391. 'Count',
  392. 'Document',
  393. 'Selection'
  394. ],
  395. cells: [
  396. [
  397. 'Words',
  398. String(documentCount.words),
  399. String(selectionCount.words)
  400. ],
  401. [
  402. 'Characters (no spaces)',
  403. String(documentCount.charactersNoSpace),
  404. String(selectionCount.charactersNoSpace)
  405. ],
  406. [
  407. 'Characters',
  408. String(documentCount.characters),
  409. String(selectionCount.characters)
  410. ]
  411. ]
  412. }]
  413. },
  414. buttons: [{
  415. type: 'cancel',
  416. name: 'close',
  417. text: 'Close',
  418. primary: true
  419. }]
  420. });
  421. };
  422. var register = function (editor) {
  423. editor.ui.registry.addButton('wordcount', {
  424. tooltip: 'Word count',
  425. icon: 'character-count',
  426. onAction: function () {
  427. return open(editor);
  428. }
  429. });
  430. editor.ui.registry.addMenuItem('wordcount', {
  431. text: 'Word count',
  432. icon: 'character-count',
  433. onAction: function () {
  434. return open(editor);
  435. }
  436. });
  437. };
  438. global.add('wordcount', function (editor) {
  439. register(editor);
  440. setup(editor);
  441. return get(editor);
  442. });
  443. function Plugin () {
  444. }
  445. return Plugin;
  446. }());
  447. })();