plugin.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. (function () {
  2. var visualchars = (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 (toggleState) {
  23. var isEnabled = function () {
  24. return toggleState.get();
  25. };
  26. return { isEnabled: isEnabled };
  27. };
  28. var $_9mm6m1stjkmcwsag = { get: get };
  29. var fireVisualChars = function (editor, state) {
  30. return editor.fire('VisualChars', { state: state });
  31. };
  32. var $_1amvi1swjkmcwsak = { fireVisualChars: fireVisualChars };
  33. var charMap = {
  34. '\xA0': 'nbsp',
  35. '\xAD': 'shy'
  36. };
  37. var charMapToRegExp = function (charMap, global) {
  38. var key, regExp = '';
  39. for (key in charMap) {
  40. regExp += key;
  41. }
  42. return new RegExp('[' + regExp + ']', global ? 'g' : '');
  43. };
  44. var charMapToSelector = function (charMap) {
  45. var key, selector = '';
  46. for (key in charMap) {
  47. if (selector) {
  48. selector += ',';
  49. }
  50. selector += 'span.mce-' + charMap[key];
  51. }
  52. return selector;
  53. };
  54. var $_dey8tosyjkmcwsas = {
  55. charMap: charMap,
  56. regExp: charMapToRegExp(charMap),
  57. regExpGlobal: charMapToRegExp(charMap, true),
  58. selector: charMapToSelector(charMap),
  59. charMapToRegExp: charMapToRegExp,
  60. charMapToSelector: charMapToSelector
  61. };
  62. var constant = function (value) {
  63. return function () {
  64. return value;
  65. };
  66. };
  67. var never = constant(false);
  68. var always = constant(true);
  69. var never$1 = never;
  70. var always$1 = always;
  71. var none = function () {
  72. return NONE;
  73. };
  74. var NONE = function () {
  75. var eq = function (o) {
  76. return o.isNone();
  77. };
  78. var call$$1 = function (thunk) {
  79. return thunk();
  80. };
  81. var id = function (n) {
  82. return n;
  83. };
  84. var noop$$1 = function () {
  85. };
  86. var nul = function () {
  87. return null;
  88. };
  89. var undef = function () {
  90. return undefined;
  91. };
  92. var me = {
  93. fold: function (n, s) {
  94. return n();
  95. },
  96. is: never$1,
  97. isSome: never$1,
  98. isNone: always$1,
  99. getOr: id,
  100. getOrThunk: call$$1,
  101. getOrDie: function (msg) {
  102. throw new Error(msg || 'error: getOrDie called on none.');
  103. },
  104. getOrNull: nul,
  105. getOrUndefined: undef,
  106. or: id,
  107. orThunk: call$$1,
  108. map: none,
  109. ap: none,
  110. each: noop$$1,
  111. bind: none,
  112. flatten: none,
  113. exists: never$1,
  114. forall: always$1,
  115. filter: none,
  116. equals: eq,
  117. equals_: eq,
  118. toArray: function () {
  119. return [];
  120. },
  121. toString: constant('none()')
  122. };
  123. if (Object.freeze)
  124. Object.freeze(me);
  125. return me;
  126. }();
  127. var some = function (a) {
  128. var constant_a = function () {
  129. return a;
  130. };
  131. var self = function () {
  132. return me;
  133. };
  134. var map = function (f) {
  135. return some(f(a));
  136. };
  137. var bind = function (f) {
  138. return f(a);
  139. };
  140. var me = {
  141. fold: function (n, s) {
  142. return s(a);
  143. },
  144. is: function (v) {
  145. return a === v;
  146. },
  147. isSome: always$1,
  148. isNone: never$1,
  149. getOr: constant_a,
  150. getOrThunk: constant_a,
  151. getOrDie: constant_a,
  152. getOrNull: constant_a,
  153. getOrUndefined: constant_a,
  154. or: self,
  155. orThunk: self,
  156. map: map,
  157. ap: function (optfab) {
  158. return optfab.fold(none, function (fab) {
  159. return some(fab(a));
  160. });
  161. },
  162. each: function (f) {
  163. f(a);
  164. },
  165. bind: bind,
  166. flatten: constant_a,
  167. exists: bind,
  168. forall: bind,
  169. filter: function (f) {
  170. return f(a) ? me : NONE;
  171. },
  172. equals: function (o) {
  173. return o.is(a);
  174. },
  175. equals_: function (o, elementEq) {
  176. return o.fold(never$1, function (b) {
  177. return elementEq(a, b);
  178. });
  179. },
  180. toArray: function () {
  181. return [a];
  182. },
  183. toString: function () {
  184. return 'some(' + a + ')';
  185. }
  186. };
  187. return me;
  188. };
  189. var from = function (value) {
  190. return value === null || value === undefined ? NONE : some(value);
  191. };
  192. var Option = {
  193. some: some,
  194. none: none,
  195. from: from
  196. };
  197. var typeOf = function (x) {
  198. if (x === null)
  199. return 'null';
  200. var t = typeof x;
  201. if (t === 'object' && Array.prototype.isPrototypeOf(x))
  202. return 'array';
  203. if (t === 'object' && String.prototype.isPrototypeOf(x))
  204. return 'string';
  205. return t;
  206. };
  207. var isType = function (type) {
  208. return function (value) {
  209. return typeOf(value) === type;
  210. };
  211. };
  212. var isFunction = isType('function');
  213. var map = function (xs, f) {
  214. var len = xs.length;
  215. var r = new Array(len);
  216. for (var i = 0; i < len; i++) {
  217. var x = xs[i];
  218. r[i] = f(x, i, xs);
  219. }
  220. return r;
  221. };
  222. var each = function (xs, f) {
  223. for (var i = 0, len = xs.length; i < len; i++) {
  224. var x = xs[i];
  225. f(x, i, xs);
  226. }
  227. };
  228. var slice = Array.prototype.slice;
  229. var from$1 = isFunction(Array.from) ? Array.from : function (x) {
  230. return slice.call(x);
  231. };
  232. var fromHtml = function (html, scope) {
  233. var doc = scope || document;
  234. var div = doc.createElement('div');
  235. div.innerHTML = html;
  236. if (!div.hasChildNodes() || div.childNodes.length > 1) {
  237. console.error('HTML does not have a single root node', html);
  238. throw 'HTML must have a single root node';
  239. }
  240. return fromDom(div.childNodes[0]);
  241. };
  242. var fromTag = function (tag, scope) {
  243. var doc = scope || document;
  244. var node = doc.createElement(tag);
  245. return fromDom(node);
  246. };
  247. var fromText = function (text, scope) {
  248. var doc = scope || document;
  249. var node = doc.createTextNode(text);
  250. return fromDom(node);
  251. };
  252. var fromDom = function (node) {
  253. if (node === null || node === undefined)
  254. throw new Error('Node cannot be null or undefined');
  255. return { dom: constant(node) };
  256. };
  257. var fromPoint = function (docElm, x, y) {
  258. var doc = docElm.dom();
  259. return Option.from(doc.elementFromPoint(x, y)).map(fromDom);
  260. };
  261. var Element$$1 = {
  262. fromHtml: fromHtml,
  263. fromTag: fromTag,
  264. fromText: fromText,
  265. fromDom: fromDom,
  266. fromPoint: fromPoint
  267. };
  268. var $_488suct7jkmcwsbz = {
  269. ATTRIBUTE: Node.ATTRIBUTE_NODE,
  270. CDATA_SECTION: Node.CDATA_SECTION_NODE,
  271. COMMENT: Node.COMMENT_NODE,
  272. DOCUMENT: Node.DOCUMENT_NODE,
  273. DOCUMENT_TYPE: Node.DOCUMENT_TYPE_NODE,
  274. DOCUMENT_FRAGMENT: Node.DOCUMENT_FRAGMENT_NODE,
  275. ELEMENT: Node.ELEMENT_NODE,
  276. TEXT: Node.TEXT_NODE,
  277. PROCESSING_INSTRUCTION: Node.PROCESSING_INSTRUCTION_NODE,
  278. ENTITY_REFERENCE: Node.ENTITY_REFERENCE_NODE,
  279. ENTITY: Node.ENTITY_NODE,
  280. NOTATION: Node.NOTATION_NODE
  281. };
  282. var name = function (element) {
  283. var r = element.dom().nodeName;
  284. return r.toLowerCase();
  285. };
  286. var type = function (element) {
  287. return element.dom().nodeType;
  288. };
  289. var value = function (element) {
  290. return element.dom().nodeValue;
  291. };
  292. var isType$1 = function (t) {
  293. return function (element) {
  294. return type(element) === t;
  295. };
  296. };
  297. var isComment = function (element) {
  298. return type(element) === $_488suct7jkmcwsbz.COMMENT || name(element) === '#comment';
  299. };
  300. var isElement = isType$1($_488suct7jkmcwsbz.ELEMENT);
  301. var isText = isType$1($_488suct7jkmcwsbz.TEXT);
  302. var isDocument = isType$1($_488suct7jkmcwsbz.DOCUMENT);
  303. var $_fswyn1t6jkmcwsby = {
  304. name: name,
  305. type: type,
  306. value: value,
  307. isElement: isElement,
  308. isText: isText,
  309. isDocument: isDocument,
  310. isComment: isComment
  311. };
  312. var wrapCharWithSpan = function (value) {
  313. return '<span data-mce-bogus="1" class="mce-' + $_dey8tosyjkmcwsas.charMap[value] + '">' + value + '</span>';
  314. };
  315. var $_2nl12ut8jkmcwsc8 = { wrapCharWithSpan: wrapCharWithSpan };
  316. var isMatch = function (n) {
  317. return $_fswyn1t6jkmcwsby.isText(n) && $_fswyn1t6jkmcwsby.value(n) !== undefined && $_dey8tosyjkmcwsas.regExp.test($_fswyn1t6jkmcwsby.value(n));
  318. };
  319. var filterDescendants = function (scope, predicate) {
  320. var result = [];
  321. var dom = scope.dom();
  322. var children = map(dom.childNodes, Element$$1.fromDom);
  323. each(children, function (x) {
  324. if (predicate(x)) {
  325. result = result.concat([x]);
  326. }
  327. result = result.concat(filterDescendants(x, predicate));
  328. });
  329. return result;
  330. };
  331. var findParentElm = function (elm, rootElm) {
  332. while (elm.parentNode) {
  333. if (elm.parentNode === rootElm) {
  334. return elm;
  335. }
  336. elm = elm.parentNode;
  337. }
  338. };
  339. var replaceWithSpans = function (html) {
  340. return html.replace($_dey8tosyjkmcwsas.regExpGlobal, $_2nl12ut8jkmcwsc8.wrapCharWithSpan);
  341. };
  342. var $_cwpoydszjkmcwsau = {
  343. isMatch: isMatch,
  344. filterDescendants: filterDescendants,
  345. findParentElm: findParentElm,
  346. replaceWithSpans: replaceWithSpans
  347. };
  348. var show = function (editor, rootElm) {
  349. var node, div;
  350. var nodeList = $_cwpoydszjkmcwsau.filterDescendants(Element$$1.fromDom(rootElm), $_cwpoydszjkmcwsau.isMatch);
  351. each(nodeList, function (n) {
  352. var withSpans = $_cwpoydszjkmcwsau.replaceWithSpans($_fswyn1t6jkmcwsby.value(n));
  353. div = editor.dom.create('div', null, withSpans);
  354. while (node = div.lastChild) {
  355. editor.dom.insertAfter(node, n.dom());
  356. }
  357. editor.dom.remove(n.dom());
  358. });
  359. };
  360. var hide = function (editor, body) {
  361. var nodeList = editor.dom.select($_dey8tosyjkmcwsas.selector, body);
  362. each(nodeList, function (node) {
  363. editor.dom.remove(node, 1);
  364. });
  365. };
  366. var toggle = function (editor) {
  367. var body = editor.getBody();
  368. var bookmark = editor.selection.getBookmark();
  369. var parentNode = $_cwpoydszjkmcwsau.findParentElm(editor.selection.getNode(), body);
  370. parentNode = parentNode !== undefined ? parentNode : body;
  371. hide(editor, parentNode);
  372. show(editor, parentNode);
  373. editor.selection.moveToBookmark(bookmark);
  374. };
  375. var $_cqqknmsxjkmcwsal = {
  376. show: show,
  377. hide: hide,
  378. toggle: toggle
  379. };
  380. var toggleVisualChars = function (editor, toggleState) {
  381. var body = editor.getBody();
  382. var selection = editor.selection;
  383. var bookmark;
  384. toggleState.set(!toggleState.get());
  385. $_1amvi1swjkmcwsak.fireVisualChars(editor, toggleState.get());
  386. bookmark = selection.getBookmark();
  387. if (toggleState.get() === true) {
  388. $_cqqknmsxjkmcwsal.show(editor, body);
  389. } else {
  390. $_cqqknmsxjkmcwsal.hide(editor, body);
  391. }
  392. selection.moveToBookmark(bookmark);
  393. };
  394. var $_6jbw14svjkmcwsaj = { toggleVisualChars: toggleVisualChars };
  395. var register = function (editor, toggleState) {
  396. editor.addCommand('mceVisualChars', function () {
  397. $_6jbw14svjkmcwsaj.toggleVisualChars(editor, toggleState);
  398. });
  399. };
  400. var $_d384o2sujkmcwsai = { register: register };
  401. var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay');
  402. var setup = function (editor, toggleState) {
  403. var debouncedToggle = global$1.debounce(function () {
  404. $_cqqknmsxjkmcwsal.toggle(editor);
  405. }, 300);
  406. if (editor.settings.forced_root_block !== false) {
  407. editor.on('keydown', function (e) {
  408. if (toggleState.get() === true) {
  409. e.keyCode === 13 ? $_cqqknmsxjkmcwsal.toggle(editor) : debouncedToggle();
  410. }
  411. });
  412. }
  413. };
  414. var $_9nthojt9jkmcwsca = { setup: setup };
  415. var toggleActiveState = function (editor) {
  416. return function (e) {
  417. var ctrl = e.control;
  418. editor.on('VisualChars', function (e) {
  419. ctrl.active(e.state);
  420. });
  421. };
  422. };
  423. var register$1 = function (editor) {
  424. editor.addButton('visualchars', {
  425. active: false,
  426. title: 'Show invisible characters',
  427. cmd: 'mceVisualChars',
  428. onPostRender: toggleActiveState(editor)
  429. });
  430. editor.addMenuItem('visualchars', {
  431. text: 'Show invisible characters',
  432. cmd: 'mceVisualChars',
  433. onPostRender: toggleActiveState(editor),
  434. selectable: true,
  435. context: 'view',
  436. prependToContext: true
  437. });
  438. };
  439. global.add('visualchars', function (editor) {
  440. var toggleState = Cell(false);
  441. $_d384o2sujkmcwsai.register(editor, toggleState);
  442. register$1(editor);
  443. $_9nthojt9jkmcwsca.setup(editor, toggleState);
  444. return $_9mm6m1stjkmcwsag.get(toggleState);
  445. });
  446. function Plugin () {
  447. }
  448. return Plugin;
  449. }());
  450. })();