plugin.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * TinyMCE version 6.0.3 (2022-05-25)
  3. */
  4. (function () {
  5. 'use strict';
  6. var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
  7. const applyListFormat = (editor, listName, styleValue) => {
  8. const cmd = listName === 'UL' ? 'InsertUnorderedList' : 'InsertOrderedList';
  9. editor.execCommand(cmd, false, styleValue === false ? null : { 'list-style-type': styleValue });
  10. };
  11. const register$2 = editor => {
  12. editor.addCommand('ApplyUnorderedListStyle', (ui, value) => {
  13. applyListFormat(editor, 'UL', value['list-style-type']);
  14. });
  15. editor.addCommand('ApplyOrderedListStyle', (ui, value) => {
  16. applyListFormat(editor, 'OL', value['list-style-type']);
  17. });
  18. };
  19. const option = name => editor => editor.options.get(name);
  20. const register$1 = editor => {
  21. const registerOption = editor.options.register;
  22. registerOption('advlist_number_styles', {
  23. processor: 'string[]',
  24. default: 'default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman'.split(',')
  25. });
  26. registerOption('advlist_bullet_styles', {
  27. processor: 'string[]',
  28. default: 'default,circle,square'.split(',')
  29. });
  30. };
  31. const getNumberStyles = option('advlist_number_styles');
  32. const getBulletStyles = option('advlist_bullet_styles');
  33. var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
  34. const isNullable = a => a === null || a === undefined;
  35. const isNonNullable = a => !isNullable(a);
  36. class Optional {
  37. constructor(tag, value) {
  38. this.tag = tag;
  39. this.value = value;
  40. }
  41. static some(value) {
  42. return new Optional(true, value);
  43. }
  44. static none() {
  45. return Optional.singletonNone;
  46. }
  47. fold(onNone, onSome) {
  48. if (this.tag) {
  49. return onSome(this.value);
  50. } else {
  51. return onNone();
  52. }
  53. }
  54. isSome() {
  55. return this.tag;
  56. }
  57. isNone() {
  58. return !this.tag;
  59. }
  60. map(mapper) {
  61. if (this.tag) {
  62. return Optional.some(mapper(this.value));
  63. } else {
  64. return Optional.none();
  65. }
  66. }
  67. bind(binder) {
  68. if (this.tag) {
  69. return binder(this.value);
  70. } else {
  71. return Optional.none();
  72. }
  73. }
  74. exists(predicate) {
  75. return this.tag && predicate(this.value);
  76. }
  77. forall(predicate) {
  78. return !this.tag || predicate(this.value);
  79. }
  80. filter(predicate) {
  81. if (!this.tag || predicate(this.value)) {
  82. return this;
  83. } else {
  84. return Optional.none();
  85. }
  86. }
  87. getOr(replacement) {
  88. return this.tag ? this.value : replacement;
  89. }
  90. or(replacement) {
  91. return this.tag ? this : replacement;
  92. }
  93. getOrThunk(thunk) {
  94. return this.tag ? this.value : thunk();
  95. }
  96. orThunk(thunk) {
  97. return this.tag ? this : thunk();
  98. }
  99. getOrDie(message) {
  100. if (!this.tag) {
  101. throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
  102. } else {
  103. return this.value;
  104. }
  105. }
  106. static from(value) {
  107. return isNonNullable(value) ? Optional.some(value) : Optional.none();
  108. }
  109. getOrNull() {
  110. return this.tag ? this.value : null;
  111. }
  112. getOrUndefined() {
  113. return this.value;
  114. }
  115. each(worker) {
  116. if (this.tag) {
  117. worker(this.value);
  118. }
  119. }
  120. toArray() {
  121. return this.tag ? [this.value] : [];
  122. }
  123. toString() {
  124. return this.tag ? `some(${ this.value })` : 'none()';
  125. }
  126. }
  127. Optional.singletonNone = new Optional(false);
  128. const isChildOfBody = (editor, elm) => {
  129. return editor.dom.isChildOf(elm, editor.getBody());
  130. };
  131. const isTableCellNode = node => {
  132. return node && /^(TH|TD)$/.test(node.nodeName);
  133. };
  134. const isListNode = editor => node => {
  135. return node && /^(OL|UL|DL)$/.test(node.nodeName) && isChildOfBody(editor, node);
  136. };
  137. const getSelectedStyleType = editor => {
  138. const listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
  139. const style = editor.dom.getStyle(listElm, 'listStyleType');
  140. return Optional.from(style);
  141. };
  142. const findIndex = (list, predicate) => {
  143. for (let index = 0; index < list.length; index++) {
  144. const element = list[index];
  145. if (predicate(element)) {
  146. return index;
  147. }
  148. }
  149. return -1;
  150. };
  151. const styleValueToText = styleValue => {
  152. return styleValue.replace(/\-/g, ' ').replace(/\b\w/g, chr => {
  153. return chr.toUpperCase();
  154. });
  155. };
  156. const isWithinList = (editor, e, nodeName) => {
  157. const tableCellIndex = findIndex(e.parents, isTableCellNode);
  158. const parents = tableCellIndex !== -1 ? e.parents.slice(0, tableCellIndex) : e.parents;
  159. const lists = global.grep(parents, isListNode(editor));
  160. return lists.length > 0 && lists[0].nodeName === nodeName;
  161. };
  162. const makeSetupHandler = (editor, nodeName) => api => {
  163. const nodeChangeHandler = e => {
  164. api.setActive(isWithinList(editor, e, nodeName));
  165. };
  166. editor.on('NodeChange', nodeChangeHandler);
  167. return () => editor.off('NodeChange', nodeChangeHandler);
  168. };
  169. const addSplitButton = (editor, id, tooltip, cmd, nodeName, styles) => {
  170. editor.ui.registry.addSplitButton(id, {
  171. tooltip,
  172. icon: nodeName === 'OL' ? 'ordered-list' : 'unordered-list',
  173. presets: 'listpreview',
  174. columns: 3,
  175. fetch: callback => {
  176. const items = global.map(styles, styleValue => {
  177. const iconStyle = nodeName === 'OL' ? 'num' : 'bull';
  178. const iconName = styleValue === 'disc' || styleValue === 'decimal' ? 'default' : styleValue;
  179. const itemValue = styleValue === 'default' ? '' : styleValue;
  180. const displayText = styleValueToText(styleValue);
  181. return {
  182. type: 'choiceitem',
  183. value: itemValue,
  184. icon: 'list-' + iconStyle + '-' + iconName,
  185. text: displayText
  186. };
  187. });
  188. callback(items);
  189. },
  190. onAction: () => editor.execCommand(cmd),
  191. onItemAction: (_splitButtonApi, value) => {
  192. applyListFormat(editor, nodeName, value);
  193. },
  194. select: value => {
  195. const listStyleType = getSelectedStyleType(editor);
  196. return listStyleType.map(listStyle => value === listStyle).getOr(false);
  197. },
  198. onSetup: makeSetupHandler(editor, nodeName)
  199. });
  200. };
  201. const addButton = (editor, id, tooltip, cmd, nodeName, _styles) => {
  202. editor.ui.registry.addToggleButton(id, {
  203. active: false,
  204. tooltip,
  205. icon: nodeName === 'OL' ? 'ordered-list' : 'unordered-list',
  206. onSetup: makeSetupHandler(editor, nodeName),
  207. onAction: () => editor.execCommand(cmd)
  208. });
  209. };
  210. const addControl = (editor, id, tooltip, cmd, nodeName, styles) => {
  211. if (styles.length > 1) {
  212. addSplitButton(editor, id, tooltip, cmd, nodeName, styles);
  213. } else {
  214. addButton(editor, id, tooltip, cmd, nodeName);
  215. }
  216. };
  217. const register = editor => {
  218. addControl(editor, 'numlist', 'Numbered list', 'InsertOrderedList', 'OL', getNumberStyles(editor));
  219. addControl(editor, 'bullist', 'Bullet list', 'InsertUnorderedList', 'UL', getBulletStyles(editor));
  220. };
  221. var Plugin = () => {
  222. global$1.add('advlist', editor => {
  223. if (editor.hasPlugin('lists')) {
  224. register$1(editor);
  225. register(editor);
  226. register$2(editor);
  227. } else {
  228. console.error('Please use the Lists plugin together with the Advanced List plugin.');
  229. }
  230. });
  231. };
  232. Plugin();
  233. })();