plugin.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. (function () {
  2. var textpattern = (function () {
  3. 'use strict';
  4. var Cell = function (initial) {
  5. var value = initial;
  6. var get = function () {
  7. return value;
  8. };
  9. var set = function (v) {
  10. value = v;
  11. };
  12. var clone = function () {
  13. return Cell(get());
  14. };
  15. return {
  16. get: get,
  17. set: set,
  18. clone: clone
  19. };
  20. };
  21. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  22. var get = function (patternsState) {
  23. var setPatterns = function (newPatterns) {
  24. patternsState.set(newPatterns);
  25. };
  26. var getPatterns = function () {
  27. return patternsState.get();
  28. };
  29. return {
  30. setPatterns: setPatterns,
  31. getPatterns: getPatterns
  32. };
  33. };
  34. var $_fp2mq2rsjkmcws6f = { get: get };
  35. var defaultPatterns = [
  36. {
  37. start: '*',
  38. end: '*',
  39. format: 'italic'
  40. },
  41. {
  42. start: '**',
  43. end: '**',
  44. format: 'bold'
  45. },
  46. {
  47. start: '***',
  48. end: '***',
  49. format: [
  50. 'bold',
  51. 'italic'
  52. ]
  53. },
  54. {
  55. start: '#',
  56. format: 'h1'
  57. },
  58. {
  59. start: '##',
  60. format: 'h2'
  61. },
  62. {
  63. start: '###',
  64. format: 'h3'
  65. },
  66. {
  67. start: '####',
  68. format: 'h4'
  69. },
  70. {
  71. start: '#####',
  72. format: 'h5'
  73. },
  74. {
  75. start: '######',
  76. format: 'h6'
  77. },
  78. {
  79. start: '1. ',
  80. cmd: 'InsertOrderedList'
  81. },
  82. {
  83. start: '* ',
  84. cmd: 'InsertUnorderedList'
  85. },
  86. {
  87. start: '- ',
  88. cmd: 'InsertUnorderedList'
  89. }
  90. ];
  91. var getPatterns = function (editorSettings) {
  92. return editorSettings.textpattern_patterns !== undefined ? editorSettings.textpattern_patterns : defaultPatterns;
  93. };
  94. var $_1rurpvrtjkmcws6g = { getPatterns: getPatterns };
  95. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  96. var global$2 = tinymce.util.Tools.resolve('tinymce.util.VK');
  97. var global$3 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
  98. var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
  99. var sortPatterns = function (patterns) {
  100. return patterns.sort(function (a, b) {
  101. if (a.start.length > b.start.length) {
  102. return -1;
  103. }
  104. if (a.start.length < b.start.length) {
  105. return 1;
  106. }
  107. return 0;
  108. });
  109. };
  110. var findPattern = function (patterns, text) {
  111. for (var i = 0; i < patterns.length; i++) {
  112. if (text.indexOf(patterns[i].start) !== 0) {
  113. continue;
  114. }
  115. if (patterns[i].end && text.lastIndexOf(patterns[i].end) !== text.length - patterns[i].end.length) {
  116. continue;
  117. }
  118. return patterns[i];
  119. }
  120. };
  121. var isMatchingPattern = function (pattern, text, offset, delta) {
  122. var textEnd = text.substr(offset - pattern.end.length - delta, pattern.end.length);
  123. return textEnd === pattern.end;
  124. };
  125. var hasContent = function (offset, delta, pattern) {
  126. return offset - delta - pattern.end.length - pattern.start.length > 0;
  127. };
  128. var findEndPattern = function (patterns, text, offset, delta) {
  129. var pattern, i;
  130. var sortedPatterns = sortPatterns(patterns);
  131. for (i = 0; i < sortedPatterns.length; i++) {
  132. pattern = sortedPatterns[i];
  133. if (pattern.end !== undefined && isMatchingPattern(pattern, text, offset, delta) && hasContent(offset, delta, pattern)) {
  134. return pattern;
  135. }
  136. }
  137. };
  138. var $_beghvss1jkmcws6v = {
  139. findPattern: findPattern,
  140. findEndPattern: findEndPattern
  141. };
  142. var splitContainer = function (container, pattern, endOffset, startOffset, space) {
  143. container = startOffset > 0 ? container.splitText(startOffset) : container;
  144. container.splitText(endOffset - startOffset + pattern.end.length);
  145. container.deleteData(0, pattern.start.length);
  146. container.deleteData(container.data.length - pattern.end.length, pattern.end.length);
  147. return container;
  148. };
  149. var patternFromRng = function (patterns, rng, space) {
  150. if (rng.collapsed === false) {
  151. return;
  152. }
  153. var container = rng.startContainer;
  154. var text = container.data;
  155. var delta = space === true ? 1 : 0;
  156. if (container.nodeType !== 3) {
  157. return;
  158. }
  159. var endPattern = $_beghvss1jkmcws6v.findEndPattern(patterns, text, rng.startOffset, delta);
  160. if (endPattern === undefined) {
  161. return;
  162. }
  163. var endOffset = text.lastIndexOf(endPattern.end, rng.startOffset - delta);
  164. var startOffset = text.lastIndexOf(endPattern.start, endOffset - endPattern.end.length);
  165. endOffset = text.indexOf(endPattern.end, startOffset + endPattern.start.length);
  166. if (startOffset === -1) {
  167. return;
  168. }
  169. var patternRng = document.createRange();
  170. patternRng.setStart(container, startOffset);
  171. patternRng.setEnd(container, endOffset + endPattern.end.length);
  172. var startPattern = $_beghvss1jkmcws6v.findPattern(patterns, patternRng.toString());
  173. if (endPattern === undefined || startPattern !== endPattern || container.data.length <= endPattern.start.length + endPattern.end.length) {
  174. return;
  175. }
  176. return {
  177. pattern: endPattern,
  178. startOffset: startOffset,
  179. endOffset: endOffset
  180. };
  181. };
  182. var splitAndApply = function (editor, container, found, space) {
  183. var formatArray = global$4.isArray(found.pattern.format) ? found.pattern.format : [found.pattern.format];
  184. var validFormats = global$4.grep(formatArray, function (formatName) {
  185. var format = editor.formatter.get(formatName);
  186. return format && format[0].inline;
  187. });
  188. if (validFormats.length !== 0) {
  189. editor.undoManager.transact(function () {
  190. container = splitContainer(container, found.pattern, found.endOffset, found.startOffset, space);
  191. formatArray.forEach(function (format) {
  192. editor.formatter.apply(format, {}, container);
  193. });
  194. });
  195. return container;
  196. }
  197. };
  198. var doApplyInlineFormat = function (editor, patterns, space) {
  199. var rng = editor.selection.getRng(true);
  200. var foundPattern = patternFromRng(patterns, rng, space);
  201. if (foundPattern) {
  202. return splitAndApply(editor, rng.startContainer, foundPattern, space);
  203. }
  204. };
  205. var applyInlineFormatSpace = function (editor, patterns) {
  206. return doApplyInlineFormat(editor, patterns, true);
  207. };
  208. var applyInlineFormatEnter = function (editor, patterns) {
  209. return doApplyInlineFormat(editor, patterns, false);
  210. };
  211. var applyBlockFormat = function (editor, patterns) {
  212. var selection, dom, container, firstTextNode, node, format, textBlockElm, pattern, walker, rng, offset;
  213. selection = editor.selection;
  214. dom = editor.dom;
  215. if (!selection.isCollapsed()) {
  216. return;
  217. }
  218. textBlockElm = dom.getParent(selection.getStart(), 'p');
  219. if (textBlockElm) {
  220. walker = new global$3(textBlockElm, textBlockElm);
  221. while (node = walker.next()) {
  222. if (node.nodeType === 3) {
  223. firstTextNode = node;
  224. break;
  225. }
  226. }
  227. if (firstTextNode) {
  228. pattern = $_beghvss1jkmcws6v.findPattern(patterns, firstTextNode.data);
  229. if (!pattern) {
  230. return;
  231. }
  232. rng = selection.getRng(true);
  233. container = rng.startContainer;
  234. offset = rng.startOffset;
  235. if (firstTextNode === container) {
  236. offset = Math.max(0, offset - pattern.start.length);
  237. }
  238. if (global$4.trim(firstTextNode.data).length === pattern.start.length) {
  239. return;
  240. }
  241. if (pattern.format) {
  242. format = editor.formatter.get(pattern.format);
  243. if (format && format[0].block) {
  244. firstTextNode.deleteData(0, pattern.start.length);
  245. editor.formatter.apply(pattern.format, {}, firstTextNode);
  246. rng.setStart(container, offset);
  247. rng.collapse(true);
  248. selection.setRng(rng);
  249. }
  250. }
  251. if (pattern.cmd) {
  252. editor.undoManager.transact(function () {
  253. firstTextNode.deleteData(0, pattern.start.length);
  254. editor.execCommand(pattern.cmd);
  255. });
  256. }
  257. }
  258. }
  259. };
  260. var $_c3c0zdryjkmcws6m = {
  261. patternFromRng: patternFromRng,
  262. applyInlineFormatSpace: applyInlineFormatSpace,
  263. applyInlineFormatEnter: applyInlineFormatEnter,
  264. applyBlockFormat: applyBlockFormat
  265. };
  266. function handleEnter(editor, patterns) {
  267. var wrappedTextNode, rng;
  268. wrappedTextNode = $_c3c0zdryjkmcws6m.applyInlineFormatEnter(editor, patterns);
  269. if (wrappedTextNode) {
  270. rng = editor.dom.createRng();
  271. rng.setStart(wrappedTextNode, wrappedTextNode.data.length);
  272. rng.setEnd(wrappedTextNode, wrappedTextNode.data.length);
  273. editor.selection.setRng(rng);
  274. }
  275. $_c3c0zdryjkmcws6m.applyBlockFormat(editor, patterns);
  276. }
  277. function handleInlineKey(editor, patterns) {
  278. var wrappedTextNode, lastChar, lastCharNode, rng, dom;
  279. wrappedTextNode = $_c3c0zdryjkmcws6m.applyInlineFormatSpace(editor, patterns);
  280. if (wrappedTextNode) {
  281. dom = editor.dom;
  282. lastChar = wrappedTextNode.data.slice(-1);
  283. if (/[\u00a0 ]/.test(lastChar)) {
  284. wrappedTextNode.deleteData(wrappedTextNode.data.length - 1, 1);
  285. lastCharNode = dom.doc.createTextNode(lastChar);
  286. dom.insertAfter(lastCharNode, wrappedTextNode.parentNode);
  287. rng = dom.createRng();
  288. rng.setStart(lastCharNode, 1);
  289. rng.setEnd(lastCharNode, 1);
  290. editor.selection.setRng(rng);
  291. }
  292. }
  293. }
  294. var checkKeyEvent = function (codes, event, predicate) {
  295. for (var i = 0; i < codes.length; i++) {
  296. if (predicate(codes[i], event)) {
  297. return true;
  298. }
  299. }
  300. };
  301. var checkKeyCode = function (codes, event) {
  302. return checkKeyEvent(codes, event, function (code, event) {
  303. return code === event.keyCode && global$2.modifierPressed(event) === false;
  304. });
  305. };
  306. var checkCharCode = function (chars, event) {
  307. return checkKeyEvent(chars, event, function (chr, event) {
  308. return chr.charCodeAt(0) === event.charCode;
  309. });
  310. };
  311. var $_g4f2z3rxjkmcws6k = {
  312. handleEnter: handleEnter,
  313. handleInlineKey: handleInlineKey,
  314. checkCharCode: checkCharCode,
  315. checkKeyCode: checkKeyCode
  316. };
  317. var setup = function (editor, patternsState) {
  318. var charCodes = [
  319. ',',
  320. '.',
  321. ';',
  322. ':',
  323. '!',
  324. '?'
  325. ];
  326. var keyCodes = [32];
  327. editor.on('keydown', function (e) {
  328. if (e.keyCode === 13 && !global$2.modifierPressed(e)) {
  329. $_g4f2z3rxjkmcws6k.handleEnter(editor, patternsState.get());
  330. }
  331. }, true);
  332. editor.on('keyup', function (e) {
  333. if ($_g4f2z3rxjkmcws6k.checkKeyCode(keyCodes, e)) {
  334. $_g4f2z3rxjkmcws6k.handleInlineKey(editor, patternsState.get());
  335. }
  336. });
  337. editor.on('keypress', function (e) {
  338. if ($_g4f2z3rxjkmcws6k.checkCharCode(charCodes, e)) {
  339. global$1.setEditorTimeout(editor, function () {
  340. $_g4f2z3rxjkmcws6k.handleInlineKey(editor, patternsState.get());
  341. });
  342. }
  343. });
  344. };
  345. var $_6b0tfhrujkmcws6h = { setup: setup };
  346. global.add('textpattern', function (editor) {
  347. var patternsState = Cell($_1rurpvrtjkmcws6g.getPatterns(editor.settings));
  348. $_6b0tfhrujkmcws6h.setup(editor, patternsState);
  349. return $_fp2mq2rsjkmcws6f.get(patternsState);
  350. });
  351. function Plugin () {
  352. }
  353. return Plugin;
  354. }());
  355. })();