plugin.js 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  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 textpattern = (function (domGlobals) {
  11. 'use strict';
  12. var Cell = function (initial) {
  13. var value = initial;
  14. var get = function () {
  15. return value;
  16. };
  17. var set = function (v) {
  18. value = v;
  19. };
  20. var clone = function () {
  21. return Cell(get());
  22. };
  23. return {
  24. get: get,
  25. set: set,
  26. clone: clone
  27. };
  28. };
  29. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  30. var noop = function () {
  31. var args = [];
  32. for (var _i = 0; _i < arguments.length; _i++) {
  33. args[_i] = arguments[_i];
  34. }
  35. };
  36. var constant = function (value) {
  37. return function () {
  38. return value;
  39. };
  40. };
  41. var identity = function (x) {
  42. return x;
  43. };
  44. var die = function (msg) {
  45. return function () {
  46. throw new Error(msg);
  47. };
  48. };
  49. var never = constant(false);
  50. var always = constant(true);
  51. var never$1 = never;
  52. var always$1 = always;
  53. var none = function () {
  54. return NONE;
  55. };
  56. var NONE = function () {
  57. var eq = function (o) {
  58. return o.isNone();
  59. };
  60. var call = function (thunk) {
  61. return thunk();
  62. };
  63. var id = function (n) {
  64. return n;
  65. };
  66. var noop = function () {
  67. };
  68. var nul = function () {
  69. return null;
  70. };
  71. var undef = function () {
  72. return undefined;
  73. };
  74. var me = {
  75. fold: function (n, s) {
  76. return n();
  77. },
  78. is: never$1,
  79. isSome: never$1,
  80. isNone: always$1,
  81. getOr: id,
  82. getOrThunk: call,
  83. getOrDie: function (msg) {
  84. throw new Error(msg || 'error: getOrDie called on none.');
  85. },
  86. getOrNull: nul,
  87. getOrUndefined: undef,
  88. or: id,
  89. orThunk: call,
  90. map: none,
  91. ap: none,
  92. each: noop,
  93. bind: none,
  94. flatten: none,
  95. exists: never$1,
  96. forall: always$1,
  97. filter: none,
  98. equals: eq,
  99. equals_: eq,
  100. toArray: function () {
  101. return [];
  102. },
  103. toString: constant('none()')
  104. };
  105. if (Object.freeze)
  106. Object.freeze(me);
  107. return me;
  108. }();
  109. var some = function (a) {
  110. var constant_a = function () {
  111. return a;
  112. };
  113. var self = function () {
  114. return me;
  115. };
  116. var map = function (f) {
  117. return some(f(a));
  118. };
  119. var bind = function (f) {
  120. return f(a);
  121. };
  122. var me = {
  123. fold: function (n, s) {
  124. return s(a);
  125. },
  126. is: function (v) {
  127. return a === v;
  128. },
  129. isSome: always$1,
  130. isNone: never$1,
  131. getOr: constant_a,
  132. getOrThunk: constant_a,
  133. getOrDie: constant_a,
  134. getOrNull: constant_a,
  135. getOrUndefined: constant_a,
  136. or: self,
  137. orThunk: self,
  138. map: map,
  139. ap: function (optfab) {
  140. return optfab.fold(none, function (fab) {
  141. return some(fab(a));
  142. });
  143. },
  144. each: function (f) {
  145. f(a);
  146. },
  147. bind: bind,
  148. flatten: constant_a,
  149. exists: bind,
  150. forall: bind,
  151. filter: function (f) {
  152. return f(a) ? me : NONE;
  153. },
  154. equals: function (o) {
  155. return o.is(a);
  156. },
  157. equals_: function (o, elementEq) {
  158. return o.fold(never$1, function (b) {
  159. return elementEq(a, b);
  160. });
  161. },
  162. toArray: function () {
  163. return [a];
  164. },
  165. toString: function () {
  166. return 'some(' + a + ')';
  167. }
  168. };
  169. return me;
  170. };
  171. var from = function (value) {
  172. return value === null || value === undefined ? NONE : some(value);
  173. };
  174. var Option = {
  175. some: some,
  176. none: none,
  177. from: from
  178. };
  179. var typeOf = function (x) {
  180. if (x === null)
  181. return 'null';
  182. var t = typeof x;
  183. if (t === 'object' && Array.prototype.isPrototypeOf(x))
  184. return 'array';
  185. if (t === 'object' && String.prototype.isPrototypeOf(x))
  186. return 'string';
  187. return t;
  188. };
  189. var isType = function (type) {
  190. return function (value) {
  191. return typeOf(value) === type;
  192. };
  193. };
  194. var isString = isType('string');
  195. var isObject = isType('object');
  196. var isArray = isType('array');
  197. var isFunction = isType('function');
  198. var rawIndexOf = function () {
  199. var pIndexOf = Array.prototype.indexOf;
  200. var fastIndex = function (xs, x) {
  201. return pIndexOf.call(xs, x);
  202. };
  203. var slowIndex = function (xs, x) {
  204. return slowIndexOf(xs, x);
  205. };
  206. return pIndexOf === undefined ? slowIndex : fastIndex;
  207. }();
  208. var contains = function (xs, x) {
  209. return rawIndexOf(xs, x) > -1;
  210. };
  211. var map = function (xs, f) {
  212. var len = xs.length;
  213. var r = new Array(len);
  214. for (var i = 0; i < len; i++) {
  215. var x = xs[i];
  216. r[i] = f(x, i, xs);
  217. }
  218. return r;
  219. };
  220. var each = function (xs, f) {
  221. for (var i = 0, len = xs.length; i < len; i++) {
  222. var x = xs[i];
  223. f(x, i, xs);
  224. }
  225. };
  226. var filter = function (xs, pred) {
  227. var r = [];
  228. for (var i = 0, len = xs.length; i < len; i++) {
  229. var x = xs[i];
  230. if (pred(x, i, xs)) {
  231. r.push(x);
  232. }
  233. }
  234. return r;
  235. };
  236. var foldl = function (xs, f, acc) {
  237. each(xs, function (x) {
  238. acc = f(acc, x);
  239. });
  240. return acc;
  241. };
  242. var slowIndexOf = function (xs, x) {
  243. for (var i = 0, len = xs.length; i < len; ++i) {
  244. if (xs[i] === x) {
  245. return i;
  246. }
  247. }
  248. return -1;
  249. };
  250. var forall = function (xs, pred) {
  251. for (var i = 0, len = xs.length; i < len; ++i) {
  252. var x = xs[i];
  253. if (pred(x, i, xs) !== true) {
  254. return false;
  255. }
  256. }
  257. return true;
  258. };
  259. var slice = Array.prototype.slice;
  260. var sort = function (xs, comparator) {
  261. var copy = slice.call(xs, 0);
  262. copy.sort(comparator);
  263. return copy;
  264. };
  265. var from$1 = isFunction(Array.from) ? Array.from : function (x) {
  266. return slice.call(x);
  267. };
  268. var keys = Object.keys;
  269. var hasOwnProperty = Object.hasOwnProperty;
  270. var get = function (obj, key) {
  271. return has(obj, key) ? Option.some(obj[key]) : Option.none();
  272. };
  273. var has = function (obj, key) {
  274. return hasOwnProperty.call(obj, key);
  275. };
  276. var generate = function (cases) {
  277. if (!isArray(cases)) {
  278. throw new Error('cases must be an array');
  279. }
  280. if (cases.length === 0) {
  281. throw new Error('there must be at least one case');
  282. }
  283. var constructors = [];
  284. var adt = {};
  285. each(cases, function (acase, count) {
  286. var keys$1 = keys(acase);
  287. if (keys$1.length !== 1) {
  288. throw new Error('one and only one name per case');
  289. }
  290. var key = keys$1[0];
  291. var value = acase[key];
  292. if (adt[key] !== undefined) {
  293. throw new Error('duplicate key detected:' + key);
  294. } else if (key === 'cata') {
  295. throw new Error('cannot have a case named cata (sorry)');
  296. } else if (!isArray(value)) {
  297. throw new Error('case arguments must be an array');
  298. }
  299. constructors.push(key);
  300. adt[key] = function () {
  301. var argLength = arguments.length;
  302. if (argLength !== value.length) {
  303. throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
  304. }
  305. var args = new Array(argLength);
  306. for (var i = 0; i < args.length; i++)
  307. args[i] = arguments[i];
  308. var match = function (branches) {
  309. var branchKeys = keys(branches);
  310. if (constructors.length !== branchKeys.length) {
  311. throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
  312. }
  313. var allReqd = forall(constructors, function (reqKey) {
  314. return contains(branchKeys, reqKey);
  315. });
  316. if (!allReqd)
  317. throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
  318. return branches[key].apply(null, args);
  319. };
  320. return {
  321. fold: function () {
  322. if (arguments.length !== cases.length) {
  323. throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);
  324. }
  325. var target = arguments[count];
  326. return target.apply(null, args);
  327. },
  328. match: match,
  329. log: function (label) {
  330. console.log(label, {
  331. constructors: constructors,
  332. constructor: key,
  333. params: args
  334. });
  335. }
  336. };
  337. };
  338. });
  339. return adt;
  340. };
  341. var Adt = { generate: generate };
  342. var comparison = Adt.generate([
  343. {
  344. bothErrors: [
  345. 'error1',
  346. 'error2'
  347. ]
  348. },
  349. {
  350. firstError: [
  351. 'error1',
  352. 'value2'
  353. ]
  354. },
  355. {
  356. secondError: [
  357. 'value1',
  358. 'error2'
  359. ]
  360. },
  361. {
  362. bothValues: [
  363. 'value1',
  364. 'value2'
  365. ]
  366. }
  367. ]);
  368. var partition = function (results) {
  369. var errors = [];
  370. var values = [];
  371. each(results, function (result) {
  372. result.fold(function (err) {
  373. errors.push(err);
  374. }, function (value) {
  375. values.push(value);
  376. });
  377. });
  378. return {
  379. errors: errors,
  380. values: values
  381. };
  382. };
  383. var value = function (o) {
  384. var is = function (v) {
  385. return o === v;
  386. };
  387. var or = function (opt) {
  388. return value(o);
  389. };
  390. var orThunk = function (f) {
  391. return value(o);
  392. };
  393. var map = function (f) {
  394. return value(f(o));
  395. };
  396. var mapError = function (f) {
  397. return value(o);
  398. };
  399. var each = function (f) {
  400. f(o);
  401. };
  402. var bind = function (f) {
  403. return f(o);
  404. };
  405. var fold = function (_, onValue) {
  406. return onValue(o);
  407. };
  408. var exists = function (f) {
  409. return f(o);
  410. };
  411. var forall = function (f) {
  412. return f(o);
  413. };
  414. var toOption = function () {
  415. return Option.some(o);
  416. };
  417. return {
  418. is: is,
  419. isValue: always,
  420. isError: never,
  421. getOr: constant(o),
  422. getOrThunk: constant(o),
  423. getOrDie: constant(o),
  424. or: or,
  425. orThunk: orThunk,
  426. fold: fold,
  427. map: map,
  428. mapError: mapError,
  429. each: each,
  430. bind: bind,
  431. exists: exists,
  432. forall: forall,
  433. toOption: toOption
  434. };
  435. };
  436. var error = function (message) {
  437. var getOrThunk = function (f) {
  438. return f();
  439. };
  440. var getOrDie = function () {
  441. return die(String(message))();
  442. };
  443. var or = function (opt) {
  444. return opt;
  445. };
  446. var orThunk = function (f) {
  447. return f();
  448. };
  449. var map = function (f) {
  450. return error(message);
  451. };
  452. var mapError = function (f) {
  453. return error(f(message));
  454. };
  455. var bind = function (f) {
  456. return error(message);
  457. };
  458. var fold = function (onError, _) {
  459. return onError(message);
  460. };
  461. return {
  462. is: never,
  463. isValue: never,
  464. isError: always,
  465. getOr: identity,
  466. getOrThunk: getOrThunk,
  467. getOrDie: getOrDie,
  468. or: or,
  469. orThunk: orThunk,
  470. fold: fold,
  471. map: map,
  472. mapError: mapError,
  473. each: noop,
  474. bind: bind,
  475. exists: never,
  476. forall: always,
  477. toOption: Option.none
  478. };
  479. };
  480. var Result = {
  481. value: value,
  482. error: error
  483. };
  484. var isInlinePattern = function (pattern) {
  485. return pattern.type === 'inline-command' || pattern.type === 'inline-format';
  486. };
  487. var isBlockPattern = function (pattern) {
  488. return pattern.type === 'block-command' || pattern.type === 'block-format';
  489. };
  490. var sortPatterns = function (patterns) {
  491. return sort(patterns, function (a, b) {
  492. if (a.start.length === b.start.length) {
  493. return 0;
  494. }
  495. return a.start.length > b.start.length ? -1 : 1;
  496. });
  497. };
  498. var normalizePattern = function (pattern) {
  499. var err = function (message) {
  500. return Result.error({
  501. message: message,
  502. pattern: pattern
  503. });
  504. };
  505. var formatOrCmd = function (name, onFormat, onCommand) {
  506. if (pattern.format !== undefined) {
  507. var formats = void 0;
  508. if (isArray(pattern.format)) {
  509. if (!forall(pattern.format, isString)) {
  510. return err(name + ' pattern has non-string items in the `format` array');
  511. }
  512. formats = pattern.format;
  513. } else if (isString(pattern.format)) {
  514. formats = [pattern.format];
  515. } else {
  516. return err(name + ' pattern has non-string `format` parameter');
  517. }
  518. return Result.value(onFormat(formats));
  519. } else if (pattern.cmd !== undefined) {
  520. if (!isString(pattern.cmd)) {
  521. return err(name + ' pattern has non-string `cmd` parameter');
  522. }
  523. return Result.value(onCommand(pattern.cmd, pattern.value));
  524. } else {
  525. return err(name + ' pattern is missing both `format` and `cmd` parameters');
  526. }
  527. };
  528. if (!isObject(pattern)) {
  529. return err('Raw pattern is not an object');
  530. }
  531. if (!isString(pattern.start)) {
  532. return err('Raw pattern is missing `start` parameter');
  533. }
  534. if (pattern.end !== undefined) {
  535. if (!isString(pattern.end)) {
  536. return err('Inline pattern has non-string `end` parameter');
  537. }
  538. if (pattern.start.length === 0 && pattern.end.length === 0) {
  539. return err('Inline pattern has empty `start` and `end` parameters');
  540. }
  541. var start_1 = pattern.start;
  542. var end_1 = pattern.end;
  543. if (end_1.length === 0) {
  544. end_1 = start_1;
  545. start_1 = '';
  546. }
  547. return formatOrCmd('Inline', function (format) {
  548. return {
  549. type: 'inline-format',
  550. start: start_1,
  551. end: end_1,
  552. format: format
  553. };
  554. }, function (cmd, value) {
  555. return {
  556. type: 'inline-command',
  557. start: start_1,
  558. end: end_1,
  559. cmd: cmd,
  560. value: value
  561. };
  562. });
  563. } else if (pattern.replacement !== undefined) {
  564. if (!isString(pattern.replacement)) {
  565. return err('Replacement pattern has non-string `replacement` parameter');
  566. }
  567. if (pattern.start.length === 0) {
  568. return err('Replacement pattern has empty `start` parameter');
  569. }
  570. return Result.value({
  571. type: 'inline-command',
  572. start: '',
  573. end: pattern.start,
  574. cmd: 'mceInsertContent',
  575. value: pattern.replacement
  576. });
  577. } else {
  578. if (pattern.start.length === 0) {
  579. return err('Block pattern has empty `start` parameter');
  580. }
  581. return formatOrCmd('Block', function (formats) {
  582. return {
  583. type: 'block-format',
  584. start: pattern.start,
  585. format: formats[0]
  586. };
  587. }, function (command, commandValue) {
  588. return {
  589. type: 'block-command',
  590. start: pattern.start,
  591. cmd: command,
  592. value: commandValue
  593. };
  594. });
  595. }
  596. };
  597. var denormalizePattern = function (pattern) {
  598. if (pattern.type === 'block-command') {
  599. return {
  600. start: pattern.start,
  601. cmd: pattern.cmd,
  602. value: pattern.value
  603. };
  604. } else if (pattern.type === 'block-format') {
  605. return {
  606. start: pattern.start,
  607. format: pattern.format
  608. };
  609. } else if (pattern.type === 'inline-command') {
  610. if (pattern.cmd === 'mceInsertContent' && pattern.start === '') {
  611. return {
  612. start: pattern.end,
  613. replacement: pattern.value
  614. };
  615. } else {
  616. return {
  617. start: pattern.start,
  618. end: pattern.end,
  619. cmd: pattern.cmd,
  620. value: pattern.value
  621. };
  622. }
  623. } else if (pattern.type === 'inline-format') {
  624. return {
  625. start: pattern.start,
  626. end: pattern.end,
  627. format: pattern.format.length === 1 ? pattern.format[0] : pattern.format
  628. };
  629. }
  630. };
  631. var createPatternSet = function (patterns) {
  632. return {
  633. inlinePatterns: filter(patterns, isInlinePattern),
  634. blockPatterns: sortPatterns(filter(patterns, isBlockPattern))
  635. };
  636. };
  637. var get$1 = function (patternsState) {
  638. var setPatterns = function (newPatterns) {
  639. var normalized = partition(map(newPatterns, normalizePattern));
  640. if (normalized.errors.length > 0) {
  641. var firstError = normalized.errors[0];
  642. throw new Error(firstError.message + ':\n' + JSON.stringify(firstError.pattern, null, 2));
  643. }
  644. patternsState.set(createPatternSet(normalized.values));
  645. };
  646. var getPatterns = function () {
  647. return map(patternsState.get().inlinePatterns, denormalizePattern).concat(map(patternsState.get().blockPatterns, denormalizePattern));
  648. };
  649. return {
  650. setPatterns: setPatterns,
  651. getPatterns: getPatterns
  652. };
  653. };
  654. var Api = { get: get$1 };
  655. var Global = typeof window !== 'undefined' ? window : Function('return this;')();
  656. var error$1 = function () {
  657. var args = [];
  658. for (var _i = 0; _i < arguments.length; _i++) {
  659. args[_i] = arguments[_i];
  660. }
  661. var console = Global.console;
  662. if (console) {
  663. if (console.error) {
  664. console.error.apply(console, args);
  665. } else {
  666. console.log.apply(console, args);
  667. }
  668. }
  669. };
  670. var defaultPatterns = [
  671. {
  672. start: '*',
  673. end: '*',
  674. format: 'italic'
  675. },
  676. {
  677. start: '**',
  678. end: '**',
  679. format: 'bold'
  680. },
  681. {
  682. start: '#',
  683. format: 'h1'
  684. },
  685. {
  686. start: '##',
  687. format: 'h2'
  688. },
  689. {
  690. start: '###',
  691. format: 'h3'
  692. },
  693. {
  694. start: '####',
  695. format: 'h4'
  696. },
  697. {
  698. start: '#####',
  699. format: 'h5'
  700. },
  701. {
  702. start: '######',
  703. format: 'h6'
  704. },
  705. {
  706. start: '1. ',
  707. cmd: 'InsertOrderedList'
  708. },
  709. {
  710. start: '* ',
  711. cmd: 'InsertUnorderedList'
  712. },
  713. {
  714. start: '- ',
  715. cmd: 'InsertUnorderedList'
  716. }
  717. ];
  718. var getPatternSet = function (editorSettings) {
  719. var patterns = get(editorSettings, 'textpattern_patterns').getOr(defaultPatterns);
  720. if (!isArray(patterns)) {
  721. error$1('The setting textpattern_patterns should be an array');
  722. return {
  723. inlinePatterns: [],
  724. blockPatterns: []
  725. };
  726. }
  727. var normalized = partition(map(patterns, normalizePattern));
  728. each(normalized.errors, function (err) {
  729. return error$1(err.message, err.pattern);
  730. });
  731. return createPatternSet(normalized.values);
  732. };
  733. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  734. var global$2 = tinymce.util.Tools.resolve('tinymce.util.VK');
  735. var checkRange = function (str, substr, start) {
  736. if (substr === '')
  737. return true;
  738. if (str.length < substr.length)
  739. return false;
  740. var x = str.substr(start, start + substr.length);
  741. return x === substr;
  742. };
  743. var startsWith = function (str, prefix) {
  744. return checkRange(str, prefix, 0);
  745. };
  746. var endsWith = function (str, suffix) {
  747. return checkRange(str, suffix, str.length - suffix.length);
  748. };
  749. var global$3 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
  750. var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
  751. var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE;
  752. var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE;
  753. var COMMENT = domGlobals.Node.COMMENT_NODE;
  754. var DOCUMENT = domGlobals.Node.DOCUMENT_NODE;
  755. var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE;
  756. var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE;
  757. var ELEMENT = domGlobals.Node.ELEMENT_NODE;
  758. var TEXT = domGlobals.Node.TEXT_NODE;
  759. var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE;
  760. var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE;
  761. var ENTITY = domGlobals.Node.ENTITY_NODE;
  762. var NOTATION = domGlobals.Node.NOTATION_NODE;
  763. var isElement = function (node) {
  764. return node.nodeType === ELEMENT;
  765. };
  766. var isText = function (node) {
  767. return node.nodeType === TEXT;
  768. };
  769. var generatePath = function (root, node, offset) {
  770. if (offset < 0 || offset > node.data.length) {
  771. return Option.none();
  772. }
  773. var p = [offset];
  774. var current = node;
  775. while (current !== root && current.parentNode) {
  776. var parent = current.parentNode;
  777. for (var i = 0; i < parent.childNodes.length; i++) {
  778. if (parent.childNodes[i] === current) {
  779. p.push(i);
  780. break;
  781. }
  782. }
  783. current = parent;
  784. }
  785. return current === root ? Option.some(p.reverse()) : Option.none();
  786. };
  787. var generatePathRange = function (root, startNode, startOffset, endNode, endOffset) {
  788. return generatePath(root, startNode, startOffset).bind(function (start) {
  789. return generatePath(root, endNode, endOffset).map(function (end) {
  790. return {
  791. start: start,
  792. end: end
  793. };
  794. });
  795. });
  796. };
  797. var resolvePath = function (root, path) {
  798. var nodePath = path.slice();
  799. var offset = nodePath.pop();
  800. return foldl(nodePath, function (optNode, index) {
  801. return optNode.bind(function (node) {
  802. return Option.from(node.childNodes[index]);
  803. });
  804. }, Option.some(root)).bind(function (node) {
  805. if (isText(node) && offset >= 0 && offset <= node.data.length) {
  806. return Option.some({
  807. node: node,
  808. offset: offset
  809. });
  810. }
  811. return Option.none();
  812. });
  813. };
  814. var resolvePathRange = function (root, range) {
  815. return resolvePath(root, range.start).bind(function (_a) {
  816. var startNode = _a.node, startOffset = _a.offset;
  817. return resolvePath(root, range.end).map(function (_a) {
  818. var endNode = _a.node, endOffset = _a.offset;
  819. return {
  820. startNode: startNode,
  821. startOffset: startOffset,
  822. endNode: endNode,
  823. endOffset: endOffset
  824. };
  825. });
  826. });
  827. };
  828. var findPattern = function (patterns, text) {
  829. for (var i = 0; i < patterns.length; i++) {
  830. var pattern = patterns[i];
  831. if (text.indexOf(pattern.start) !== 0) {
  832. continue;
  833. }
  834. if (pattern.end && text.lastIndexOf(pattern.end) !== text.length - pattern.end.length) {
  835. continue;
  836. }
  837. return pattern;
  838. }
  839. };
  840. var textBefore = function (node, offset, block) {
  841. if (isText(node) && offset > 0) {
  842. return Option.some({
  843. node: node,
  844. offset: offset
  845. });
  846. }
  847. var startNode;
  848. if (offset > 0) {
  849. startNode = node.childNodes[offset - 1];
  850. } else {
  851. for (var current = node; current && current !== block && !startNode; current = current.parentNode) {
  852. startNode = current.previousSibling;
  853. }
  854. }
  855. var tw = new global$3(startNode, block);
  856. for (var current = tw.current(); current; current = tw.prev()) {
  857. if (isText(current) && current.length > 0) {
  858. return Option.some({
  859. node: current,
  860. offset: current.length
  861. });
  862. }
  863. }
  864. return Option.none();
  865. };
  866. var findInlinePatternStart = function (dom, pattern, node, offset, block, requireGap) {
  867. if (requireGap === void 0) {
  868. requireGap = false;
  869. }
  870. if (pattern.start.length === 0 && !requireGap) {
  871. return Option.some({
  872. node: node,
  873. offset: offset
  874. });
  875. }
  876. var sameBlockParent = function (spot) {
  877. return dom.getParent(spot.node, dom.isBlock) === block;
  878. };
  879. return textBefore(node, offset, block).filter(sameBlockParent).bind(function (_a) {
  880. var node = _a.node, offset = _a.offset;
  881. var text = node.data.substring(0, offset);
  882. var startPos = text.lastIndexOf(pattern.start);
  883. if (startPos === -1) {
  884. if (text.indexOf(pattern.end) !== -1) {
  885. return Option.none();
  886. }
  887. return findInlinePatternStart(dom, pattern, node, 0, block, requireGap && text.length === 0);
  888. }
  889. if (text.indexOf(pattern.end, startPos + pattern.start.length) !== -1) {
  890. return Option.none();
  891. }
  892. if (requireGap && startPos + pattern.start.length === text.length) {
  893. return Option.none();
  894. }
  895. return Option.some({
  896. node: node,
  897. offset: startPos
  898. });
  899. });
  900. };
  901. var findInlinePatternRec = function (dom, patterns, node, offset, block) {
  902. return textBefore(node, offset, block).bind(function (_a) {
  903. var endNode = _a.node, endOffset = _a.offset;
  904. var text = endNode.data.substring(0, endOffset);
  905. var _loop_1 = function (i) {
  906. var pattern = patterns[i];
  907. if (!endsWith(text, pattern.end)) {
  908. return 'continue';
  909. }
  910. var newOffset = endOffset - pattern.end.length;
  911. var hasContent = pattern.start.length > 0 && pattern.end.length > 0;
  912. var allowInner = hasContent ? Option.some(true) : Option.none();
  913. var recursiveMatch = allowInner.bind(function () {
  914. var patternsWithoutCurrent = patterns.slice();
  915. patternsWithoutCurrent.splice(i, 1);
  916. return findInlinePatternRec(dom, patternsWithoutCurrent, endNode, newOffset, block);
  917. }).fold(function () {
  918. var start = findInlinePatternStart(dom, pattern, endNode, newOffset, block, hasContent);
  919. return start.map(function (_a) {
  920. var startNode = _a.node, startOffset = _a.offset;
  921. var range = generatePathRange(dom.getRoot(), startNode, startOffset, endNode, endOffset).getOrDie('Internal constraint violation');
  922. return [{
  923. pattern: pattern,
  924. range: range
  925. }];
  926. });
  927. }, function (areas) {
  928. var outermostRange = resolvePathRange(dom.getRoot(), areas[areas.length - 1].range).getOrDie('Internal constraint violation');
  929. var start = findInlinePatternStart(dom, pattern, outermostRange.startNode, outermostRange.startOffset, block);
  930. return start.map(function (_a) {
  931. var startNode = _a.node, startOffset = _a.offset;
  932. var range = generatePathRange(dom.getRoot(), startNode, startOffset, endNode, endOffset).getOrDie('Internal constraint violation');
  933. return areas.concat([{
  934. pattern: pattern,
  935. range: range
  936. }]);
  937. });
  938. });
  939. if (recursiveMatch.isSome()) {
  940. return { value: recursiveMatch };
  941. }
  942. };
  943. for (var i = 0; i < patterns.length; i++) {
  944. var state_1 = _loop_1(i);
  945. if (typeof state_1 === 'object')
  946. return state_1.value;
  947. }
  948. return Option.none();
  949. });
  950. };
  951. var findNestedInlinePatterns = function (dom, patterns, rng, space) {
  952. if (rng.collapsed === false) {
  953. return [];
  954. }
  955. var block = dom.getParent(rng.startContainer, dom.isBlock);
  956. return findInlinePatternRec(dom, patterns, rng.startContainer, rng.startOffset - (space ? 1 : 0), block).getOr([]);
  957. };
  958. var findBlockPattern = function (dom, patterns, rng) {
  959. var block = dom.getParent(rng.startContainer, dom.isBlock);
  960. if (!(dom.is(block, 'p') && isElement(block))) {
  961. return Option.none();
  962. }
  963. var walker = new global$3(block, block);
  964. var node;
  965. var firstTextNode;
  966. while (node = walker.next()) {
  967. if (isText(node)) {
  968. firstTextNode = node;
  969. break;
  970. }
  971. }
  972. if (!firstTextNode) {
  973. return Option.none();
  974. }
  975. var pattern = findPattern(patterns, firstTextNode.data);
  976. if (!pattern) {
  977. return Option.none();
  978. }
  979. if (global$4.trim(block.textContent).length === pattern.start.length) {
  980. return Option.none();
  981. }
  982. return Option.some(pattern);
  983. };
  984. var unique = 0;
  985. var generate$1 = function (prefix) {
  986. var date = new Date();
  987. var time = date.getTime();
  988. var random = Math.floor(Math.random() * 1000000000);
  989. unique++;
  990. return prefix + '_' + random + unique + String(time);
  991. };
  992. var liftN = function (arr, f) {
  993. var r = [];
  994. for (var i = 0; i < arr.length; i++) {
  995. var x = arr[i];
  996. if (x.isSome()) {
  997. r.push(x.getOrDie());
  998. } else {
  999. return Option.none();
  1000. }
  1001. }
  1002. return Option.some(f.apply(null, r));
  1003. };
  1004. function lift() {
  1005. var args = [];
  1006. for (var _i = 0; _i < arguments.length; _i++) {
  1007. args[_i] = arguments[_i];
  1008. }
  1009. var f = args.pop();
  1010. return liftN(args, f);
  1011. }
  1012. var isCollapsed = function (start, end, root) {
  1013. var walker = new global$3(start, root);
  1014. while (walker.next()) {
  1015. var node = walker.current();
  1016. if (isText(node) && node.data.length === 0) {
  1017. continue;
  1018. }
  1019. return node === end;
  1020. }
  1021. return false;
  1022. };
  1023. var applyInlinePatterns = function (editor, areas) {
  1024. var dom = editor.dom;
  1025. var newMarker = function (id) {
  1026. return dom.create('span', {
  1027. 'data-mce-type': 'bookmark',
  1028. 'id': id
  1029. });
  1030. };
  1031. var markerRange = function (ids) {
  1032. var start = Option.from(dom.select('#' + ids.start)[0]);
  1033. var end = Option.from(dom.select('#' + ids.end)[0]);
  1034. return lift(start, end, function (start, end) {
  1035. var range = dom.createRng();
  1036. range.setStartAfter(start);
  1037. if (!isCollapsed(start, end, dom.getRoot())) {
  1038. range.setEndBefore(end);
  1039. } else {
  1040. range.collapse(true);
  1041. }
  1042. return range;
  1043. });
  1044. };
  1045. var markerPrefix = generate$1('mce_');
  1046. var markerIds = map(areas, function (_area, i) {
  1047. return {
  1048. start: markerPrefix + '_' + i + '_start',
  1049. end: markerPrefix + '_' + i + '_end'
  1050. };
  1051. });
  1052. var cursor = editor.selection.getBookmark();
  1053. for (var i = areas.length - 1; i >= 0; i--) {
  1054. var _a = areas[i], pattern = _a.pattern, range = _a.range;
  1055. var _b = resolvePath(dom.getRoot(), range.end).getOrDie('Failed to resolve range[' + i + '].end'), endNode = _b.node, endOffset = _b.offset;
  1056. var textOutsideRange = endOffset === 0 ? endNode : endNode.splitText(endOffset);
  1057. textOutsideRange.parentNode.insertBefore(newMarker(markerIds[i].end), textOutsideRange);
  1058. if (pattern.start.length > 0) {
  1059. endNode.deleteData(endOffset - pattern.end.length, pattern.end.length);
  1060. }
  1061. }
  1062. for (var i = 0; i < areas.length; i++) {
  1063. var _c = areas[i], pattern = _c.pattern, range = _c.range;
  1064. var _d = resolvePath(dom.getRoot(), range.start).getOrDie('Failed to resolve range.start'), startNode = _d.node, startOffset = _d.offset;
  1065. var textInsideRange = startOffset === 0 ? startNode : startNode.splitText(startOffset);
  1066. textInsideRange.parentNode.insertBefore(newMarker(markerIds[i].start), textInsideRange);
  1067. if (pattern.start.length > 0) {
  1068. textInsideRange.deleteData(0, pattern.start.length);
  1069. } else {
  1070. textInsideRange.deleteData(0, pattern.end.length);
  1071. }
  1072. }
  1073. var _loop_1 = function (i) {
  1074. var pattern = areas[i].pattern;
  1075. var optRange = markerRange(markerIds[i]);
  1076. optRange.each(function (range) {
  1077. editor.selection.setRng(range);
  1078. if (pattern.type === 'inline-format') {
  1079. pattern.format.forEach(function (format) {
  1080. editor.formatter.apply(format);
  1081. });
  1082. } else {
  1083. editor.execCommand(pattern.cmd, false, pattern.value);
  1084. }
  1085. });
  1086. dom.remove(markerIds[i].start);
  1087. dom.remove(markerIds[i].end);
  1088. };
  1089. for (var i = 0; i < areas.length; i++) {
  1090. _loop_1(i);
  1091. }
  1092. editor.selection.moveToBookmark(cursor);
  1093. };
  1094. var applyBlockPattern = function (editor, pattern) {
  1095. var dom = editor.dom;
  1096. var rng = editor.selection.getRng();
  1097. var block = dom.getParent(rng.startContainer, dom.isBlock);
  1098. if (!block || !dom.is(block, 'p') || !isElement(block)) {
  1099. return;
  1100. }
  1101. var walker = new global$3(block, block);
  1102. var node;
  1103. var firstTextNode;
  1104. while (node = walker.next()) {
  1105. if (isText(node)) {
  1106. firstTextNode = node;
  1107. break;
  1108. }
  1109. }
  1110. if (!firstTextNode) {
  1111. return;
  1112. }
  1113. if (!startsWith(firstTextNode.data, pattern.start)) {
  1114. return;
  1115. }
  1116. if (global$4.trim(block.textContent).length === pattern.start.length) {
  1117. return;
  1118. }
  1119. var cursor = editor.selection.getBookmark();
  1120. if (pattern.type === 'block-format') {
  1121. var format = editor.formatter.get(pattern.format);
  1122. if (format && format[0].block) {
  1123. editor.undoManager.transact(function () {
  1124. firstTextNode.deleteData(0, pattern.start.length);
  1125. editor.selection.select(block);
  1126. editor.formatter.apply(pattern.format);
  1127. });
  1128. }
  1129. } else if (pattern.type === 'block-command') {
  1130. editor.undoManager.transact(function () {
  1131. firstTextNode.deleteData(0, pattern.start.length);
  1132. editor.selection.select(block);
  1133. editor.execCommand(pattern.cmd, false, pattern.value);
  1134. });
  1135. }
  1136. editor.selection.moveToBookmark(cursor);
  1137. };
  1138. var zeroWidth = function () {
  1139. return '\uFEFF';
  1140. };
  1141. var handleEnter = function (editor, patternSet) {
  1142. var inlineAreas = findNestedInlinePatterns(editor.dom, patternSet.inlinePatterns, editor.selection.getRng(), false);
  1143. var blockArea = findBlockPattern(editor.dom, patternSet.blockPatterns, editor.selection.getRng());
  1144. if (editor.selection.isCollapsed() && (inlineAreas.length > 0 || blockArea.isSome())) {
  1145. editor.undoManager.add();
  1146. editor.undoManager.extra(function () {
  1147. editor.execCommand('mceInsertNewLine');
  1148. }, function () {
  1149. editor.insertContent(zeroWidth());
  1150. applyInlinePatterns(editor, inlineAreas);
  1151. blockArea.each(function (pattern) {
  1152. return applyBlockPattern(editor, pattern);
  1153. });
  1154. var range = editor.selection.getRng();
  1155. var block = editor.dom.getParent(range.startContainer, editor.dom.isBlock);
  1156. var spot = textBefore(range.startContainer, range.startOffset, block);
  1157. editor.execCommand('mceInsertNewLine');
  1158. spot.each(function (s) {
  1159. if (s.node.data.charAt(s.offset - 1) === zeroWidth()) {
  1160. s.node.deleteData(s.offset - 1, 1);
  1161. if (editor.dom.isEmpty(s.node.parentNode)) {
  1162. editor.dom.remove(s.node.parentNode);
  1163. }
  1164. }
  1165. });
  1166. });
  1167. return true;
  1168. }
  1169. return false;
  1170. };
  1171. var handleInlineKey = function (editor, patternSet) {
  1172. var areas = findNestedInlinePatterns(editor.dom, patternSet.inlinePatterns, editor.selection.getRng(), true);
  1173. if (areas.length > 0) {
  1174. editor.undoManager.transact(function () {
  1175. applyInlinePatterns(editor, areas);
  1176. });
  1177. }
  1178. };
  1179. var checkKeyEvent = function (codes, event, predicate) {
  1180. for (var i = 0; i < codes.length; i++) {
  1181. if (predicate(codes[i], event)) {
  1182. return true;
  1183. }
  1184. }
  1185. };
  1186. var checkKeyCode = function (codes, event) {
  1187. return checkKeyEvent(codes, event, function (code, event) {
  1188. return code === event.keyCode && global$2.modifierPressed(event) === false;
  1189. });
  1190. };
  1191. var checkCharCode = function (chars, event) {
  1192. return checkKeyEvent(chars, event, function (chr, event) {
  1193. return chr.charCodeAt(0) === event.charCode;
  1194. });
  1195. };
  1196. var KeyHandler = {
  1197. handleEnter: handleEnter,
  1198. handleInlineKey: handleInlineKey,
  1199. checkCharCode: checkCharCode,
  1200. checkKeyCode: checkKeyCode
  1201. };
  1202. var setup = function (editor, patternsState) {
  1203. var charCodes = [
  1204. ',',
  1205. '.',
  1206. ';',
  1207. ':',
  1208. '!',
  1209. '?'
  1210. ];
  1211. var keyCodes = [32];
  1212. editor.on('keydown', function (e) {
  1213. if (e.keyCode === 13 && !global$2.modifierPressed(e)) {
  1214. if (KeyHandler.handleEnter(editor, patternsState.get())) {
  1215. e.preventDefault();
  1216. }
  1217. }
  1218. }, true);
  1219. editor.on('keyup', function (e) {
  1220. if (KeyHandler.checkKeyCode(keyCodes, e)) {
  1221. KeyHandler.handleInlineKey(editor, patternsState.get());
  1222. }
  1223. });
  1224. editor.on('keypress', function (e) {
  1225. if (KeyHandler.checkCharCode(charCodes, e)) {
  1226. global$1.setEditorTimeout(editor, function () {
  1227. KeyHandler.handleInlineKey(editor, patternsState.get());
  1228. });
  1229. }
  1230. });
  1231. };
  1232. var Keyboard = { setup: setup };
  1233. global.add('textpattern', function (editor) {
  1234. var patternsState = Cell(getPatternSet(editor.settings));
  1235. Keyboard.setup(editor, patternsState);
  1236. return Api.get(patternsState);
  1237. });
  1238. function Plugin () {
  1239. }
  1240. return Plugin;
  1241. }(window));
  1242. })();