@dangl/angular-material-shared 2.9.0-beta0037 → 2.9.0-beta0040

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/fesm2022/dangl-angular-material-shared-tiny-mce.mjs +29 -35
  2. package/fesm2022/dangl-angular-material-shared-tiny-mce.mjs.map +1 -1
  3. package/fesm2022/dangl-angular-material-shared.mjs +36 -51
  4. package/fesm2022/dangl-angular-material-shared.mjs.map +1 -1
  5. package/package.json +11 -10
  6. package/styles/material-theme.scss +1 -1
  7. package/styles/material-variables.scss +5 -5
  8. package/tinymce-assets/icons/default/icons.js +46 -9
  9. package/tinymce-assets/icons/default/icons.min.js +1 -1
  10. package/tinymce-assets/models/dom/model.js +8198 -7244
  11. package/tinymce-assets/models/dom/model.min.js +1 -4
  12. package/tinymce-assets/plugins/accordion/plugin.js +1174 -879
  13. package/tinymce-assets/plugins/accordion/plugin.min.js +1 -4
  14. package/tinymce-assets/plugins/advlist/plugin.js +412 -200
  15. package/tinymce-assets/plugins/advlist/plugin.min.js +1 -4
  16. package/tinymce-assets/plugins/anchor/plugin.js +189 -166
  17. package/tinymce-assets/plugins/anchor/plugin.min.js +1 -4
  18. package/tinymce-assets/plugins/autolink/plugin.js +310 -220
  19. package/tinymce-assets/plugins/autolink/plugin.min.js +1 -4
  20. package/tinymce-assets/plugins/autoresize/plugin.js +180 -149
  21. package/tinymce-assets/plugins/autoresize/plugin.min.js +1 -4
  22. package/tinymce-assets/plugins/autosave/plugin.js +208 -189
  23. package/tinymce-assets/plugins/autosave/plugin.min.js +1 -4
  24. package/tinymce-assets/plugins/charmap/plugin.js +905 -1566
  25. package/tinymce-assets/plugins/charmap/plugin.min.js +1 -4
  26. package/tinymce-assets/plugins/code/plugin.js +73 -61
  27. package/tinymce-assets/plugins/code/plugin.min.js +0 -3
  28. package/tinymce-assets/plugins/codesample/plugin.js +3593 -2402
  29. package/tinymce-assets/plugins/codesample/plugin.min.js +8 -3
  30. package/tinymce-assets/plugins/directionality/plugin.js +545 -304
  31. package/tinymce-assets/plugins/directionality/plugin.min.js +1 -4
  32. package/tinymce-assets/plugins/emoticons/js/emojiimages.min.js +0 -2
  33. package/tinymce-assets/plugins/emoticons/js/emojis.min.js +0 -1
  34. package/tinymce-assets/plugins/emoticons/plugin.js +702 -488
  35. package/tinymce-assets/plugins/emoticons/plugin.min.js +1 -4
  36. package/tinymce-assets/plugins/fullscreen/plugin.js +1409 -1049
  37. package/tinymce-assets/plugins/fullscreen/plugin.min.js +1 -4
  38. package/tinymce-assets/plugins/help/js/i18n/keynav/ar.js +4 -1
  39. package/tinymce-assets/plugins/help/js/i18n/keynav/bg_BG.js +4 -1
  40. package/tinymce-assets/plugins/help/js/i18n/keynav/ca.js +4 -1
  41. package/tinymce-assets/plugins/help/js/i18n/keynav/cs.js +4 -1
  42. package/tinymce-assets/plugins/help/js/i18n/keynav/da.js +4 -1
  43. package/tinymce-assets/plugins/help/js/i18n/keynav/de.js +4 -1
  44. package/tinymce-assets/plugins/help/js/i18n/keynav/el.js +4 -1
  45. package/tinymce-assets/plugins/help/js/i18n/keynav/en.js +4 -1
  46. package/tinymce-assets/plugins/help/js/i18n/keynav/es.js +4 -1
  47. package/tinymce-assets/plugins/help/js/i18n/keynav/eu.js +4 -1
  48. package/tinymce-assets/plugins/help/js/i18n/keynav/fa.js +4 -1
  49. package/tinymce-assets/plugins/help/js/i18n/keynav/fi.js +4 -1
  50. package/tinymce-assets/plugins/help/js/i18n/keynav/fr_FR.js +4 -1
  51. package/tinymce-assets/plugins/help/js/i18n/keynav/he_IL.js +4 -1
  52. package/tinymce-assets/plugins/help/js/i18n/keynav/hi.js +4 -1
  53. package/tinymce-assets/plugins/help/js/i18n/keynav/hr.js +4 -1
  54. package/tinymce-assets/plugins/help/js/i18n/keynav/hu_HU.js +4 -1
  55. package/tinymce-assets/plugins/help/js/i18n/keynav/id.js +4 -1
  56. package/tinymce-assets/plugins/help/js/i18n/keynav/it.js +4 -1
  57. package/tinymce-assets/plugins/help/js/i18n/keynav/ja.js +4 -1
  58. package/tinymce-assets/plugins/help/js/i18n/keynav/kk.js +4 -1
  59. package/tinymce-assets/plugins/help/js/i18n/keynav/ko_KR.js +4 -1
  60. package/tinymce-assets/plugins/help/js/i18n/keynav/ms.js +4 -1
  61. package/tinymce-assets/plugins/help/js/i18n/keynav/nb_NO.js +4 -1
  62. package/tinymce-assets/plugins/help/js/i18n/keynav/nl.js +4 -1
  63. package/tinymce-assets/plugins/help/js/i18n/keynav/pl.js +4 -1
  64. package/tinymce-assets/plugins/help/js/i18n/keynav/pt_BR.js +4 -1
  65. package/tinymce-assets/plugins/help/js/i18n/keynav/pt_PT.js +4 -1
  66. package/tinymce-assets/plugins/help/js/i18n/keynav/ro.js +4 -1
  67. package/tinymce-assets/plugins/help/js/i18n/keynav/ru.js +4 -1
  68. package/tinymce-assets/plugins/help/js/i18n/keynav/sk.js +4 -1
  69. package/tinymce-assets/plugins/help/js/i18n/keynav/sl_SI.js +5 -2
  70. package/tinymce-assets/plugins/help/js/i18n/keynav/sv_SE.js +4 -1
  71. package/tinymce-assets/plugins/help/js/i18n/keynav/th_TH.js +4 -1
  72. package/tinymce-assets/plugins/help/js/i18n/keynav/tr.js +4 -1
  73. package/tinymce-assets/plugins/help/js/i18n/keynav/uk.js +4 -1
  74. package/tinymce-assets/plugins/help/js/i18n/keynav/vi.js +4 -1
  75. package/tinymce-assets/plugins/help/js/i18n/keynav/zh_CN.js +8 -5
  76. package/tinymce-assets/plugins/help/js/i18n/keynav/zh_TW.js +4 -1
  77. package/tinymce-assets/plugins/help/plugin.js +739 -809
  78. package/tinymce-assets/plugins/help/plugin.min.js +1 -4
  79. package/tinymce-assets/plugins/image/plugin.js +1475 -1291
  80. package/tinymce-assets/plugins/image/plugin.min.js +1 -4
  81. package/tinymce-assets/plugins/importcss/plugin.js +328 -269
  82. package/tinymce-assets/plugins/importcss/plugin.min.js +1 -4
  83. package/tinymce-assets/plugins/insertdatetime/plugin.js +140 -141
  84. package/tinymce-assets/plugins/insertdatetime/plugin.min.js +1 -4
  85. package/tinymce-assets/plugins/link/plugin.js +1419 -1084
  86. package/tinymce-assets/plugins/link/plugin.min.js +1 -4
  87. package/tinymce-assets/plugins/lists/plugin.js +2177 -1805
  88. package/tinymce-assets/plugins/lists/plugin.min.js +1 -4
  89. package/tinymce-assets/plugins/media/plugin.js +1305 -1047
  90. package/tinymce-assets/plugins/media/plugin.min.js +1 -4
  91. package/tinymce-assets/plugins/nonbreaking/plugin.js +93 -88
  92. package/tinymce-assets/plugins/nonbreaking/plugin.min.js +0 -3
  93. package/tinymce-assets/plugins/pagebreak/plugin.js +91 -85
  94. package/tinymce-assets/plugins/pagebreak/plugin.min.js +0 -3
  95. package/tinymce-assets/plugins/preview/plugin.js +742 -74
  96. package/tinymce-assets/plugins/preview/plugin.min.js +1 -4
  97. package/tinymce-assets/plugins/quickbars/plugin.js +582 -375
  98. package/tinymce-assets/plugins/quickbars/plugin.min.js +1 -4
  99. package/tinymce-assets/plugins/save/plugin.js +100 -82
  100. package/tinymce-assets/plugins/save/plugin.min.js +1 -4
  101. package/tinymce-assets/plugins/searchreplace/plugin.js +1183 -906
  102. package/tinymce-assets/plugins/searchreplace/plugin.min.js +1 -4
  103. package/tinymce-assets/plugins/table/plugin.js +3651 -3094
  104. package/tinymce-assets/plugins/table/plugin.min.js +1 -4
  105. package/tinymce-assets/plugins/visualblocks/plugin.js +71 -63
  106. package/tinymce-assets/plugins/visualblocks/plugin.min.js +1 -4
  107. package/tinymce-assets/plugins/visualchars/plugin.js +685 -436
  108. package/tinymce-assets/plugins/visualchars/plugin.min.js +1 -4
  109. package/tinymce-assets/plugins/wordcount/plugin.js +382 -307
  110. package/tinymce-assets/plugins/wordcount/plugin.min.js +1 -4
  111. package/tinymce-assets/skins/content/dark/content.css +9 -0
  112. package/tinymce-assets/skins/content/dark/content.js +10 -2
  113. package/tinymce-assets/skins/content/dark/content.min.css +9 -0
  114. package/tinymce-assets/skins/content/default/content.css +9 -0
  115. package/tinymce-assets/skins/content/default/content.js +10 -2
  116. package/tinymce-assets/skins/content/default/content.min.css +9 -0
  117. package/tinymce-assets/skins/content/document/content.css +9 -0
  118. package/tinymce-assets/skins/content/document/content.js +10 -2
  119. package/tinymce-assets/skins/content/document/content.min.css +9 -0
  120. package/tinymce-assets/skins/content/tinymce-5/content.css +9 -0
  121. package/tinymce-assets/skins/content/tinymce-5/content.js +10 -2
  122. package/tinymce-assets/skins/content/tinymce-5/content.min.css +9 -0
  123. package/tinymce-assets/skins/content/tinymce-5-dark/content.css +9 -0
  124. package/tinymce-assets/skins/content/tinymce-5-dark/content.js +10 -2
  125. package/tinymce-assets/skins/content/tinymce-5-dark/content.min.css +9 -0
  126. package/tinymce-assets/skins/content/writer/content.css +9 -0
  127. package/tinymce-assets/skins/content/writer/content.js +10 -2
  128. package/tinymce-assets/skins/content/writer/content.min.css +9 -0
  129. package/tinymce-assets/skins/ui/oxide/content.css +157 -49
  130. package/tinymce-assets/skins/ui/oxide/content.inline.css +157 -49
  131. package/tinymce-assets/skins/ui/oxide/content.inline.js +10 -2
  132. package/tinymce-assets/skins/ui/oxide/content.inline.min.css +10 -1
  133. package/tinymce-assets/skins/ui/oxide/content.js +10 -2
  134. package/tinymce-assets/skins/ui/oxide/content.min.css +10 -1
  135. package/tinymce-assets/skins/ui/oxide/skin.css +1592 -214
  136. package/tinymce-assets/skins/ui/oxide/skin.js +1 -2
  137. package/tinymce-assets/skins/ui/oxide/skin.min.css +1 -1
  138. package/tinymce-assets/skins/ui/oxide/skin.shadowdom.js +1 -2
  139. package/tinymce-assets/skins/ui/oxide-dark/content.css +157 -42
  140. package/tinymce-assets/skins/ui/oxide-dark/content.inline.css +157 -49
  141. package/tinymce-assets/skins/ui/oxide-dark/content.inline.js +10 -2
  142. package/tinymce-assets/skins/ui/oxide-dark/content.inline.min.css +10 -1
  143. package/tinymce-assets/skins/ui/oxide-dark/content.js +10 -2
  144. package/tinymce-assets/skins/ui/oxide-dark/content.min.css +10 -1
  145. package/tinymce-assets/skins/ui/oxide-dark/skin.css +1595 -217
  146. package/tinymce-assets/skins/ui/oxide-dark/skin.js +1 -2
  147. package/tinymce-assets/skins/ui/oxide-dark/skin.min.css +1 -1
  148. package/tinymce-assets/skins/ui/oxide-dark/skin.shadowdom.js +1 -2
  149. package/tinymce-assets/skins/ui/tinymce-5/content.css +157 -49
  150. package/tinymce-assets/skins/ui/tinymce-5/content.inline.css +157 -49
  151. package/tinymce-assets/skins/ui/tinymce-5/content.inline.js +10 -2
  152. package/tinymce-assets/skins/ui/tinymce-5/content.inline.min.css +10 -1
  153. package/tinymce-assets/skins/ui/tinymce-5/content.js +10 -2
  154. package/tinymce-assets/skins/ui/tinymce-5/content.min.css +10 -1
  155. package/tinymce-assets/skins/ui/tinymce-5/skin.css +1606 -203
  156. package/tinymce-assets/skins/ui/tinymce-5/skin.js +1 -2
  157. package/tinymce-assets/skins/ui/tinymce-5/skin.min.css +1 -1
  158. package/tinymce-assets/skins/ui/tinymce-5/skin.shadowdom.js +1 -2
  159. package/tinymce-assets/skins/ui/tinymce-5-dark/content.css +157 -42
  160. package/tinymce-assets/skins/ui/tinymce-5-dark/content.inline.css +157 -49
  161. package/tinymce-assets/skins/ui/tinymce-5-dark/content.inline.js +10 -2
  162. package/tinymce-assets/skins/ui/tinymce-5-dark/content.inline.min.css +10 -1
  163. package/tinymce-assets/skins/ui/tinymce-5-dark/content.js +10 -2
  164. package/tinymce-assets/skins/ui/tinymce-5-dark/content.min.css +10 -1
  165. package/tinymce-assets/skins/ui/tinymce-5-dark/skin.css +1607 -204
  166. package/tinymce-assets/skins/ui/tinymce-5-dark/skin.js +1 -2
  167. package/tinymce-assets/skins/ui/tinymce-5-dark/skin.min.css +1 -1
  168. package/tinymce-assets/skins/ui/tinymce-5-dark/skin.shadowdom.js +1 -2
  169. package/tinymce-assets/themes/silver/theme.js +32786 -28738
  170. package/tinymce-assets/themes/silver/theme.min.js +1 -4
  171. package/types/dangl-angular-material-shared-tiny-mce.d.ts +12 -13
  172. package/types/dangl-angular-material-shared.d.ts +26 -26
  173. package/tinymce-assets/plugins/template/index.js +0 -7
  174. package/tinymce-assets/plugins/template/plugin.js +0 -567
  175. package/tinymce-assets/plugins/template/plugin.min.js +0 -4
@@ -1,5 +1,5 @@
1
1
  /**
2
- * TinyMCE version 6.8.3 (2024-02-08)
2
+ * TinyMCE version 7.9.3 (2026-05-19)
3
3
  */
4
4
 
5
5
  (function () {
@@ -7,589 +7,921 @@
7
7
 
8
8
  var global$7 = tinymce.util.Tools.resolve('tinymce.PluginManager');
9
9
 
10
+ /* eslint-disable @typescript-eslint/no-wrapper-object-types */
10
11
  const hasProto = (v, constructor, predicate) => {
11
- var _a;
12
- if (predicate(v, constructor.prototype)) {
13
- return true;
14
- } else {
15
- return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
16
- }
17
- };
18
- const typeOf = x => {
19
- const t = typeof x;
20
- if (x === null) {
21
- return 'null';
22
- } else if (t === 'object' && Array.isArray(x)) {
23
- return 'array';
24
- } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
25
- return 'string';
26
- } else {
27
- return t;
28
- }
12
+ var _a;
13
+ if (predicate(v, constructor.prototype)) {
14
+ return true;
15
+ }
16
+ else {
17
+ // String-based fallback time
18
+ return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
19
+ }
20
+ };
21
+ const typeOf = (x) => {
22
+ const t = typeof x;
23
+ if (x === null) {
24
+ return 'null';
25
+ }
26
+ else if (t === 'object' && Array.isArray(x)) {
27
+ return 'array';
28
+ }
29
+ else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
30
+ return 'string';
31
+ }
32
+ else {
33
+ return t;
34
+ }
29
35
  };
30
- const isType$1 = type => value => typeOf(value) === type;
31
- const isSimpleType = type => value => typeof value === type;
36
+ const isType$1 = (type) => (value) => typeOf(value) === type;
37
+ const isSimpleType = (type) => (value) => typeof value === type;
32
38
  const isString = isType$1('string');
33
39
  const isObject = isType$1('object');
34
40
  const isArray = isType$1('array');
35
41
  const isBoolean = isSimpleType('boolean');
36
- const isNullable = a => a === null || a === undefined;
37
- const isNonNullable = a => !isNullable(a);
42
+ const isNullable = (a) => a === null || a === undefined;
43
+ const isNonNullable = (a) => !isNullable(a);
38
44
  const isFunction = isSimpleType('function');
39
45
  const isNumber = isSimpleType('number');
40
46
 
41
- const noop = () => {
42
- };
43
- const compose1 = (fbc, fab) => a => fbc(fab(a));
44
- const constant = value => {
45
- return () => {
46
- return value;
47
- };
47
+ const noop = () => { };
48
+ /** Compose two unary functions. Similar to compose, but avoids using Function.prototype.apply. */
49
+ const compose1 = (fbc, fab) => (a) => fbc(fab(a));
50
+ const constant = (value) => {
51
+ return () => {
52
+ return value;
53
+ };
48
54
  };
49
55
  const tripleEquals = (a, b) => {
50
- return a === b;
56
+ return a === b;
51
57
  };
58
+ // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
52
59
  function curry(fn, ...initialArgs) {
53
- return (...restArgs) => {
54
- const all = initialArgs.concat(restArgs);
55
- return fn.apply(null, all);
56
- };
60
+ return (...restArgs) => {
61
+ const all = initialArgs.concat(restArgs);
62
+ return fn.apply(null, all);
63
+ };
57
64
  }
58
- const not = f => t => !f(t);
65
+ const not = (f) => (t) => !f(t);
59
66
  const never = constant(false);
60
67
 
68
+ /**
69
+ * The `Optional` type represents a value (of any type) that potentially does
70
+ * not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
71
+ * value does exist) or a `None` (in which case the value does not exist). This
72
+ * module defines a whole lot of FP-inspired utility functions for dealing with
73
+ * `Optional` objects.
74
+ *
75
+ * Comparison with null or undefined:
76
+ * - We don't get fancy null coalescing operators with `Optional`
77
+ * - We do get fancy helper functions with `Optional`
78
+ * - `Optional` support nesting, and allow for the type to still be nullable (or
79
+ * another `Optional`)
80
+ * - There is no option to turn off strict-optional-checks like there is for
81
+ * strict-null-checks
82
+ */
61
83
  class Optional {
62
- constructor(tag, value) {
63
- this.tag = tag;
64
- this.value = value;
65
- }
66
- static some(value) {
67
- return new Optional(true, value);
68
- }
69
- static none() {
70
- return Optional.singletonNone;
71
- }
72
- fold(onNone, onSome) {
73
- if (this.tag) {
74
- return onSome(this.value);
75
- } else {
76
- return onNone();
77
- }
78
- }
79
- isSome() {
80
- return this.tag;
81
- }
82
- isNone() {
83
- return !this.tag;
84
- }
85
- map(mapper) {
86
- if (this.tag) {
87
- return Optional.some(mapper(this.value));
88
- } else {
89
- return Optional.none();
90
- }
91
- }
92
- bind(binder) {
93
- if (this.tag) {
94
- return binder(this.value);
95
- } else {
96
- return Optional.none();
97
- }
98
- }
99
- exists(predicate) {
100
- return this.tag && predicate(this.value);
101
- }
102
- forall(predicate) {
103
- return !this.tag || predicate(this.value);
104
- }
105
- filter(predicate) {
106
- if (!this.tag || predicate(this.value)) {
107
- return this;
108
- } else {
109
- return Optional.none();
110
- }
111
- }
112
- getOr(replacement) {
113
- return this.tag ? this.value : replacement;
114
- }
115
- or(replacement) {
116
- return this.tag ? this : replacement;
117
- }
118
- getOrThunk(thunk) {
119
- return this.tag ? this.value : thunk();
120
- }
121
- orThunk(thunk) {
122
- return this.tag ? this : thunk();
123
- }
124
- getOrDie(message) {
125
- if (!this.tag) {
126
- throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
127
- } else {
128
- return this.value;
129
- }
130
- }
131
- static from(value) {
132
- return isNonNullable(value) ? Optional.some(value) : Optional.none();
133
- }
134
- getOrNull() {
135
- return this.tag ? this.value : null;
136
- }
137
- getOrUndefined() {
138
- return this.value;
139
- }
140
- each(worker) {
141
- if (this.tag) {
142
- worker(this.value);
143
- }
144
- }
145
- toArray() {
146
- return this.tag ? [this.value] : [];
147
- }
148
- toString() {
149
- return this.tag ? `some(${ this.value })` : 'none()';
150
- }
84
+ // The internal representation has a `tag` and a `value`, but both are
85
+ // private: able to be console.logged, but not able to be accessed by code
86
+ constructor(tag, value) {
87
+ this.tag = tag;
88
+ this.value = value;
89
+ }
90
+ // --- Identities ---
91
+ /**
92
+ * Creates a new `Optional<T>` that **does** contain a value.
93
+ */
94
+ static some(value) {
95
+ return new Optional(true, value);
96
+ }
97
+ /**
98
+ * Create a new `Optional<T>` that **does not** contain a value. `T` can be
99
+ * any type because we don't actually have a `T`.
100
+ */
101
+ static none() {
102
+ return Optional.singletonNone;
103
+ }
104
+ /**
105
+ * Perform a transform on an `Optional` type. Regardless of whether this
106
+ * `Optional` contains a value or not, `fold` will return a value of type `U`.
107
+ * If this `Optional` does not contain a value, the `U` will be created by
108
+ * calling `onNone`. If this `Optional` does contain a value, the `U` will be
109
+ * created by calling `onSome`.
110
+ *
111
+ * For the FP enthusiasts in the room, this function:
112
+ * 1. Could be used to implement all of the functions below
113
+ * 2. Forms a catamorphism
114
+ */
115
+ fold(onNone, onSome) {
116
+ if (this.tag) {
117
+ return onSome(this.value);
118
+ }
119
+ else {
120
+ return onNone();
121
+ }
122
+ }
123
+ /**
124
+ * Determine if this `Optional` object contains a value.
125
+ */
126
+ isSome() {
127
+ return this.tag;
128
+ }
129
+ /**
130
+ * Determine if this `Optional` object **does not** contain a value.
131
+ */
132
+ isNone() {
133
+ return !this.tag;
134
+ }
135
+ // --- Functor (name stolen from Haskell / maths) ---
136
+ /**
137
+ * Perform a transform on an `Optional` object, **if** there is a value. If
138
+ * you provide a function to turn a T into a U, this is the function you use
139
+ * to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
140
+ * a value then the output will also contain a value (that value being the
141
+ * output of `mapper(this.value)`), and if this **does not** contain a value
142
+ * then neither will the output.
143
+ */
144
+ map(mapper) {
145
+ if (this.tag) {
146
+ return Optional.some(mapper(this.value));
147
+ }
148
+ else {
149
+ return Optional.none();
150
+ }
151
+ }
152
+ // --- Monad (name stolen from Haskell / maths) ---
153
+ /**
154
+ * Perform a transform on an `Optional` object, **if** there is a value.
155
+ * Unlike `map`, here the transform itself also returns an `Optional`.
156
+ */
157
+ bind(binder) {
158
+ if (this.tag) {
159
+ return binder(this.value);
160
+ }
161
+ else {
162
+ return Optional.none();
163
+ }
164
+ }
165
+ // --- Traversable (name stolen from Haskell / maths) ---
166
+ /**
167
+ * For a given predicate, this function finds out if there **exists** a value
168
+ * inside this `Optional` object that meets the predicate. In practice, this
169
+ * means that for `Optional`s that do not contain a value it returns false (as
170
+ * no predicate-meeting value exists).
171
+ */
172
+ exists(predicate) {
173
+ return this.tag && predicate(this.value);
174
+ }
175
+ /**
176
+ * For a given predicate, this function finds out if **all** the values inside
177
+ * this `Optional` object meet the predicate. In practice, this means that
178
+ * for `Optional`s that do not contain a value it returns true (as all 0
179
+ * objects do meet the predicate).
180
+ */
181
+ forall(predicate) {
182
+ return !this.tag || predicate(this.value);
183
+ }
184
+ filter(predicate) {
185
+ if (!this.tag || predicate(this.value)) {
186
+ return this;
187
+ }
188
+ else {
189
+ return Optional.none();
190
+ }
191
+ }
192
+ // --- Getters ---
193
+ /**
194
+ * Get the value out of the inside of the `Optional` object, using a default
195
+ * `replacement` value if the provided `Optional` object does not contain a
196
+ * value.
197
+ */
198
+ getOr(replacement) {
199
+ return this.tag ? this.value : replacement;
200
+ }
201
+ /**
202
+ * Get the value out of the inside of the `Optional` object, using a default
203
+ * `replacement` value if the provided `Optional` object does not contain a
204
+ * value. Unlike `getOr`, in this method the `replacement` object is also
205
+ * `Optional` - meaning that this method will always return an `Optional`.
206
+ */
207
+ or(replacement) {
208
+ return this.tag ? this : replacement;
209
+ }
210
+ /**
211
+ * Get the value out of the inside of the `Optional` object, using a default
212
+ * `replacement` value if the provided `Optional` object does not contain a
213
+ * value. Unlike `getOr`, in this method the `replacement` value is
214
+ * "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
215
+ * pass a function which (if called) will **return** the `value` you want to
216
+ * use.
217
+ */
218
+ getOrThunk(thunk) {
219
+ return this.tag ? this.value : thunk();
220
+ }
221
+ /**
222
+ * Get the value out of the inside of the `Optional` object, using a default
223
+ * `replacement` value if the provided Optional object does not contain a
224
+ * value.
225
+ *
226
+ * Unlike `or`, in this method the `replacement` value is "thunked" - that is
227
+ * to say that you don't pass a value to `orThunk`, you pass a function which
228
+ * (if called) will **return** the `value` you want to use.
229
+ *
230
+ * Unlike `getOrThunk`, in this method the `replacement` value is also
231
+ * `Optional`, meaning that this method will always return an `Optional`.
232
+ */
233
+ orThunk(thunk) {
234
+ return this.tag ? this : thunk();
235
+ }
236
+ /**
237
+ * Get the value out of the inside of the `Optional` object, throwing an
238
+ * exception if the provided `Optional` object does not contain a value.
239
+ *
240
+ * WARNING:
241
+ * You should only be using this function if you know that the `Optional`
242
+ * object **is not** empty (otherwise you're throwing exceptions in production
243
+ * code, which is bad).
244
+ *
245
+ * In tests this is more acceptable.
246
+ *
247
+ * Prefer other methods to this, such as `.each`.
248
+ */
249
+ getOrDie(message) {
250
+ if (!this.tag) {
251
+ throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
252
+ }
253
+ else {
254
+ return this.value;
255
+ }
256
+ }
257
+ // --- Interop with null and undefined ---
258
+ /**
259
+ * Creates an `Optional` value from a nullable (or undefined-able) input.
260
+ * Null, or undefined, is converted to `None`, and anything else is converted
261
+ * to `Some`.
262
+ */
263
+ static from(value) {
264
+ return isNonNullable(value) ? Optional.some(value) : Optional.none();
265
+ }
266
+ /**
267
+ * Converts an `Optional` to a nullable type, by getting the value if it
268
+ * exists, or returning `null` if it does not.
269
+ */
270
+ getOrNull() {
271
+ return this.tag ? this.value : null;
272
+ }
273
+ /**
274
+ * Converts an `Optional` to an undefined-able type, by getting the value if
275
+ * it exists, or returning `undefined` if it does not.
276
+ */
277
+ getOrUndefined() {
278
+ return this.value;
279
+ }
280
+ // --- Utilities ---
281
+ /**
282
+ * If the `Optional` contains a value, perform an action on that value.
283
+ * Unlike the rest of the methods on this type, `.each` has side-effects. If
284
+ * you want to transform an `Optional<T>` **into** something, then this is not
285
+ * the method for you. If you want to use an `Optional<T>` to **do**
286
+ * something, then this is the method for you - provided you're okay with not
287
+ * doing anything in the case where the `Optional` doesn't have a value inside
288
+ * it. If you're not sure whether your use-case fits into transforming
289
+ * **into** something or **doing** something, check whether it has a return
290
+ * value. If it does, you should be performing a transform.
291
+ */
292
+ each(worker) {
293
+ if (this.tag) {
294
+ worker(this.value);
295
+ }
296
+ }
297
+ /**
298
+ * Turn the `Optional` object into an array that contains all of the values
299
+ * stored inside the `Optional`. In practice, this means the output will have
300
+ * either 0 or 1 elements.
301
+ */
302
+ toArray() {
303
+ return this.tag ? [this.value] : [];
304
+ }
305
+ /**
306
+ * Turn the `Optional` object into a string for debugging or printing. Not
307
+ * recommended for production code, but good for debugging. Also note that
308
+ * these days an `Optional` object can be logged to the console directly, and
309
+ * its inner value (if it exists) will be visible.
310
+ */
311
+ toString() {
312
+ return this.tag ? `some(${this.value})` : 'none()';
313
+ }
151
314
  }
315
+ // Sneaky optimisation: every instance of Optional.none is identical, so just
316
+ // reuse the same object
152
317
  Optional.singletonNone = new Optional(false);
153
318
 
319
+ /* eslint-disable @typescript-eslint/unbound-method */
154
320
  const nativeSlice = Array.prototype.slice;
155
321
  const nativeIndexOf = Array.prototype.indexOf;
156
322
  const nativePush = Array.prototype.push;
323
+ /* eslint-enable */
157
324
  const rawIndexOf = (ts, t) => nativeIndexOf.call(ts, t);
158
325
  const contains$1 = (xs, x) => rawIndexOf(xs, x) > -1;
159
326
  const exists = (xs, pred) => {
160
- for (let i = 0, len = xs.length; i < len; i++) {
161
- const x = xs[i];
162
- if (pred(x, i)) {
163
- return true;
327
+ for (let i = 0, len = xs.length; i < len; i++) {
328
+ const x = xs[i];
329
+ if (pred(x, i)) {
330
+ return true;
331
+ }
164
332
  }
165
- }
166
- return false;
333
+ return false;
167
334
  };
168
335
  const map = (xs, f) => {
169
- const len = xs.length;
170
- const r = new Array(len);
171
- for (let i = 0; i < len; i++) {
172
- const x = xs[i];
173
- r[i] = f(x, i);
174
- }
175
- return r;
336
+ // pre-allocating array size when it's guaranteed to be known
337
+ // http://jsperf.com/push-allocated-vs-dynamic/22
338
+ const len = xs.length;
339
+ const r = new Array(len);
340
+ for (let i = 0; i < len; i++) {
341
+ const x = xs[i];
342
+ r[i] = f(x, i);
343
+ }
344
+ return r;
176
345
  };
346
+ // Unwound implementing other functions in terms of each.
347
+ // The code size is roughly the same, and it should allow for better optimisation.
348
+ // const each = function<T, U>(xs: T[], f: (x: T, i?: number, xs?: T[]) => void): void {
177
349
  const each$1 = (xs, f) => {
178
- for (let i = 0, len = xs.length; i < len; i++) {
179
- const x = xs[i];
180
- f(x, i);
181
- }
182
- };
183
- const filter$1 = (xs, pred) => {
184
- const r = [];
185
- for (let i = 0, len = xs.length; i < len; i++) {
186
- const x = xs[i];
187
- if (pred(x, i)) {
188
- r.push(x);
350
+ for (let i = 0, len = xs.length; i < len; i++) {
351
+ const x = xs[i];
352
+ f(x, i);
189
353
  }
190
- }
191
- return r;
192
354
  };
193
- const groupBy = (xs, f) => {
194
- if (xs.length === 0) {
195
- return [];
196
- } else {
197
- let wasType = f(xs[0]);
355
+ const filter$1 = (xs, pred) => {
198
356
  const r = [];
199
- let group = [];
200
357
  for (let i = 0, len = xs.length; i < len; i++) {
201
- const x = xs[i];
202
- const type = f(x);
203
- if (type !== wasType) {
204
- r.push(group);
205
- group = [];
206
- }
207
- wasType = type;
208
- group.push(x);
209
- }
210
- if (group.length !== 0) {
211
- r.push(group);
358
+ const x = xs[i];
359
+ if (pred(x, i)) {
360
+ r.push(x);
361
+ }
212
362
  }
213
363
  return r;
214
- }
364
+ };
365
+ /*
366
+ * Groups an array into contiguous arrays of like elements. Whether an element is like or not depends on f.
367
+ *
368
+ * f is a function that derives a value from an element - e.g. true or false, or a string.
369
+ * Elements are like if this function generates the same value for them (according to ===).
370
+ *
371
+ *
372
+ * Order of the elements is preserved. Arr.flatten() on the result will return the original list, as with Haskell groupBy function.
373
+ * For a good explanation, see the group function (which is a special case of groupBy)
374
+ * http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-List.html#v:group
375
+ */
376
+ const groupBy = (xs, f) => {
377
+ if (xs.length === 0) {
378
+ return [];
379
+ }
380
+ else {
381
+ let wasType = f(xs[0]); // initial case for matching
382
+ const r = [];
383
+ let group = [];
384
+ for (let i = 0, len = xs.length; i < len; i++) {
385
+ const x = xs[i];
386
+ const type = f(x);
387
+ if (type !== wasType) {
388
+ r.push(group);
389
+ group = [];
390
+ }
391
+ wasType = type;
392
+ group.push(x);
393
+ }
394
+ if (group.length !== 0) {
395
+ r.push(group);
396
+ }
397
+ return r;
398
+ }
215
399
  };
216
400
  const foldl = (xs, f, acc) => {
217
- each$1(xs, (x, i) => {
218
- acc = f(acc, x, i);
219
- });
220
- return acc;
401
+ each$1(xs, (x, i) => {
402
+ acc = f(acc, x, i);
403
+ });
404
+ return acc;
221
405
  };
222
406
  const findUntil = (xs, pred, until) => {
223
- for (let i = 0, len = xs.length; i < len; i++) {
224
- const x = xs[i];
225
- if (pred(x, i)) {
226
- return Optional.some(x);
227
- } else if (until(x, i)) {
228
- break;
407
+ for (let i = 0, len = xs.length; i < len; i++) {
408
+ const x = xs[i];
409
+ if (pred(x, i)) {
410
+ return Optional.some(x);
411
+ }
412
+ else if (until(x, i)) {
413
+ break;
414
+ }
229
415
  }
230
- }
231
- return Optional.none();
416
+ return Optional.none();
232
417
  };
233
418
  const find = (xs, pred) => {
234
- return findUntil(xs, pred, never);
419
+ return findUntil(xs, pred, never);
235
420
  };
236
- const flatten = xs => {
237
- const r = [];
238
- for (let i = 0, len = xs.length; i < len; ++i) {
239
- if (!isArray(xs[i])) {
240
- throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
421
+ const flatten = (xs) => {
422
+ // Note, this is possible because push supports multiple arguments:
423
+ // http://jsperf.com/concat-push/6
424
+ // Note that in the past, concat() would silently work (very slowly) for array-like objects.
425
+ // With this change it will throw an error.
426
+ const r = [];
427
+ for (let i = 0, len = xs.length; i < len; ++i) {
428
+ // Ensure that each value is an array itself
429
+ if (!isArray(xs[i])) {
430
+ throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
431
+ }
432
+ nativePush.apply(r, xs[i]);
241
433
  }
242
- nativePush.apply(r, xs[i]);
243
- }
244
- return r;
434
+ return r;
245
435
  };
246
436
  const bind = (xs, f) => flatten(map(xs, f));
247
- const reverse = xs => {
248
- const r = nativeSlice.call(xs, 0);
249
- r.reverse();
250
- return r;
437
+ const reverse = (xs) => {
438
+ const r = nativeSlice.call(xs, 0);
439
+ r.reverse();
440
+ return r;
251
441
  };
252
442
  const get$1 = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
253
- const head = xs => get$1(xs, 0);
254
- const last = xs => get$1(xs, xs.length - 1);
443
+ const head = (xs) => get$1(xs, 0);
444
+ const last = (xs) => get$1(xs, xs.length - 1);
255
445
  const unique = (xs, comparator) => {
256
- const r = [];
257
- const isDuplicated = isFunction(comparator) ? x => exists(r, i => comparator(i, x)) : x => contains$1(r, x);
258
- for (let i = 0, len = xs.length; i < len; i++) {
259
- const x = xs[i];
260
- if (!isDuplicated(x)) {
261
- r.push(x);
446
+ const r = [];
447
+ const isDuplicated = isFunction(comparator) ?
448
+ (x) => exists(r, (i) => comparator(i, x)) :
449
+ (x) => contains$1(r, x);
450
+ for (let i = 0, len = xs.length; i < len; i++) {
451
+ const x = xs[i];
452
+ if (!isDuplicated(x)) {
453
+ r.push(x);
454
+ }
262
455
  }
263
- }
264
- return r;
456
+ return r;
457
+ };
458
+
459
+ // There are many variations of Object iteration that are faster than the 'for-in' style:
460
+ // http://jsperf.com/object-keys-iteration/107
461
+ //
462
+ // Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
463
+ const keys = Object.keys;
464
+ const each = (obj, f) => {
465
+ const props = keys(obj);
466
+ for (let k = 0, len = props.length; k < len; k++) {
467
+ const i = props[k];
468
+ const x = obj[i];
469
+ f(x, i);
470
+ }
471
+ };
472
+ const objAcc = (r) => (x, i) => {
473
+ r[i] = x;
474
+ };
475
+ const internalFilter = (obj, pred, onTrue, onFalse) => {
476
+ each(obj, (x, i) => {
477
+ (pred(x, i) ? onTrue : onFalse)(x, i);
478
+ });
479
+ };
480
+ const filter = (obj, pred) => {
481
+ const t = {};
482
+ internalFilter(obj, pred, objAcc(t), noop);
483
+ return t;
265
484
  };
266
485
 
267
- const is$2 = (lhs, rhs, comparator = tripleEquals) => lhs.exists(left => comparator(left, rhs));
486
+ const Cell = (initial) => {
487
+ let value = initial;
488
+ const get = () => {
489
+ return value;
490
+ };
491
+ const set = (v) => {
492
+ value = v;
493
+ };
494
+ return {
495
+ get,
496
+ set
497
+ };
498
+ };
499
+
500
+ // Use window object as the global if it's available since CSP will block script evals
501
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
502
+ const Global = typeof window !== 'undefined' ? window : Function('return this;')();
503
+
504
+ /**
505
+ * **Is** the value stored inside this Optional object equal to `rhs`?
506
+ */
507
+ const is$2 = (lhs, rhs, comparator = tripleEquals) => lhs.exists((left) => comparator(left, rhs));
508
+ /**
509
+ * Are these two Optional objects equal? Equality here means either they're both
510
+ * `Some` (and the values are equal under the comparator) or they're both `None`.
511
+ */
268
512
  const equals = (lhs, rhs, comparator = tripleEquals) => lift2(lhs, rhs, comparator).getOr(lhs.isNone() && rhs.isNone());
513
+ /*
514
+ Notes on the lift functions:
515
+ - We used to have a generic liftN, but we were concerned about its type-safety, and the below variants were faster in microbenchmarks.
516
+ - The getOrDie calls are partial functions, but are checked beforehand. This is faster and more convenient (but less safe) than folds.
517
+ - && is used instead of a loop for simplicity and performance.
518
+ */
269
519
  const lift2 = (oa, ob, f) => oa.isSome() && ob.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie())) : Optional.none();
270
520
 
271
- const COMMENT = 8;
272
- const DOCUMENT = 9;
273
- const DOCUMENT_FRAGMENT = 11;
274
- const ELEMENT = 1;
275
- const TEXT = 3;
521
+ /** path :: ([String], JsObj?) -> JsObj */
522
+ const path = (parts, scope) => {
523
+ let o = scope !== undefined && scope !== null ? scope : Global;
524
+ for (let i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
525
+ o = o[parts[i]];
526
+ }
527
+ return o;
528
+ };
529
+ /** resolve :: (String, JsObj?) -> JsObj */
530
+ const resolve = (p, scope) => {
531
+ const parts = p.split('.');
532
+ return path(parts, scope);
533
+ };
534
+
535
+ const blank = (r) => (s) => s.replace(r, '');
536
+ /** removes all leading and trailing spaces */
537
+ const trim = blank(/^\s+|\s+$/g);
538
+ const isNotEmpty = (s) => s.length > 0;
539
+ const isEmpty$2 = (s) => !isNotEmpty(s);
540
+
541
+ const zeroWidth = '\uFEFF';
542
+ const isZwsp = (char) => char === zeroWidth;
276
543
 
277
544
  const fromHtml = (html, scope) => {
278
- const doc = scope || document;
279
- const div = doc.createElement('div');
280
- div.innerHTML = html;
281
- if (!div.hasChildNodes() || div.childNodes.length > 1) {
282
- const message = 'HTML does not have a single root node';
283
- console.error(message, html);
284
- throw new Error(message);
285
- }
286
- return fromDom$1(div.childNodes[0]);
545
+ const doc = scope || document;
546
+ const div = doc.createElement('div');
547
+ div.innerHTML = html;
548
+ if (!div.hasChildNodes() || div.childNodes.length > 1) {
549
+ const message = 'HTML does not have a single root node';
550
+ // eslint-disable-next-line no-console
551
+ console.error(message, html);
552
+ throw new Error(message);
553
+ }
554
+ return fromDom$1(div.childNodes[0]);
287
555
  };
288
556
  const fromTag = (tag, scope) => {
289
- const doc = scope || document;
290
- const node = doc.createElement(tag);
291
- return fromDom$1(node);
557
+ const doc = scope || document;
558
+ const node = doc.createElement(tag);
559
+ return fromDom$1(node);
292
560
  };
293
561
  const fromText = (text, scope) => {
294
- const doc = scope || document;
295
- const node = doc.createTextNode(text);
296
- return fromDom$1(node);
562
+ const doc = scope || document;
563
+ const node = doc.createTextNode(text);
564
+ return fromDom$1(node);
297
565
  };
298
- const fromDom$1 = node => {
299
- if (node === null || node === undefined) {
300
- throw new Error('Node cannot be null or undefined');
301
- }
302
- return { dom: node };
566
+ const fromDom$1 = (node) => {
567
+ // TODO: Consider removing this check, but left atm for safety
568
+ if (node === null || node === undefined) {
569
+ throw new Error('Node cannot be null or undefined');
570
+ }
571
+ return {
572
+ dom: node
573
+ };
303
574
  };
304
575
  const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom$1);
576
+ // tslint:disable-next-line:variable-name
305
577
  const SugarElement = {
306
- fromHtml,
307
- fromTag,
308
- fromText,
309
- fromDom: fromDom$1,
310
- fromPoint
578
+ fromHtml,
579
+ fromTag,
580
+ fromText,
581
+ fromDom: fromDom$1,
582
+ fromPoint
311
583
  };
312
584
 
585
+ const COMMENT = 8;
586
+ const DOCUMENT_FRAGMENT = 11;
587
+ const ELEMENT = 1;
588
+ const TEXT = 3;
589
+
313
590
  const is$1 = (element, selector) => {
314
- const dom = element.dom;
315
- if (dom.nodeType !== ELEMENT) {
316
- return false;
317
- } else {
318
- const elem = dom;
319
- if (elem.matches !== undefined) {
320
- return elem.matches(selector);
321
- } else if (elem.msMatchesSelector !== undefined) {
322
- return elem.msMatchesSelector(selector);
323
- } else if (elem.webkitMatchesSelector !== undefined) {
324
- return elem.webkitMatchesSelector(selector);
325
- } else if (elem.mozMatchesSelector !== undefined) {
326
- return elem.mozMatchesSelector(selector);
327
- } else {
328
- throw new Error('Browser lacks native selectors');
329
- }
330
- }
591
+ const dom = element.dom;
592
+ if (dom.nodeType !== ELEMENT) {
593
+ return false;
594
+ }
595
+ else {
596
+ const elem = dom;
597
+ if (elem.matches !== undefined) {
598
+ return elem.matches(selector);
599
+ }
600
+ else if (elem.msMatchesSelector !== undefined) {
601
+ return elem.msMatchesSelector(selector);
602
+ }
603
+ else if (elem.webkitMatchesSelector !== undefined) {
604
+ return elem.webkitMatchesSelector(selector);
605
+ }
606
+ else if (elem.mozMatchesSelector !== undefined) {
607
+ // cast to any as mozMatchesSelector doesn't exist in TS DOM lib
608
+ return elem.mozMatchesSelector(selector);
609
+ }
610
+ else {
611
+ throw new Error('Browser lacks native selectors');
612
+ } // unfortunately we can't throw this on startup :(
613
+ }
331
614
  };
332
615
 
333
616
  const eq = (e1, e2) => e1.dom === e2.dom;
617
+ // Returns: true if node e1 contains e2, otherwise false.
618
+ // (returns false if e1===e2: A node does not contain itself).
334
619
  const contains = (e1, e2) => {
335
- const d1 = e1.dom;
336
- const d2 = e2.dom;
337
- return d1 === d2 ? false : d1.contains(d2);
620
+ const d1 = e1.dom;
621
+ const d2 = e2.dom;
622
+ return d1 === d2 ? false : d1.contains(d2);
338
623
  };
339
624
  const is = is$1;
340
625
 
341
- const Global = typeof window !== 'undefined' ? window : Function('return this;')();
342
-
343
- const path = (parts, scope) => {
344
- let o = scope !== undefined && scope !== null ? scope : Global;
345
- for (let i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
346
- o = o[parts[i]];
347
- }
348
- return o;
349
- };
350
- const resolve = (p, scope) => {
351
- const parts = p.split('.');
352
- return path(parts, scope);
353
- };
354
-
355
626
  const unsafe = (name, scope) => {
356
- return resolve(name, scope);
627
+ return resolve(name, scope);
357
628
  };
358
629
  const getOrDie = (name, scope) => {
359
- const actual = unsafe(name, scope);
360
- if (actual === undefined || actual === null) {
361
- throw new Error(name + ' not available on this browser');
362
- }
363
- return actual;
630
+ const actual = unsafe(name, scope);
631
+ if (actual === undefined || actual === null) {
632
+ throw new Error(name + ' not available on this browser');
633
+ }
634
+ return actual;
364
635
  };
365
636
 
366
637
  const getPrototypeOf = Object.getPrototypeOf;
367
- const sandHTMLElement = scope => {
368
- return getOrDie('HTMLElement', scope);
369
- };
370
- const isPrototypeOf = x => {
371
- const scope = resolve('ownerDocument.defaultView', x);
372
- return isObject(x) && (sandHTMLElement(scope).prototype.isPrototypeOf(x) || /^HTML\w*Element$/.test(getPrototypeOf(x).constructor.name));
373
- };
374
-
375
- const name = element => {
376
- const r = element.dom.nodeName;
377
- return r.toLowerCase();
378
- };
379
- const type = element => element.dom.nodeType;
380
- const isType = t => element => type(element) === t;
381
- const isComment = element => type(element) === COMMENT || name(element) === '#comment';
382
- const isHTMLElement = element => isElement$1(element) && isPrototypeOf(element.dom);
638
+ /*
639
+ * IE9 and above
640
+ *
641
+ * MDN no use on this one, but here's the link anyway:
642
+ * https://developer.mozilla.org/en/docs/Web/API/HTMLElement
643
+ */
644
+ const sandHTMLElement = (scope) => {
645
+ return getOrDie('HTMLElement', scope);
646
+ };
647
+ const isPrototypeOf = (x) => {
648
+ // use Resolve to get the window object for x and just return undefined if it can't find it.
649
+ // undefined scope later triggers using the global window.
650
+ const scope = resolve('ownerDocument.defaultView', x);
651
+ // TINY-7374: We can't rely on looking at the owner window HTMLElement as the element may have
652
+ // been constructed in a different window and then appended to the current window document.
653
+ return isObject(x) && (sandHTMLElement(scope).prototype.isPrototypeOf(x) || /^HTML\w*Element$/.test(getPrototypeOf(x).constructor.name));
654
+ };
655
+
656
+ const name = (element) => {
657
+ const r = element.dom.nodeName;
658
+ return r.toLowerCase();
659
+ };
660
+ const type = (element) => element.dom.nodeType;
661
+ const isType = (t) => (element) => type(element) === t;
662
+ const isComment = (element) => type(element) === COMMENT || name(element) === '#comment';
663
+ const isHTMLElement = (element) => isElement$1(element) && isPrototypeOf(element.dom);
383
664
  const isElement$1 = isType(ELEMENT);
384
665
  const isText = isType(TEXT);
385
- const isDocument = isType(DOCUMENT);
386
666
  const isDocumentFragment = isType(DOCUMENT_FRAGMENT);
387
- const isTag = tag => e => isElement$1(e) && name(e) === tag;
388
-
389
- const owner = element => SugarElement.fromDom(element.dom.ownerDocument);
390
- const documentOrOwner = dos => isDocument(dos) ? dos : owner(dos);
391
- const parent = element => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
392
- const parentElement = element => Optional.from(element.dom.parentElement).map(SugarElement.fromDom);
393
- const nextSibling = element => Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
394
- const children = element => map(element.dom.childNodes, SugarElement.fromDom);
395
- const child = (element, index) => {
396
- const cs = element.dom.childNodes;
397
- return Optional.from(cs[index]).map(SugarElement.fromDom);
398
- };
399
- const firstChild = element => child(element, 0);
400
- const lastChild = element => child(element, element.dom.childNodes.length - 1);
401
-
402
- const isShadowRoot = dos => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
403
- const supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
404
- const getRootNode = supported ? e => SugarElement.fromDom(e.dom.getRootNode()) : documentOrOwner;
405
- const getShadowRoot = e => {
406
- const r = getRootNode(e);
407
- return isShadowRoot(r) ? Optional.some(r) : Optional.none();
408
- };
409
- const getShadowHost = e => SugarElement.fromDom(e.dom.host);
410
-
411
- const inBody = element => {
412
- const dom = isText(element) ? element.dom.parentNode : element.dom;
413
- if (dom === undefined || dom === null || dom.ownerDocument === null) {
414
- return false;
415
- }
416
- const doc = dom.ownerDocument;
417
- return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
418
- };
419
-
420
- var ClosestOrAncestor = (is, ancestor, scope, a, isRoot) => {
421
- if (is(scope, a)) {
422
- return Optional.some(scope);
423
- } else if (isFunction(isRoot) && isRoot(scope)) {
424
- return Optional.none();
425
- } else {
426
- return ancestor(scope, a, isRoot);
427
- }
428
- };
429
-
430
- const ancestor$3 = (scope, predicate, isRoot) => {
431
- let element = scope.dom;
432
- const stop = isFunction(isRoot) ? isRoot : never;
433
- while (element.parentNode) {
434
- element = element.parentNode;
435
- const el = SugarElement.fromDom(element);
436
- if (predicate(el)) {
437
- return Optional.some(el);
438
- } else if (stop(el)) {
439
- break;
440
- }
441
- }
442
- return Optional.none();
443
- };
444
- const closest$2 = (scope, predicate, isRoot) => {
445
- const is = (s, test) => test(s);
446
- return ClosestOrAncestor(is, ancestor$3, scope, predicate, isRoot);
447
- };
448
-
449
- const ancestor$2 = (scope, selector, isRoot) => ancestor$3(scope, e => is$1(e, selector), isRoot);
450
- const closest$1 = (scope, selector, isRoot) => {
451
- const is = (element, selector) => is$1(element, selector);
452
- return ClosestOrAncestor(is, ancestor$2, scope, selector, isRoot);
453
- };
667
+ const isTag = (tag) => (e) => isElement$1(e) && name(e) === tag;
454
668
 
455
- const closest = target => closest$1(target, '[contenteditable]');
456
- const isEditable = (element, assumeEditable = false) => {
457
- if (inBody(element)) {
458
- return element.dom.isContentEditable;
459
- } else {
460
- return closest(element).fold(constant(assumeEditable), editable => getRaw(editable) === 'true');
461
- }
462
- };
463
- const getRaw = element => element.dom.contentEditable;
669
+ const parent = (element) => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
670
+ const parentElement = (element) => Optional.from(element.dom.parentElement).map(SugarElement.fromDom);
671
+ const nextSibling = (element) => Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
672
+ const children = (element) => map(element.dom.childNodes, SugarElement.fromDom);
673
+ const child = (element, index) => {
674
+ const cs = element.dom.childNodes;
675
+ return Optional.from(cs[index]).map(SugarElement.fromDom);
676
+ };
677
+ const firstChild = (element) => child(element, 0);
678
+ const lastChild = (element) => child(element, element.dom.childNodes.length - 1);
679
+
680
+ /**
681
+ * Is the element a ShadowRoot?
682
+ *
683
+ * Note: this is insufficient to test if any element is a shadow root, but it is sufficient to differentiate between
684
+ * a Document and a ShadowRoot.
685
+ */
686
+ const isShadowRoot = (dos) => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
687
+ const getRootNode = (e) => SugarElement.fromDom(e.dom.getRootNode());
688
+ /** If this element is in a ShadowRoot, return it. */
689
+ const getShadowRoot = (e) => {
690
+ const r = getRootNode(e);
691
+ return isShadowRoot(r) ? Optional.some(r) : Optional.none();
692
+ };
693
+ /** Return the host of a ShadowRoot.
694
+ *
695
+ * This function will throw if Shadow DOM is unsupported in the browser, or if the host is null.
696
+ * If you actually have a ShadowRoot, this shouldn't happen.
697
+ */
698
+ const getShadowHost = (e) => SugarElement.fromDom(e.dom.host);
464
699
 
465
700
  const before$1 = (marker, element) => {
466
- const parent$1 = parent(marker);
467
- parent$1.each(v => {
468
- v.dom.insertBefore(element.dom, marker.dom);
469
- });
701
+ const parent$1 = parent(marker);
702
+ parent$1.each((v) => {
703
+ v.dom.insertBefore(element.dom, marker.dom);
704
+ });
470
705
  };
471
706
  const after = (marker, element) => {
472
- const sibling = nextSibling(marker);
473
- sibling.fold(() => {
474
- const parent$1 = parent(marker);
475
- parent$1.each(v => {
476
- append$1(v, element);
707
+ const sibling = nextSibling(marker);
708
+ sibling.fold(() => {
709
+ const parent$1 = parent(marker);
710
+ parent$1.each((v) => {
711
+ append$1(v, element);
712
+ });
713
+ }, (v) => {
714
+ before$1(v, element);
477
715
  });
478
- }, v => {
479
- before$1(v, element);
480
- });
481
716
  };
482
717
  const prepend = (parent, element) => {
483
- const firstChild$1 = firstChild(parent);
484
- firstChild$1.fold(() => {
485
- append$1(parent, element);
486
- }, v => {
487
- parent.dom.insertBefore(element.dom, v.dom);
488
- });
718
+ const firstChild$1 = firstChild(parent);
719
+ firstChild$1.fold(() => {
720
+ append$1(parent, element);
721
+ }, (v) => {
722
+ parent.dom.insertBefore(element.dom, v.dom);
723
+ });
489
724
  };
490
725
  const append$1 = (parent, element) => {
491
- parent.dom.appendChild(element.dom);
726
+ parent.dom.appendChild(element.dom);
492
727
  };
493
728
 
494
729
  const before = (marker, elements) => {
495
- each$1(elements, x => {
496
- before$1(marker, x);
497
- });
730
+ each$1(elements, (x) => {
731
+ before$1(marker, x);
732
+ });
498
733
  };
499
734
  const append = (parent, elements) => {
500
- each$1(elements, x => {
501
- append$1(parent, x);
502
- });
735
+ each$1(elements, (x) => {
736
+ append$1(parent, x);
737
+ });
503
738
  };
504
739
 
505
- const empty = element => {
506
- element.dom.textContent = '';
507
- each$1(children(element), rogue => {
508
- remove(rogue);
509
- });
740
+ const rawSet = (dom, key, value) => {
741
+ /*
742
+ * JQuery coerced everything to a string, and silently did nothing on text node/null/undefined.
743
+ *
744
+ * We fail on those invalid cases, only allowing numbers and booleans.
745
+ */
746
+ if (isString(value) || isBoolean(value) || isNumber(value)) {
747
+ dom.setAttribute(key, value + '');
748
+ }
749
+ else {
750
+ // eslint-disable-next-line no-console
751
+ console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
752
+ throw new Error('Attribute value was not simple');
753
+ }
510
754
  };
511
- const remove = element => {
512
- const dom = element.dom;
513
- if (dom.parentNode !== null) {
514
- dom.parentNode.removeChild(dom);
515
- }
755
+ const setAll = (element, attrs) => {
756
+ const dom = element.dom;
757
+ each(attrs, (v, k) => {
758
+ rawSet(dom, k, v);
759
+ });
516
760
  };
761
+ const clone$1 = (element) => foldl(element.dom.attributes, (acc, attr) => {
762
+ acc[attr.name] = attr.value;
763
+ return acc;
764
+ }, {});
517
765
 
518
- var global$6 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
519
-
520
- var global$5 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
521
-
522
- var global$4 = tinymce.util.Tools.resolve('tinymce.util.VK');
766
+ const empty = (element) => {
767
+ // shortcut "empty node" trick. Requires IE 9.
768
+ element.dom.textContent = '';
769
+ // If the contents was a single empty text node, the above doesn't remove it. But, it's still faster in general
770
+ // than removing every child node manually.
771
+ // The following is (probably) safe for performance as 99.9% of the time the trick works and
772
+ // Traverse.children will return an empty array.
773
+ each$1(children(element), (rogue) => {
774
+ remove(rogue);
775
+ });
776
+ };
777
+ const remove = (element) => {
778
+ const dom = element.dom;
779
+ if (dom.parentNode !== null) {
780
+ dom.parentNode.removeChild(dom);
781
+ }
782
+ };
523
783
 
524
- const fromDom = nodes => map(nodes, SugarElement.fromDom);
784
+ const clone = (original, isDeep) => SugarElement.fromDom(original.dom.cloneNode(isDeep));
785
+ /** Deep clone - everything copied including children */
786
+ const deep = (original) => clone(original, true);
787
+ /** Shallow clone, with a new tag */
788
+ const shallowAs = (original, tag) => {
789
+ const nu = SugarElement.fromTag(tag);
790
+ const attributes = clone$1(original);
791
+ setAll(nu, attributes);
792
+ return nu;
793
+ };
794
+ /** Change the tag name, but keep all children */
795
+ const mutate = (original, tag) => {
796
+ const nu = shallowAs(original, tag);
797
+ after(original, nu);
798
+ const children$1 = children(original);
799
+ append(nu, children$1);
800
+ remove(original);
801
+ return nu;
802
+ };
803
+
804
+ const fromDom = (nodes) => map(nodes, SugarElement.fromDom);
805
+
806
+ // some elements, such as mathml, don't have style attributes
807
+ // others, such as angular elements, have style attributes that aren't a CSSStyleDeclaration
808
+ const isSupported = (dom) =>
809
+ // eslint-disable-next-line @typescript-eslint/unbound-method
810
+ dom.style !== undefined && isFunction(dom.style.getPropertyValue);
811
+
812
+ // Node.contains() is very, very, very good performance
813
+ // http://jsperf.com/closest-vs-contains/5
814
+ const inBody = (element) => {
815
+ // Technically this is only required on IE, where contains() returns false for text nodes.
816
+ // But it's cheap enough to run everywhere and Sugar doesn't have platform detection (yet).
817
+ const dom = isText(element) ? element.dom.parentNode : element.dom;
818
+ // use ownerDocument.body to ensure this works inside iframes.
819
+ // Normally contains is bad because an element "contains" itself, but here we want that.
820
+ if (dom === undefined || dom === null || dom.ownerDocument === null) {
821
+ return false;
822
+ }
823
+ const doc = dom.ownerDocument;
824
+ return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
825
+ };
525
826
 
526
- const keys = Object.keys;
527
- const each = (obj, f) => {
528
- const props = keys(obj);
529
- for (let k = 0, len = props.length; k < len; k++) {
530
- const i = props[k];
531
- const x = obj[i];
532
- f(x, i);
533
- }
827
+ const internalSet = (dom, property, value) => {
828
+ // This is going to hurt. Apologies.
829
+ // JQuery coerces numbers to pixels for certain property names, and other times lets numbers through.
830
+ // we're going to be explicit; strings only.
831
+ if (!isString(value)) {
832
+ // eslint-disable-next-line no-console
833
+ console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
834
+ throw new Error('CSS value must be a string: ' + value);
835
+ }
836
+ // removed: support for dom().style[property] where prop is camel case instead of normal property name
837
+ if (isSupported(dom)) {
838
+ dom.style.setProperty(property, value);
839
+ }
534
840
  };
535
- const objAcc = r => (x, i) => {
536
- r[i] = x;
841
+ const set = (element, property, value) => {
842
+ const dom = element.dom;
843
+ internalSet(dom, property, value);
537
844
  };
538
- const internalFilter = (obj, pred, onTrue, onFalse) => {
539
- each(obj, (x, i) => {
540
- (pred(x, i) ? onTrue : onFalse)(x, i);
541
- });
845
+
846
+ const fromElements = (elements, scope) => {
847
+ const doc = scope || document;
848
+ const fragment = doc.createDocumentFragment();
849
+ each$1(elements, (element) => {
850
+ fragment.appendChild(element.dom);
851
+ });
852
+ return SugarElement.fromDom(fragment);
542
853
  };
543
- const filter = (obj, pred) => {
544
- const t = {};
545
- internalFilter(obj, pred, objAcc(t), noop);
546
- return t;
854
+
855
+ var ClosestOrAncestor = (is, ancestor, scope, a, isRoot) => {
856
+ if (is(scope, a)) {
857
+ return Optional.some(scope);
858
+ }
859
+ else if (isFunction(isRoot) && isRoot(scope)) {
860
+ return Optional.none();
861
+ }
862
+ else {
863
+ return ancestor(scope, a, isRoot);
864
+ }
547
865
  };
548
866
 
549
- const rawSet = (dom, key, value) => {
550
- if (isString(value) || isBoolean(value) || isNumber(value)) {
551
- dom.setAttribute(key, value + '');
552
- } else {
553
- console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
554
- throw new Error('Attribute value was not simple');
555
- }
867
+ const ancestor$3 = (scope, predicate, isRoot) => {
868
+ let element = scope.dom;
869
+ const stop = isFunction(isRoot) ? isRoot : never;
870
+ while (element.parentNode) {
871
+ element = element.parentNode;
872
+ const el = SugarElement.fromDom(element);
873
+ if (predicate(el)) {
874
+ return Optional.some(el);
875
+ }
876
+ else if (stop(el)) {
877
+ break;
878
+ }
879
+ }
880
+ return Optional.none();
881
+ };
882
+ const closest$2 = (scope, predicate, isRoot) => {
883
+ // This is required to avoid ClosestOrAncestor passing the predicate to itself
884
+ const is = (s, test) => test(s);
885
+ return ClosestOrAncestor(is, ancestor$3, scope, predicate, isRoot);
556
886
  };
557
- const setAll = (element, attrs) => {
558
- const dom = element.dom;
559
- each(attrs, (v, k) => {
560
- rawSet(dom, k, v);
561
- });
562
- };
563
- const clone$1 = element => foldl(element.dom.attributes, (acc, attr) => {
564
- acc[attr.name] = attr.value;
565
- return acc;
566
- }, {});
567
887
 
568
- const clone = (original, isDeep) => SugarElement.fromDom(original.dom.cloneNode(isDeep));
569
- const deep = original => clone(original, true);
570
- const shallowAs = (original, tag) => {
571
- const nu = SugarElement.fromTag(tag);
572
- const attributes = clone$1(original);
573
- setAll(nu, attributes);
574
- return nu;
888
+ const ancestor$2 = (scope, selector, isRoot) => ancestor$3(scope, (e) => is$1(e, selector), isRoot);
889
+ // Returns Some(closest ancestor element (sugared)) matching 'selector' up to isRoot, or None() otherwise
890
+ const closest$1 = (scope, selector, isRoot) => {
891
+ const is = (element, selector) => is$1(element, selector);
892
+ return ClosestOrAncestor(is, ancestor$2, scope, selector, isRoot);
575
893
  };
576
- const mutate = (original, tag) => {
577
- const nu = shallowAs(original, tag);
578
- after(original, nu);
579
- const children$1 = children(original);
580
- append(nu, children$1);
581
- remove(original);
582
- return nu;
894
+
895
+ const closest = (target) => closest$1(target, '[contenteditable]');
896
+ const isEditable = (element, assumeEditable = false) => {
897
+ if (inBody(element)) {
898
+ return element.dom.isContentEditable;
899
+ }
900
+ else {
901
+ // Find the closest contenteditable element and check if it's editable
902
+ return closest(element).fold(constant(assumeEditable), (editable) => getRaw(editable) === 'true');
903
+ }
583
904
  };
905
+ const getRaw = (element) => element.dom.contentEditable;
906
+
907
+ const ancestor$1 = (scope, predicate, isRoot) => ancestor$3(scope, predicate, isRoot).isSome();
908
+
909
+ const ancestor = (element, target) => ancestor$1(element, curry(eq, target));
910
+
911
+ var global$6 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
912
+
913
+ var global$5 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
914
+
915
+ var global$4 = tinymce.util.Tools.resolve('tinymce.util.VK');
584
916
 
585
917
  var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
586
918
 
587
919
  var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools');
588
920
 
589
- const matchNodeName = name => node => isNonNullable(node) && node.nodeName.toLowerCase() === name;
590
- const matchNodeNames = regex => node => isNonNullable(node) && regex.test(node.nodeName);
591
- const isTextNode$1 = node => isNonNullable(node) && node.nodeType === 3;
592
- const isElement = node => isNonNullable(node) && node.nodeType === 1;
921
+ const matchNodeName = (name) => (node) => isNonNullable(node) && node.nodeName.toLowerCase() === name;
922
+ const matchNodeNames = (regex) => (node) => isNonNullable(node) && regex.test(node.nodeName);
923
+ const isTextNode$1 = (node) => isNonNullable(node) && node.nodeType === 3;
924
+ const isElement = (node) => isNonNullable(node) && node.nodeType === 1;
593
925
  const isListNode = matchNodeNames(/^(OL|UL|DL)$/);
594
926
  const isOlUlNode = matchNodeNames(/^(OL|UL)$/);
595
927
  const isOlNode = matchNodeName('ol');
@@ -597,1576 +929,1616 @@
597
929
  const isDlItemNode = matchNodeNames(/^(DT|DD)$/);
598
930
  const isTableCellNode = matchNodeNames(/^(TH|TD)$/);
599
931
  const isBr = matchNodeName('br');
600
- const isFirstChild = node => {
601
- var _a;
602
- return ((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === node;
603
- };
932
+ const isFirstChild = (node) => { var _a; return ((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === node; };
604
933
  const isTextBlock = (editor, node) => isNonNullable(node) && node.nodeName in editor.schema.getTextBlockElements();
605
934
  const isBlock = (node, blockElements) => isNonNullable(node) && node.nodeName in blockElements;
606
935
  const isVoid = (editor, node) => isNonNullable(node) && node.nodeName in editor.schema.getVoidElements();
607
936
  const isBogusBr = (dom, node) => {
608
- if (!isBr(node)) {
609
- return false;
610
- }
611
- return dom.isBlock(node.nextSibling) && !isBr(node.previousSibling);
937
+ if (!isBr(node)) {
938
+ return false;
939
+ }
940
+ return dom.isBlock(node.nextSibling) && !isBr(node.previousSibling);
612
941
  };
613
- const isEmpty$2 = (dom, elm, keepBookmarks) => {
614
- const empty = dom.isEmpty(elm);
615
- if (keepBookmarks && dom.select('span[data-mce-type=bookmark]', elm).length > 0) {
616
- return false;
617
- }
618
- return empty;
942
+ const isEmpty$1 = (dom, elm, keepBookmarks) => {
943
+ const empty = dom.isEmpty(elm);
944
+ if (keepBookmarks && dom.select('span[data-mce-type=bookmark]', elm).length > 0) {
945
+ return false;
946
+ }
947
+ return empty;
619
948
  };
620
949
  const isChildOfBody = (dom, elm) => dom.isChildOf(elm, dom.getRoot());
621
950
 
622
- const option = name => editor => editor.options.get(name);
623
- const register$3 = editor => {
624
- const registerOption = editor.options.register;
625
- registerOption('lists_indent_on_tab', {
626
- processor: 'boolean',
627
- default: true
628
- });
951
+ const option = (name) => (editor) => editor.options.get(name);
952
+ const register$3 = (editor) => {
953
+ const registerOption = editor.options.register;
954
+ registerOption('lists_indent_on_tab', {
955
+ processor: 'boolean',
956
+ default: true
957
+ });
629
958
  };
630
959
  const shouldIndentOnTab = option('lists_indent_on_tab');
631
960
  const getForcedRootBlock = option('forced_root_block');
632
961
  const getForcedRootBlockAttrs = option('forced_root_block_attrs');
633
962
 
634
- const createTextBlock = (editor, contentNode) => {
635
- const dom = editor.dom;
636
- const blockElements = editor.schema.getBlockElements();
637
- const fragment = dom.createFragment();
638
- const blockName = getForcedRootBlock(editor);
639
- const blockAttrs = getForcedRootBlockAttrs(editor);
640
- let node;
641
- let textBlock;
642
- let hasContentNode = false;
643
- textBlock = dom.create(blockName, blockAttrs);
644
- if (!isBlock(contentNode.firstChild, blockElements)) {
645
- fragment.appendChild(textBlock);
646
- }
647
- while (node = contentNode.firstChild) {
648
- const nodeName = node.nodeName;
649
- if (!hasContentNode && (nodeName !== 'SPAN' || node.getAttribute('data-mce-type') !== 'bookmark')) {
650
- hasContentNode = true;
651
- }
652
- if (isBlock(node, blockElements)) {
653
- fragment.appendChild(node);
654
- textBlock = null;
655
- } else {
656
- if (!textBlock) {
657
- textBlock = dom.create(blockName, blockAttrs);
963
+ const createTextBlock = (editor, contentNode, attrs = {}) => {
964
+ const dom = editor.dom;
965
+ const blockElements = editor.schema.getBlockElements();
966
+ const fragment = dom.createFragment();
967
+ const blockName = getForcedRootBlock(editor);
968
+ const blockAttrs = getForcedRootBlockAttrs(editor);
969
+ let node;
970
+ let textBlock;
971
+ let hasContentNode = false;
972
+ textBlock = dom.create(blockName, {
973
+ ...blockAttrs,
974
+ ...(attrs.style ? { style: attrs.style } : {})
975
+ });
976
+ if (!isBlock(contentNode.firstChild, blockElements)) {
658
977
  fragment.appendChild(textBlock);
659
- }
660
- textBlock.appendChild(node);
661
978
  }
662
- }
663
- if (!hasContentNode && textBlock) {
664
- textBlock.appendChild(dom.create('br', { 'data-mce-bogus': '1' }));
665
- }
666
- return fragment;
979
+ while ((node = contentNode.firstChild)) {
980
+ const nodeName = node.nodeName;
981
+ if (!hasContentNode && (nodeName !== 'SPAN' || node.getAttribute('data-mce-type') !== 'bookmark')) {
982
+ hasContentNode = true;
983
+ }
984
+ if (isBlock(node, blockElements)) {
985
+ fragment.appendChild(node);
986
+ textBlock = null;
987
+ }
988
+ else {
989
+ if (!textBlock) {
990
+ textBlock = dom.create(blockName, blockAttrs);
991
+ fragment.appendChild(textBlock);
992
+ }
993
+ textBlock.appendChild(node);
994
+ }
995
+ }
996
+ // BR is needed in empty blocks
997
+ if (!hasContentNode && textBlock) {
998
+ textBlock.appendChild(dom.create('br', { 'data-mce-bogus': '1' }));
999
+ }
1000
+ return fragment;
667
1001
  };
668
1002
 
669
1003
  const DOM$2 = global$3.DOM;
670
1004
  const splitList = (editor, list, li) => {
671
- const removeAndKeepBookmarks = targetNode => {
672
- const parent = targetNode.parentNode;
673
- if (parent) {
674
- global$2.each(bookmarks, node => {
675
- parent.insertBefore(node, li.parentNode);
676
- });
677
- }
678
- DOM$2.remove(targetNode);
679
- };
680
- const bookmarks = DOM$2.select('span[data-mce-type="bookmark"]', list);
681
- const newBlock = createTextBlock(editor, li);
682
- const tmpRng = DOM$2.createRng();
683
- tmpRng.setStartAfter(li);
684
- tmpRng.setEndAfter(list);
685
- const fragment = tmpRng.extractContents();
686
- for (let node = fragment.firstChild; node; node = node.firstChild) {
687
- if (node.nodeName === 'LI' && editor.dom.isEmpty(node)) {
688
- DOM$2.remove(node);
689
- break;
690
- }
691
- }
692
- if (!editor.dom.isEmpty(fragment)) {
693
- DOM$2.insertAfter(fragment, list);
694
- }
695
- DOM$2.insertAfter(newBlock, list);
696
- const parent = li.parentElement;
697
- if (parent && isEmpty$2(editor.dom, parent)) {
698
- removeAndKeepBookmarks(parent);
699
- }
700
- DOM$2.remove(li);
701
- if (isEmpty$2(editor.dom, list)) {
702
- DOM$2.remove(list);
703
- }
1005
+ const removeAndKeepBookmarks = (targetNode) => {
1006
+ const parent = targetNode.parentNode;
1007
+ if (parent) {
1008
+ global$2.each(bookmarks, (node) => {
1009
+ parent.insertBefore(node, li.parentNode);
1010
+ });
1011
+ }
1012
+ DOM$2.remove(targetNode);
1013
+ };
1014
+ const bookmarks = DOM$2.select('span[data-mce-type="bookmark"]', list);
1015
+ const newBlock = createTextBlock(editor, li);
1016
+ const tmpRng = DOM$2.createRng();
1017
+ tmpRng.setStartAfter(li);
1018
+ tmpRng.setEndAfter(list);
1019
+ const fragment = tmpRng.extractContents();
1020
+ for (let node = fragment.firstChild; node; node = node.firstChild) {
1021
+ if (node.nodeName === 'LI' && editor.dom.isEmpty(node)) {
1022
+ DOM$2.remove(node);
1023
+ break;
1024
+ }
1025
+ }
1026
+ if (!editor.dom.isEmpty(fragment)) {
1027
+ DOM$2.insertAfter(fragment, list);
1028
+ }
1029
+ DOM$2.insertAfter(newBlock, list);
1030
+ const parent = li.parentElement;
1031
+ if (parent && isEmpty$1(editor.dom, parent)) {
1032
+ removeAndKeepBookmarks(parent);
1033
+ }
1034
+ DOM$2.remove(li);
1035
+ if (isEmpty$1(editor.dom, list)) {
1036
+ DOM$2.remove(list);
1037
+ }
704
1038
  };
705
1039
 
706
1040
  const isDescriptionDetail = isTag('dd');
707
1041
  const isDescriptionTerm = isTag('dt');
708
1042
  const outdentDlItem = (editor, item) => {
709
- if (isDescriptionDetail(item)) {
710
- mutate(item, 'dt');
711
- } else if (isDescriptionTerm(item)) {
712
- parentElement(item).each(dl => splitList(editor, dl.dom, item.dom));
713
- }
1043
+ if (isDescriptionDetail(item)) {
1044
+ mutate(item, 'dt');
1045
+ }
1046
+ else if (isDescriptionTerm(item)) {
1047
+ parentElement(item).each((dl) => splitList(editor, dl.dom, item.dom));
1048
+ }
714
1049
  };
715
- const indentDlItem = item => {
716
- if (isDescriptionTerm(item)) {
717
- mutate(item, 'dd');
718
- }
1050
+ const indentDlItem = (item) => {
1051
+ if (isDescriptionTerm(item)) {
1052
+ mutate(item, 'dd');
1053
+ }
719
1054
  };
720
1055
  const dlIndentation = (editor, indentation, dlItems) => {
721
- if (indentation === 'Indent') {
722
- each$1(dlItems, indentDlItem);
723
- } else {
724
- each$1(dlItems, item => outdentDlItem(editor, item));
725
- }
1056
+ if (indentation === "Indent" /* Indentation.Indent */) {
1057
+ each$1(dlItems, indentDlItem);
1058
+ }
1059
+ else {
1060
+ each$1(dlItems, (item) => outdentDlItem(editor, item));
1061
+ }
726
1062
  };
727
1063
 
728
1064
  const getNormalizedPoint = (container, offset) => {
729
- if (isTextNode$1(container)) {
730
- return {
731
- container,
732
- offset
733
- };
734
- }
735
- const node = global$6.getNode(container, offset);
736
- if (isTextNode$1(node)) {
737
- return {
738
- container: node,
739
- offset: offset >= container.childNodes.length ? node.data.length : 0
740
- };
741
- } else if (node.previousSibling && isTextNode$1(node.previousSibling)) {
742
- return {
743
- container: node.previousSibling,
744
- offset: node.previousSibling.data.length
745
- };
746
- } else if (node.nextSibling && isTextNode$1(node.nextSibling)) {
747
- return {
748
- container: node.nextSibling,
749
- offset: 0
750
- };
751
- }
752
- return {
753
- container,
754
- offset
755
- };
756
- };
757
- const normalizeRange = rng => {
758
- const outRng = rng.cloneRange();
759
- const rangeStart = getNormalizedPoint(rng.startContainer, rng.startOffset);
760
- outRng.setStart(rangeStart.container, rangeStart.offset);
761
- const rangeEnd = getNormalizedPoint(rng.endContainer, rng.endOffset);
762
- outRng.setEnd(rangeEnd.container, rangeEnd.offset);
763
- return outRng;
764
- };
765
-
766
- const listNames = [
767
- 'OL',
768
- 'UL',
769
- 'DL'
770
- ];
1065
+ if (isTextNode$1(container)) {
1066
+ return { container, offset };
1067
+ }
1068
+ const node = global$6.getNode(container, offset);
1069
+ if (isTextNode$1(node)) {
1070
+ return {
1071
+ container: node,
1072
+ offset: offset >= container.childNodes.length ? node.data.length : 0
1073
+ };
1074
+ }
1075
+ else if (node.previousSibling && isTextNode$1(node.previousSibling)) {
1076
+ return {
1077
+ container: node.previousSibling,
1078
+ offset: node.previousSibling.data.length
1079
+ };
1080
+ }
1081
+ else if (node.nextSibling && isTextNode$1(node.nextSibling)) {
1082
+ return {
1083
+ container: node.nextSibling,
1084
+ offset: 0
1085
+ };
1086
+ }
1087
+ return { container, offset };
1088
+ };
1089
+ const normalizeRange = (rng) => {
1090
+ const outRng = rng.cloneRange();
1091
+ const rangeStart = getNormalizedPoint(rng.startContainer, rng.startOffset);
1092
+ outRng.setStart(rangeStart.container, rangeStart.offset);
1093
+ const rangeEnd = getNormalizedPoint(rng.endContainer, rng.endOffset);
1094
+ outRng.setEnd(rangeEnd.container, rangeEnd.offset);
1095
+ return outRng;
1096
+ };
1097
+
1098
+ const listNames = ['OL', 'UL', 'DL'];
771
1099
  const listSelector = listNames.join(',');
772
1100
  const getParentList = (editor, node) => {
773
- const selectionStart = node || editor.selection.getStart(true);
774
- return editor.dom.getParent(selectionStart, listSelector, getClosestListHost(editor, selectionStart));
1101
+ const selectionStart = node || editor.selection.getStart(true);
1102
+ return editor.dom.getParent(selectionStart, listSelector, getClosestListHost(editor, selectionStart));
775
1103
  };
776
1104
  const isParentListSelected = (parentList, selectedBlocks) => isNonNullable(parentList) && selectedBlocks.length === 1 && selectedBlocks[0] === parentList;
777
- const findSubLists = parentList => filter$1(parentList.querySelectorAll(listSelector), isListNode);
778
- const getSelectedSubLists = editor => {
779
- const parentList = getParentList(editor);
780
- const selectedBlocks = editor.selection.getSelectedBlocks();
781
- if (isParentListSelected(parentList, selectedBlocks)) {
782
- return findSubLists(parentList);
783
- } else {
784
- return filter$1(selectedBlocks, elm => {
785
- return isListNode(elm) && parentList !== elm;
786
- });
787
- }
1105
+ const findSubLists = (parentList) => filter$1(parentList.querySelectorAll(listSelector), isListNode);
1106
+ const getSelectedSubLists = (editor) => {
1107
+ const parentList = getParentList(editor);
1108
+ const selectedBlocks = editor.selection.getSelectedBlocks();
1109
+ if (isParentListSelected(parentList, selectedBlocks)) {
1110
+ return findSubLists(parentList);
1111
+ }
1112
+ else {
1113
+ return filter$1(selectedBlocks, (elm) => {
1114
+ return isListNode(elm) && parentList !== elm;
1115
+ });
1116
+ }
788
1117
  };
789
1118
  const findParentListItemsNodes = (editor, elms) => {
790
- const listItemsElms = global$2.map(elms, elm => {
791
- const parentLi = editor.dom.getParent(elm, 'li,dd,dt', getClosestListHost(editor, elm));
792
- return parentLi ? parentLi : elm;
793
- });
794
- return unique(listItemsElms);
1119
+ const listItemsElms = global$2.map(elms, (elm) => {
1120
+ const parentLi = editor.dom.getParent(elm, 'li,dd,dt', getClosestListHost(editor, elm));
1121
+ return parentLi ? parentLi : elm;
1122
+ });
1123
+ return unique(listItemsElms);
795
1124
  };
796
- const getSelectedListItems = editor => {
797
- const selectedBlocks = editor.selection.getSelectedBlocks();
798
- return filter$1(findParentListItemsNodes(editor, selectedBlocks), isListItemNode);
1125
+ const getSelectedListItems = (editor) => {
1126
+ const selectedBlocks = editor.selection.getSelectedBlocks();
1127
+ return filter$1(findParentListItemsNodes(editor, selectedBlocks), isListItemNode);
799
1128
  };
800
- const getSelectedDlItems = editor => filter$1(getSelectedListItems(editor), isDlItemNode);
1129
+ const getSelectedDlItems = (editor) => filter$1(getSelectedListItems(editor), isDlItemNode);
801
1130
  const getClosestEditingHost = (editor, elm) => {
802
- const parentTableCell = editor.dom.getParents(elm, 'TD,TH');
803
- return parentTableCell.length > 0 ? parentTableCell[0] : editor.getBody();
1131
+ const parentTableCell = editor.dom.getParents(elm, 'TD,TH');
1132
+ return parentTableCell.length > 0 ? parentTableCell[0] : editor.getBody();
804
1133
  };
805
- const isListHost = (schema, node) => !isListNode(node) && !isListItemNode(node) && exists(listNames, listName => schema.isValidChild(node.nodeName, listName));
1134
+ const isListHost = (schema, node) => !isListNode(node) && !isListItemNode(node) && exists(listNames, (listName) => schema.isValidChild(node.nodeName, listName));
806
1135
  const getClosestListHost = (editor, elm) => {
807
- const parentBlocks = editor.dom.getParents(elm, editor.dom.isBlock);
808
- const parentBlock = find(parentBlocks, elm => isListHost(editor.schema, elm));
809
- return parentBlock.getOr(editor.getBody());
810
- };
811
- const isListInsideAnLiWithFirstAndLastNotListElement = list => parent(list).exists(parent => isListItemNode(parent.dom) && firstChild(parent).exists(firstChild => !isListNode(firstChild.dom)) && lastChild(parent).exists(lastChild => !isListNode(lastChild.dom)));
1136
+ const parentBlocks = editor.dom.getParents(elm, editor.dom.isBlock);
1137
+ const isNotForcedRootBlock = (elm) => elm.nodeName.toLowerCase() !== getForcedRootBlock(editor);
1138
+ const parentBlock = find(parentBlocks, (elm) => isNotForcedRootBlock(elm) && isListHost(editor.schema, elm));
1139
+ return parentBlock.getOr(editor.getBody());
1140
+ };
1141
+ const isListInsideAnLiWithFirstAndLastNotListElement = (list) => parent(list).exists((parent) => isListItemNode(parent.dom)
1142
+ && firstChild(parent).exists((firstChild) => !isListNode(firstChild.dom))
1143
+ && lastChild(parent).exists((lastChild) => !isListNode(lastChild.dom)));
812
1144
  const findLastParentListNode = (editor, elm) => {
813
- const parentLists = editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
814
- return last(parentLists);
1145
+ const parentLists = editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
1146
+ return last(parentLists);
815
1147
  };
816
- const getSelectedLists = editor => {
817
- const firstList = findLastParentListNode(editor, editor.selection.getStart());
818
- const subsequentLists = filter$1(editor.selection.getSelectedBlocks(), isOlUlNode);
819
- return firstList.toArray().concat(subsequentLists);
1148
+ const getSelectedLists = (editor) => {
1149
+ const firstList = findLastParentListNode(editor, editor.selection.getStart());
1150
+ const subsequentLists = filter$1(editor.selection.getSelectedBlocks(), isOlUlNode);
1151
+ return firstList.toArray().concat(subsequentLists);
820
1152
  };
821
- const getParentLists = editor => {
822
- const elm = editor.selection.getStart();
823
- return editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
1153
+ const getParentLists = (editor) => {
1154
+ const elm = editor.selection.getStart();
1155
+ return editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
824
1156
  };
825
- const getSelectedListRoots = editor => {
826
- const selectedLists = getSelectedLists(editor);
827
- const parentLists = getParentLists(editor);
828
- return find(parentLists, p => isListInsideAnLiWithFirstAndLastNotListElement(SugarElement.fromDom(p))).fold(() => getUniqueListRoots(editor, selectedLists), l => [l]);
1157
+ const getSelectedListRoots = (editor) => {
1158
+ const selectedLists = getSelectedLists(editor);
1159
+ const parentLists = getParentLists(editor);
1160
+ return find(parentLists, (p) => isListInsideAnLiWithFirstAndLastNotListElement(SugarElement.fromDom(p))).fold(() => getUniqueListRoots(editor, selectedLists), (l) => [l]);
829
1161
  };
830
1162
  const getUniqueListRoots = (editor, lists) => {
831
- const listRoots = map(lists, list => findLastParentListNode(editor, list).getOr(list));
832
- return unique(listRoots);
1163
+ const listRoots = map(lists, (list) => findLastParentListNode(editor, list).getOr(list));
1164
+ return unique(listRoots);
833
1165
  };
834
1166
 
835
- const isCustomList = list => /\btox\-/.test(list.className);
836
- const inList = (parents, listName) => findUntil(parents, isListNode, isTableCellNode).exists(list => list.nodeName === listName && !isCustomList(list));
1167
+ const isCustomList = (list) => /\btox\-/.test(list.className);
1168
+ const inList = (parents, listName) => findUntil(parents, isListNode, isTableCellNode)
1169
+ .exists((list) => list.nodeName === listName && !isCustomList(list));
1170
+ // Advlist/core/ListUtils.ts - Duplicated in Advlist plugin
837
1171
  const isWithinNonEditable = (editor, element) => element !== null && !editor.dom.isEditable(element);
838
- const selectionIsWithinNonEditableList = editor => {
839
- const parentList = getParentList(editor);
840
- return isWithinNonEditable(editor, parentList);
1172
+ const selectionIsWithinNonEditableList = (editor) => {
1173
+ const parentList = getParentList(editor);
1174
+ return isWithinNonEditable(editor, parentList) || !editor.selection.isEditable();
841
1175
  };
842
1176
  const isWithinNonEditableList = (editor, element) => {
843
- const parentList = editor.dom.getParent(element, 'ol,ul,dl');
844
- return isWithinNonEditable(editor, parentList);
1177
+ const parentList = editor.dom.getParent(element, 'ol,ul,dl');
1178
+ return isWithinNonEditable(editor, parentList) || !editor.selection.isEditable();
845
1179
  };
846
1180
  const setNodeChangeHandler = (editor, nodeChangeHandler) => {
847
- const initialNode = editor.selection.getNode();
848
- nodeChangeHandler({
849
- parents: editor.dom.getParents(initialNode),
850
- element: initialNode
851
- });
852
- editor.on('NodeChange', nodeChangeHandler);
853
- return () => editor.off('NodeChange', nodeChangeHandler);
854
- };
855
-
856
- const fromElements = (elements, scope) => {
857
- const doc = scope || document;
858
- const fragment = doc.createDocumentFragment();
859
- each$1(elements, element => {
860
- fragment.appendChild(element.dom);
861
- });
862
- return SugarElement.fromDom(fragment);
863
- };
864
-
865
- const fireListEvent = (editor, action, element) => editor.dispatch('ListMutation', {
866
- action,
867
- element
868
- });
869
-
870
- const blank = r => s => s.replace(r, '');
871
- const trim = blank(/^\s+|\s+$/g);
872
- const isNotEmpty = s => s.length > 0;
873
- const isEmpty$1 = s => !isNotEmpty(s);
874
-
875
- const isSupported = dom => dom.style !== undefined && isFunction(dom.style.getPropertyValue);
876
-
877
- const internalSet = (dom, property, value) => {
878
- if (!isString(value)) {
879
- console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
880
- throw new Error('CSS value must be a string: ' + value);
881
- }
882
- if (isSupported(dom)) {
883
- dom.style.setProperty(property, value);
884
- }
885
- };
886
- const set = (element, property, value) => {
887
- const dom = element.dom;
888
- internalSet(dom, property, value);
889
- };
890
-
891
- const isList = el => is(el, 'OL,UL');
892
- const isListItem = el => is(el, 'LI');
893
- const hasFirstChildList = el => firstChild(el).exists(isList);
894
- const hasLastChildList = el => lastChild(el).exists(isList);
895
-
896
- const isEntryList = entry => 'listAttributes' in entry;
897
- const isEntryComment = entry => 'isComment' in entry;
898
- const isEntryFragment = entry => 'isFragment' in entry;
899
- const isIndented = entry => entry.depth > 0;
900
- const isSelected = entry => entry.isSelected;
901
- const cloneItemContent = li => {
902
- const children$1 = children(li);
903
- const content = hasLastChildList(li) ? children$1.slice(0, -1) : children$1;
904
- return map(content, deep);
905
- };
906
- const createEntry = (li, depth, isSelected) => parent(li).filter(isElement$1).map(list => ({
907
- depth,
908
- dirty: false,
909
- isSelected,
910
- content: cloneItemContent(li),
911
- itemAttributes: clone$1(li),
912
- listAttributes: clone$1(list),
913
- listType: name(list),
914
- isInPreviousLi: false
1181
+ const initialNode = editor.selection.getNode();
1182
+ // Set the initial state
1183
+ nodeChangeHandler({
1184
+ parents: editor.dom.getParents(initialNode),
1185
+ element: initialNode
1186
+ });
1187
+ editor.on('NodeChange', nodeChangeHandler);
1188
+ return () => editor.off('NodeChange', nodeChangeHandler);
1189
+ };
1190
+
1191
+ const fireListEvent = (editor, action, element) => editor.dispatch('ListMutation', { action, element });
1192
+
1193
+ const isList = (el) => is(el, 'OL,UL');
1194
+ const isListItem = (el) => is(el, 'LI');
1195
+ const hasFirstChildList = (el) => firstChild(el).exists(isList);
1196
+ const hasLastChildList = (el) => lastChild(el).exists(isList);
1197
+
1198
+ const isEntryList = (entry) => 'listAttributes' in entry;
1199
+ const isEntryComment = (entry) => 'isComment' in entry;
1200
+ const isEntryFragment = (entry) => 'isFragment' in entry;
1201
+ const isIndented = (entry) => entry.depth > 0;
1202
+ const isSelected = (entry) => entry.isSelected;
1203
+ const cloneItemContent = (li) => {
1204
+ const children$1 = children(li);
1205
+ const content = hasLastChildList(li) ? children$1.slice(0, -1) : children$1;
1206
+ return map(content, deep);
1207
+ };
1208
+ const createEntry = (li, depth, isSelected) => parent(li).filter(isElement$1).map((list) => ({
1209
+ depth,
1210
+ dirty: false,
1211
+ isSelected,
1212
+ content: cloneItemContent(li),
1213
+ itemAttributes: clone$1(li),
1214
+ listAttributes: clone$1(list),
1215
+ listType: name(list),
1216
+ isInPreviousLi: false
915
1217
  }));
916
1218
 
917
1219
  const joinSegment = (parent, child) => {
918
- append$1(parent.item, child.list);
1220
+ append$1(parent.item, child.list);
919
1221
  };
920
- const joinSegments = segments => {
921
- for (let i = 1; i < segments.length; i++) {
922
- joinSegment(segments[i - 1], segments[i]);
923
- }
1222
+ const joinSegments = (segments) => {
1223
+ for (let i = 1; i < segments.length; i++) {
1224
+ joinSegment(segments[i - 1], segments[i]);
1225
+ }
924
1226
  };
925
1227
  const appendSegments = (head$1, tail) => {
926
- lift2(last(head$1), head(tail), joinSegment);
1228
+ lift2(last(head$1), head(tail), joinSegment);
927
1229
  };
928
1230
  const createSegment = (scope, listType) => {
929
- const segment = {
930
- list: SugarElement.fromTag(listType, scope),
931
- item: SugarElement.fromTag('li', scope)
932
- };
933
- append$1(segment.list, segment.item);
934
- return segment;
1231
+ const segment = {
1232
+ list: SugarElement.fromTag(listType, scope),
1233
+ item: SugarElement.fromTag('li', scope)
1234
+ };
1235
+ append$1(segment.list, segment.item);
1236
+ return segment;
935
1237
  };
936
1238
  const createSegments = (scope, entry, size) => {
937
- const segments = [];
938
- for (let i = 0; i < size; i++) {
939
- segments.push(createSegment(scope, isEntryList(entry) ? entry.listType : entry.parentListType));
940
- }
941
- return segments;
1239
+ const segments = [];
1240
+ for (let i = 0; i < size; i++) {
1241
+ segments.push(createSegment(scope, isEntryList(entry) ? entry.listType : entry.parentListType));
1242
+ }
1243
+ return segments;
942
1244
  };
943
1245
  const populateSegments = (segments, entry) => {
944
- for (let i = 0; i < segments.length - 1; i++) {
945
- set(segments[i].item, 'list-style-type', 'none');
946
- }
947
- last(segments).each(segment => {
948
- if (isEntryList(entry)) {
949
- setAll(segment.list, entry.listAttributes);
950
- setAll(segment.item, entry.itemAttributes);
1246
+ for (let i = 0; i < segments.length - 1; i++) {
1247
+ set(segments[i].item, 'list-style-type', 'none');
951
1248
  }
952
- append(segment.item, entry.content);
953
- });
1249
+ last(segments).each((segment) => {
1250
+ if (isEntryList(entry)) {
1251
+ setAll(segment.list, entry.listAttributes);
1252
+ setAll(segment.item, entry.itemAttributes);
1253
+ }
1254
+ append(segment.item, entry.content);
1255
+ });
954
1256
  };
955
1257
  const normalizeSegment = (segment, entry) => {
956
- if (name(segment.list) !== entry.listType) {
957
- segment.list = mutate(segment.list, entry.listType);
958
- }
959
- setAll(segment.list, entry.listAttributes);
1258
+ if (name(segment.list) !== entry.listType) {
1259
+ segment.list = mutate(segment.list, entry.listType);
1260
+ }
1261
+ setAll(segment.list, entry.listAttributes);
960
1262
  };
961
1263
  const createItem = (scope, attr, content) => {
962
- const item = SugarElement.fromTag('li', scope);
963
- setAll(item, attr);
964
- append(item, content);
965
- return item;
1264
+ const item = SugarElement.fromTag('li', scope);
1265
+ setAll(item, attr);
1266
+ append(item, content);
1267
+ return item;
966
1268
  };
967
1269
  const appendItem = (segment, item) => {
968
- append$1(segment.list, item);
969
- segment.item = item;
1270
+ append$1(segment.list, item);
1271
+ segment.item = item;
970
1272
  };
971
1273
  const writeShallow = (scope, cast, entry) => {
972
- const newCast = cast.slice(0, entry.depth);
973
- last(newCast).each(segment => {
974
- if (isEntryList(entry)) {
975
- const item = createItem(scope, entry.itemAttributes, entry.content);
976
- appendItem(segment, item);
977
- normalizeSegment(segment, entry);
978
- } else if (isEntryFragment(entry)) {
979
- append(segment.item, entry.content);
980
- } else {
981
- const item = SugarElement.fromHtml(`<!--${ entry.content }-->`);
982
- append$1(segment.list, item);
983
- }
984
- });
985
- return newCast;
1274
+ const newCast = cast.slice(0, entry.depth);
1275
+ last(newCast).each((segment) => {
1276
+ if (isEntryList(entry)) {
1277
+ const item = createItem(scope, entry.itemAttributes, entry.content);
1278
+ appendItem(segment, item);
1279
+ normalizeSegment(segment, entry);
1280
+ }
1281
+ else if (isEntryFragment(entry)) {
1282
+ append(segment.item, entry.content);
1283
+ }
1284
+ else {
1285
+ const item = SugarElement.fromHtml(`<!--${entry.content}-->`);
1286
+ append$1(segment.list, item);
1287
+ }
1288
+ });
1289
+ return newCast;
986
1290
  };
987
1291
  const writeDeep = (scope, cast, entry) => {
988
- const segments = createSegments(scope, entry, entry.depth - cast.length);
989
- joinSegments(segments);
990
- populateSegments(segments, entry);
991
- appendSegments(cast, segments);
992
- return cast.concat(segments);
1292
+ const segments = createSegments(scope, entry, entry.depth - cast.length);
1293
+ joinSegments(segments);
1294
+ populateSegments(segments, entry);
1295
+ appendSegments(cast, segments);
1296
+ return cast.concat(segments);
993
1297
  };
994
1298
  const composeList = (scope, entries) => {
995
- let firstCommentEntryOpt = Optional.none();
996
- const cast = foldl(entries, (cast, entry, i) => {
997
- if (!isEntryComment(entry)) {
998
- return entry.depth > cast.length ? writeDeep(scope, cast, entry) : writeShallow(scope, cast, entry);
999
- } else {
1000
- if (i === 0) {
1001
- firstCommentEntryOpt = Optional.some(entry);
1002
- return cast;
1003
- }
1004
- return writeShallow(scope, cast, entry);
1005
- }
1006
- }, []);
1007
- firstCommentEntryOpt.each(firstCommentEntry => {
1008
- const item = SugarElement.fromHtml(`<!--${ firstCommentEntry.content }-->`);
1009
- head(cast).each(fistCast => {
1010
- prepend(fistCast.list, item);
1299
+ let firstCommentEntryOpt = Optional.none();
1300
+ const cast = foldl(entries, (cast, entry, i) => {
1301
+ if (!isEntryComment(entry)) {
1302
+ return entry.depth > cast.length ? writeDeep(scope, cast, entry) : writeShallow(scope, cast, entry);
1303
+ }
1304
+ else {
1305
+ // this is needed becuase if the first element of the list is a comment we would not have the data to create the new list
1306
+ if (i === 0) {
1307
+ firstCommentEntryOpt = Optional.some(entry);
1308
+ return cast;
1309
+ }
1310
+ return writeShallow(scope, cast, entry);
1311
+ }
1312
+ }, []);
1313
+ firstCommentEntryOpt.each((firstCommentEntry) => {
1314
+ const item = SugarElement.fromHtml(`<!--${firstCommentEntry.content}-->`);
1315
+ head(cast).each((fistCast) => {
1316
+ prepend(fistCast.list, item);
1317
+ });
1011
1318
  });
1012
- });
1013
- return head(cast).map(segment => segment.list);
1319
+ return head(cast).map((segment) => segment.list);
1014
1320
  };
1015
1321
 
1016
1322
  const indentEntry = (indentation, entry) => {
1017
- switch (indentation) {
1018
- case 'Indent':
1019
- entry.depth++;
1020
- break;
1021
- case 'Outdent':
1022
- entry.depth--;
1023
- break;
1024
- case 'Flatten':
1025
- entry.depth = 0;
1026
- }
1027
- entry.dirty = true;
1323
+ switch (indentation) {
1324
+ case "Indent" /* Indentation.Indent */:
1325
+ entry.depth++;
1326
+ break;
1327
+ case "Outdent" /* Indentation.Outdent */:
1328
+ entry.depth--;
1329
+ break;
1330
+ case "Flatten" /* Indentation.Flatten */:
1331
+ entry.depth = 0;
1332
+ }
1333
+ entry.dirty = true;
1028
1334
  };
1029
1335
 
1030
1336
  const cloneListProperties = (target, source) => {
1031
- if (isEntryList(target) && isEntryList(source)) {
1032
- target.listType = source.listType;
1033
- target.listAttributes = { ...source.listAttributes };
1034
- }
1337
+ if (isEntryList(target) && isEntryList(source)) {
1338
+ target.listType = source.listType;
1339
+ target.listAttributes = { ...source.listAttributes };
1340
+ }
1035
1341
  };
1036
- const cleanListProperties = entry => {
1037
- entry.listAttributes = filter(entry.listAttributes, (_value, key) => key !== 'start');
1342
+ const cleanListProperties = (entry) => {
1343
+ // Remove the start attribute if generating a new list
1344
+ entry.listAttributes = filter(entry.listAttributes, (_value, key) => key !== 'start');
1038
1345
  };
1346
+ // Closest entry above/below in the same list
1039
1347
  const closestSiblingEntry = (entries, start) => {
1040
- const depth = entries[start].depth;
1041
- const matches = entry => entry.depth === depth && !entry.dirty;
1042
- const until = entry => entry.depth < depth;
1043
- return findUntil(reverse(entries.slice(0, start)), matches, until).orThunk(() => findUntil(entries.slice(start + 1), matches, until));
1044
- };
1045
- const normalizeEntries = entries => {
1046
- each$1(entries, (entry, i) => {
1047
- closestSiblingEntry(entries, i).fold(() => {
1048
- if (entry.dirty && isEntryList(entry)) {
1049
- cleanListProperties(entry);
1050
- }
1051
- }, matchingEntry => cloneListProperties(entry, matchingEntry));
1052
- });
1053
- return entries;
1054
- };
1055
-
1056
- const Cell = initial => {
1057
- let value = initial;
1058
- const get = () => {
1059
- return value;
1060
- };
1061
- const set = v => {
1062
- value = v;
1063
- };
1064
- return {
1065
- get,
1066
- set
1067
- };
1348
+ const depth = entries[start].depth;
1349
+ // Ignore dirty items as they've been moved and won't have the right list data yet
1350
+ const matches = (entry) => entry.depth === depth && !entry.dirty;
1351
+ const until = (entry) => entry.depth < depth;
1352
+ // Check in reverse to see if there's an entry as the same depth before the current entry
1353
+ // but if not, then try to walk forwards as well
1354
+ return findUntil(reverse(entries.slice(0, start)), matches, until)
1355
+ .orThunk(() => findUntil(entries.slice(start + 1), matches, until));
1356
+ };
1357
+ const normalizeEntries = (entries) => {
1358
+ each$1(entries, (entry, i) => {
1359
+ closestSiblingEntry(entries, i).fold(() => {
1360
+ if (entry.dirty && isEntryList(entry)) {
1361
+ cleanListProperties(entry);
1362
+ }
1363
+ }, (matchingEntry) => cloneListProperties(entry, matchingEntry));
1364
+ });
1365
+ return entries;
1068
1366
  };
1069
1367
 
1070
1368
  const parseSingleItem = (depth, itemSelection, selectionState, item) => {
1071
- var _a;
1072
- if (isComment(item)) {
1073
- return [{
1074
- depth: depth + 1,
1075
- content: (_a = item.dom.nodeValue) !== null && _a !== void 0 ? _a : '',
1076
- dirty: false,
1077
- isSelected: false,
1078
- isComment: true
1079
- }];
1080
- }
1081
- itemSelection.each(selection => {
1082
- if (eq(selection.start, item)) {
1083
- selectionState.set(true);
1084
- }
1085
- });
1086
- const currentItemEntry = createEntry(item, depth, selectionState.get());
1087
- itemSelection.each(selection => {
1088
- if (eq(selection.end, item)) {
1089
- selectionState.set(false);
1090
- }
1091
- });
1092
- const childListEntries = lastChild(item).filter(isList).map(list => parseList(depth, itemSelection, selectionState, list)).getOr([]);
1093
- return currentItemEntry.toArray().concat(childListEntries);
1094
- };
1095
- const parseItem = (depth, itemSelection, selectionState, item) => firstChild(item).filter(isList).fold(() => parseSingleItem(depth, itemSelection, selectionState, item), list => {
1096
- const parsedSiblings = foldl(children(item), (acc, liChild, i) => {
1097
- if (i === 0) {
1098
- return acc;
1099
- } else {
1100
- if (isListItem(liChild)) {
1101
- return acc.concat(parseSingleItem(depth, itemSelection, selectionState, liChild));
1102
- } else {
1103
- const fragment = {
1104
- isFragment: true,
1105
- depth,
1106
- content: [liChild],
1107
- isSelected: false,
1108
- dirty: false,
1109
- parentListType: name(list)
1110
- };
1111
- return acc.concat(fragment);
1112
- }
1113
- }
1114
- }, []);
1115
- return parseList(depth, itemSelection, selectionState, list).concat(parsedSiblings);
1369
+ var _a;
1370
+ if (isComment(item)) {
1371
+ return [{
1372
+ depth: depth + 1,
1373
+ content: (_a = item.dom.nodeValue) !== null && _a !== void 0 ? _a : '',
1374
+ dirty: false,
1375
+ isSelected: false,
1376
+ isComment: true
1377
+ }];
1378
+ }
1379
+ itemSelection.each((selection) => {
1380
+ if (eq(selection.start, item)) {
1381
+ selectionState.set(true);
1382
+ }
1383
+ });
1384
+ const currentItemEntry = createEntry(item, depth, selectionState.get());
1385
+ // Update selectionState (end)
1386
+ itemSelection.each((selection) => {
1387
+ if (eq(selection.end, item)) {
1388
+ selectionState.set(false);
1389
+ }
1390
+ });
1391
+ const childListEntries = lastChild(item)
1392
+ .filter(isList)
1393
+ .map((list) => parseList(depth, itemSelection, selectionState, list))
1394
+ .getOr([]);
1395
+ return currentItemEntry.toArray().concat(childListEntries);
1396
+ };
1397
+ const parseItem = (depth, itemSelection, selectionState, item) => firstChild(item).filter(isList).fold(() => parseSingleItem(depth, itemSelection, selectionState, item), (list) => {
1398
+ const parsedSiblings = foldl(children(item), (acc, liChild, i) => {
1399
+ if (i === 0) {
1400
+ return acc;
1401
+ }
1402
+ else {
1403
+ if (isListItem(liChild)) {
1404
+ return acc.concat(parseSingleItem(depth, itemSelection, selectionState, liChild));
1405
+ }
1406
+ else {
1407
+ const fragment = {
1408
+ isFragment: true,
1409
+ depth,
1410
+ content: [liChild],
1411
+ isSelected: false,
1412
+ dirty: false,
1413
+ parentListType: name(list)
1414
+ };
1415
+ return acc.concat(fragment);
1416
+ }
1417
+ }
1418
+ }, []);
1419
+ return parseList(depth, itemSelection, selectionState, list).concat(parsedSiblings);
1116
1420
  });
1117
- const parseList = (depth, itemSelection, selectionState, list) => bind(children(list), element => {
1118
- const parser = isList(element) ? parseList : parseItem;
1119
- const newDepth = depth + 1;
1120
- return parser(newDepth, itemSelection, selectionState, element);
1421
+ const parseList = (depth, itemSelection, selectionState, list) => bind(children(list), (element) => {
1422
+ const parser = isList(element) ? parseList : parseItem;
1423
+ const newDepth = depth + 1;
1424
+ return parser(newDepth, itemSelection, selectionState, element);
1121
1425
  });
1122
1426
  const parseLists = (lists, itemSelection) => {
1123
- const selectionState = Cell(false);
1124
- const initialDepth = 0;
1125
- return map(lists, list => ({
1126
- sourceList: list,
1127
- entries: parseList(initialDepth, itemSelection, selectionState, list)
1128
- }));
1427
+ const selectionState = Cell(false);
1428
+ const initialDepth = 0;
1429
+ return map(lists, (list) => ({
1430
+ sourceList: list,
1431
+ entries: parseList(initialDepth, itemSelection, selectionState, list)
1432
+ }));
1129
1433
  };
1130
1434
 
1131
1435
  const outdentedComposer = (editor, entries) => {
1132
- const normalizedEntries = normalizeEntries(entries);
1133
- return map(normalizedEntries, entry => {
1134
- const content = !isEntryComment(entry) ? fromElements(entry.content) : fromElements([SugarElement.fromHtml(`<!--${ entry.content }-->`)]);
1135
- return SugarElement.fromDom(createTextBlock(editor, content.dom));
1136
- });
1436
+ const normalizedEntries = normalizeEntries(entries);
1437
+ return map(normalizedEntries, (entry) => {
1438
+ const content = !isEntryComment(entry)
1439
+ ? fromElements(entry.content)
1440
+ : fromElements([SugarElement.fromHtml(`<!--${entry.content}-->`)]);
1441
+ const listItemAttrs = isEntryList(entry) ? entry.itemAttributes : {};
1442
+ return SugarElement.fromDom(createTextBlock(editor, content.dom, listItemAttrs));
1443
+ });
1137
1444
  };
1138
1445
  const indentedComposer = (editor, entries) => {
1139
- const normalizedEntries = normalizeEntries(entries);
1140
- return composeList(editor.contentDocument, normalizedEntries).toArray();
1446
+ const normalizedEntries = normalizeEntries(entries);
1447
+ return composeList(editor.contentDocument, normalizedEntries).toArray();
1141
1448
  };
1142
- const composeEntries = (editor, entries) => bind(groupBy(entries, isIndented), entries => {
1143
- const groupIsIndented = head(entries).exists(isIndented);
1144
- return groupIsIndented ? indentedComposer(editor, entries) : outdentedComposer(editor, entries);
1449
+ const composeEntries = (editor, entries) => bind(groupBy(entries, isIndented), (entries) => {
1450
+ const groupIsIndented = head(entries).exists(isIndented);
1451
+ return groupIsIndented ? indentedComposer(editor, entries) : outdentedComposer(editor, entries);
1145
1452
  });
1146
1453
  const indentSelectedEntries = (entries, indentation) => {
1147
- each$1(filter$1(entries, isSelected), entry => indentEntry(indentation, entry));
1454
+ each$1(filter$1(entries, isSelected), (entry) => indentEntry(indentation, entry));
1148
1455
  };
1149
- const getItemSelection = editor => {
1150
- const selectedListItems = map(getSelectedListItems(editor), SugarElement.fromDom);
1151
- return lift2(find(selectedListItems, not(hasFirstChildList)), find(reverse(selectedListItems), not(hasFirstChildList)), (start, end) => ({
1152
- start,
1153
- end
1154
- }));
1456
+ const getItemSelection = (editor) => {
1457
+ const selectedListItems = map(getSelectedListItems(editor), SugarElement.fromDom);
1458
+ return lift2(find(selectedListItems, not(hasFirstChildList)), find(reverse(selectedListItems), not(hasFirstChildList)), (start, end) => ({ start, end }));
1155
1459
  };
1156
1460
  const listIndentation = (editor, lists, indentation) => {
1157
- const entrySets = parseLists(lists, getItemSelection(editor));
1158
- each$1(entrySets, entrySet => {
1159
- indentSelectedEntries(entrySet.entries, indentation);
1160
- const composedLists = composeEntries(editor, entrySet.entries);
1161
- each$1(composedLists, composedList => {
1162
- fireListEvent(editor, indentation === 'Indent' ? 'IndentList' : 'OutdentList', composedList.dom);
1461
+ const entrySets = parseLists(lists, getItemSelection(editor));
1462
+ each$1(entrySets, (entrySet) => {
1463
+ indentSelectedEntries(entrySet.entries, indentation);
1464
+ const composedLists = composeEntries(editor, entrySet.entries);
1465
+ each$1(composedLists, (composedList) => {
1466
+ fireListEvent(editor, indentation === "Indent" /* Indentation.Indent */ ? "IndentList" /* ListAction.IndentList */ : "OutdentList" /* ListAction.OutdentList */, composedList.dom);
1467
+ });
1468
+ before(entrySet.sourceList, composedLists);
1469
+ remove(entrySet.sourceList);
1163
1470
  });
1164
- before(entrySet.sourceList, composedLists);
1165
- remove(entrySet.sourceList);
1166
- });
1167
1471
  };
1168
1472
 
1169
1473
  const selectionIndentation = (editor, indentation) => {
1170
- const lists = fromDom(getSelectedListRoots(editor));
1171
- const dlItems = fromDom(getSelectedDlItems(editor));
1172
- let isHandled = false;
1173
- if (lists.length || dlItems.length) {
1174
- const bookmark = editor.selection.getBookmark();
1175
- listIndentation(editor, lists, indentation);
1176
- dlIndentation(editor, indentation, dlItems);
1177
- editor.selection.moveToBookmark(bookmark);
1178
- editor.selection.setRng(normalizeRange(editor.selection.getRng()));
1179
- editor.nodeChanged();
1180
- isHandled = true;
1181
- }
1182
- return isHandled;
1474
+ const lists = fromDom(getSelectedListRoots(editor));
1475
+ const dlItems = fromDom(getSelectedDlItems(editor));
1476
+ let isHandled = false;
1477
+ if (lists.length || dlItems.length) {
1478
+ const bookmark = editor.selection.getBookmark();
1479
+ listIndentation(editor, lists, indentation);
1480
+ dlIndentation(editor, indentation, dlItems);
1481
+ editor.selection.moveToBookmark(bookmark);
1482
+ editor.selection.setRng(normalizeRange(editor.selection.getRng()));
1483
+ editor.nodeChanged();
1484
+ isHandled = true;
1485
+ }
1486
+ return isHandled;
1183
1487
  };
1184
1488
  const handleIndentation = (editor, indentation) => !selectionIsWithinNonEditableList(editor) && selectionIndentation(editor, indentation);
1185
- const indentListSelection = editor => handleIndentation(editor, 'Indent');
1186
- const outdentListSelection = editor => handleIndentation(editor, 'Outdent');
1187
- const flattenListSelection = editor => handleIndentation(editor, 'Flatten');
1188
-
1189
- const zeroWidth = '\uFEFF';
1190
- const isZwsp = char => char === zeroWidth;
1191
-
1192
- const ancestor$1 = (scope, predicate, isRoot) => ancestor$3(scope, predicate, isRoot).isSome();
1193
-
1194
- const ancestor = (element, target) => ancestor$1(element, curry(eq, target));
1489
+ const indentListSelection = (editor) => handleIndentation(editor, "Indent" /* Indentation.Indent */);
1490
+ const outdentListSelection = (editor) => handleIndentation(editor, "Outdent" /* Indentation.Outdent */);
1491
+ const flattenListSelection = (editor) => handleIndentation(editor, "Flatten" /* Indentation.Flatten */);
1195
1492
 
1196
1493
  var global$1 = tinymce.util.Tools.resolve('tinymce.dom.BookmarkManager');
1197
1494
 
1198
1495
  const DOM$1 = global$3.DOM;
1199
- const createBookmark = rng => {
1200
- const bookmark = {};
1201
- const setupEndPoint = start => {
1202
- let container = rng[start ? 'startContainer' : 'endContainer'];
1203
- let offset = rng[start ? 'startOffset' : 'endOffset'];
1204
- if (isElement(container)) {
1205
- const offsetNode = DOM$1.create('span', { 'data-mce-type': 'bookmark' });
1206
- if (container.hasChildNodes()) {
1207
- offset = Math.min(offset, container.childNodes.length - 1);
1208
- if (start) {
1209
- container.insertBefore(offsetNode, container.childNodes[offset]);
1210
- } else {
1211
- DOM$1.insertAfter(offsetNode, container.childNodes[offset]);
1212
- }
1213
- } else {
1214
- container.appendChild(offsetNode);
1215
- }
1216
- container = offsetNode;
1217
- offset = 0;
1218
- }
1219
- bookmark[start ? 'startContainer' : 'endContainer'] = container;
1220
- bookmark[start ? 'startOffset' : 'endOffset'] = offset;
1221
- };
1222
- setupEndPoint(true);
1223
- if (!rng.collapsed) {
1224
- setupEndPoint();
1225
- }
1226
- return bookmark;
1227
- };
1228
- const resolveBookmark = bookmark => {
1229
- const restoreEndPoint = start => {
1230
- const nodeIndex = container => {
1231
- var _a;
1232
- let node = (_a = container.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild;
1233
- let idx = 0;
1234
- while (node) {
1235
- if (node === container) {
1236
- return idx;
1237
- }
1238
- if (!isElement(node) || node.getAttribute('data-mce-type') !== 'bookmark') {
1239
- idx++;
1240
- }
1241
- node = node.nextSibling;
1242
- }
1243
- return -1;
1496
+ /**
1497
+ * Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with
1498
+ * index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans
1499
+ * added to them since they can be restored after a dom operation.
1500
+ *
1501
+ * So this: <p><b>|</b><b>|</b></p>
1502
+ * becomes: <p><b><span data-mce-type="bookmark">|</span></b><b data-mce-type="bookmark">|</span></b></p>
1503
+ *
1504
+ * @param {DOMRange} rng DOM Range to get bookmark on.
1505
+ * @return {Object} Bookmark object.
1506
+ */
1507
+ const createBookmark = (rng) => {
1508
+ const bookmark = {};
1509
+ const setupEndPoint = (start) => {
1510
+ let container = rng[start ? 'startContainer' : 'endContainer'];
1511
+ let offset = rng[start ? 'startOffset' : 'endOffset'];
1512
+ if (isElement(container)) {
1513
+ const offsetNode = DOM$1.create('span', { 'data-mce-type': 'bookmark' });
1514
+ if (container.hasChildNodes()) {
1515
+ offset = Math.min(offset, container.childNodes.length - 1);
1516
+ if (start) {
1517
+ container.insertBefore(offsetNode, container.childNodes[offset]);
1518
+ }
1519
+ else {
1520
+ DOM$1.insertAfter(offsetNode, container.childNodes[offset]);
1521
+ }
1522
+ }
1523
+ else {
1524
+ container.appendChild(offsetNode);
1525
+ }
1526
+ container = offsetNode;
1527
+ offset = 0;
1528
+ }
1529
+ bookmark[start ? 'startContainer' : 'endContainer'] = container;
1530
+ bookmark[start ? 'startOffset' : 'endOffset'] = offset;
1244
1531
  };
1245
- let container = bookmark[start ? 'startContainer' : 'endContainer'];
1246
- let offset = bookmark[start ? 'startOffset' : 'endOffset'];
1247
- if (!container) {
1248
- return;
1249
- }
1250
- if (isElement(container) && container.parentNode) {
1251
- const node = container;
1252
- offset = nodeIndex(container);
1253
- container = container.parentNode;
1254
- DOM$1.remove(node);
1255
- if (!container.hasChildNodes() && DOM$1.isBlock(container)) {
1256
- container.appendChild(DOM$1.create('br'));
1257
- }
1258
- }
1259
- bookmark[start ? 'startContainer' : 'endContainer'] = container;
1260
- bookmark[start ? 'startOffset' : 'endOffset'] = offset;
1261
- };
1262
- restoreEndPoint(true);
1263
- restoreEndPoint();
1264
- const rng = DOM$1.createRng();
1265
- rng.setStart(bookmark.startContainer, bookmark.startOffset);
1266
- if (bookmark.endContainer) {
1267
- rng.setEnd(bookmark.endContainer, bookmark.endOffset);
1268
- }
1269
- return normalizeRange(rng);
1270
- };
1271
-
1272
- const listToggleActionFromListName = listName => {
1273
- switch (listName) {
1274
- case 'UL':
1275
- return 'ToggleUlList';
1276
- case 'OL':
1277
- return 'ToggleOlList';
1278
- case 'DL':
1279
- return 'ToggleDLList';
1280
- }
1532
+ setupEndPoint(true);
1533
+ if (!rng.collapsed) {
1534
+ setupEndPoint();
1535
+ }
1536
+ return bookmark;
1537
+ };
1538
+ const resolveBookmark = (bookmark) => {
1539
+ const restoreEndPoint = (start) => {
1540
+ const nodeIndex = (container) => {
1541
+ var _a;
1542
+ let node = (_a = container.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild;
1543
+ let idx = 0;
1544
+ while (node) {
1545
+ if (node === container) {
1546
+ return idx;
1547
+ }
1548
+ // Skip data-mce-type=bookmark nodes
1549
+ if (!isElement(node) || node.getAttribute('data-mce-type') !== 'bookmark') {
1550
+ idx++;
1551
+ }
1552
+ node = node.nextSibling;
1553
+ }
1554
+ return -1;
1555
+ };
1556
+ let container = bookmark[start ? 'startContainer' : 'endContainer'];
1557
+ let offset = bookmark[start ? 'startOffset' : 'endOffset'];
1558
+ if (!container) {
1559
+ return;
1560
+ }
1561
+ if (isElement(container) && container.parentNode) {
1562
+ const node = container;
1563
+ offset = nodeIndex(container);
1564
+ container = container.parentNode;
1565
+ DOM$1.remove(node);
1566
+ if (!container.hasChildNodes() && DOM$1.isBlock(container)) {
1567
+ container.appendChild(DOM$1.create('br'));
1568
+ }
1569
+ }
1570
+ bookmark[start ? 'startContainer' : 'endContainer'] = container;
1571
+ bookmark[start ? 'startOffset' : 'endOffset'] = offset;
1572
+ };
1573
+ restoreEndPoint(true);
1574
+ restoreEndPoint();
1575
+ const rng = DOM$1.createRng();
1576
+ rng.setStart(bookmark.startContainer, bookmark.startOffset);
1577
+ if (bookmark.endContainer) {
1578
+ rng.setEnd(bookmark.endContainer, bookmark.endOffset);
1579
+ }
1580
+ return normalizeRange(rng);
1581
+ };
1582
+
1583
+ const listToggleActionFromListName = (listName) => {
1584
+ switch (listName) {
1585
+ case 'UL': return "ToggleUlList" /* ListAction.ToggleUlList */;
1586
+ case 'OL': return "ToggleOlList" /* ListAction.ToggleOlList */;
1587
+ case 'DL': return "ToggleDLList" /* ListAction.ToggleDLList */;
1588
+ }
1281
1589
  };
1282
1590
 
1283
1591
  const updateListStyle = (dom, el, detail) => {
1284
- const type = detail['list-style-type'] ? detail['list-style-type'] : null;
1285
- dom.setStyle(el, 'list-style-type', type);
1592
+ const type = detail['list-style-type'] ? detail['list-style-type'] : null;
1593
+ dom.setStyle(el, 'list-style-type', type);
1286
1594
  };
1287
1595
  const setAttribs = (elm, attrs) => {
1288
- global$2.each(attrs, (value, key) => {
1289
- elm.setAttribute(key, value);
1290
- });
1596
+ global$2.each(attrs, (value, key) => {
1597
+ elm.setAttribute(key, value);
1598
+ });
1291
1599
  };
1292
1600
  const updateListAttrs = (dom, el, detail) => {
1293
- setAttribs(el, detail['list-attributes']);
1294
- global$2.each(dom.select('li', el), li => {
1295
- setAttribs(li, detail['list-item-attributes']);
1296
- });
1601
+ setAttribs(el, detail['list-attributes']);
1602
+ global$2.each(dom.select('li', el), (li) => {
1603
+ setAttribs(li, detail['list-item-attributes']);
1604
+ });
1297
1605
  };
1298
1606
  const updateListWithDetails = (dom, el, detail) => {
1299
- updateListStyle(dom, el, detail);
1300
- updateListAttrs(dom, el, detail);
1607
+ updateListStyle(dom, el, detail);
1608
+ updateListAttrs(dom, el, detail);
1301
1609
  };
1302
1610
  const removeStyles = (dom, element, styles) => {
1303
- global$2.each(styles, style => dom.setStyle(element, style, ''));
1611
+ global$2.each(styles, (style) => dom.setStyle(element, style, ''));
1304
1612
  };
1305
1613
  const isInline = (editor, node) => isNonNullable(node) && !isBlock(node, editor.schema.getBlockElements());
1306
1614
  const getEndPointNode = (editor, rng, start, root) => {
1307
- let container = rng[start ? 'startContainer' : 'endContainer'];
1308
- const offset = rng[start ? 'startOffset' : 'endOffset'];
1309
- if (isElement(container)) {
1310
- container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
1311
- }
1312
- if (!start && isBr(container.nextSibling)) {
1313
- container = container.nextSibling;
1314
- }
1315
- const findBlockAncestor = node => {
1316
- while (!editor.dom.isBlock(node) && node.parentNode && root !== node) {
1317
- node = node.parentNode;
1318
- }
1319
- return node;
1320
- };
1321
- const findBetterContainer = (container, forward) => {
1322
- var _a;
1323
- const walker = new global$5(container, findBlockAncestor(container));
1324
- const dir = forward ? 'next' : 'prev';
1325
- let node;
1326
- while (node = walker[dir]()) {
1327
- if (!(isVoid(editor, node) || isZwsp(node.textContent) || ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) === 0)) {
1328
- return Optional.some(node);
1329
- }
1615
+ let container = rng[start ? 'startContainer' : 'endContainer'];
1616
+ const offset = rng[start ? 'startOffset' : 'endOffset'];
1617
+ // Resolve node index
1618
+ if (isElement(container)) {
1619
+ container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
1330
1620
  }
1331
- return Optional.none();
1332
- };
1333
- if (start && isTextNode$1(container)) {
1334
- if (isZwsp(container.textContent)) {
1335
- container = findBetterContainer(container, false).getOr(container);
1336
- } else {
1337
- if (container.parentNode !== null && isInline(editor, container.parentNode)) {
1338
- container = container.parentNode;
1339
- }
1340
- while (container.previousSibling !== null && (isInline(editor, container.previousSibling) || isTextNode$1(container.previousSibling))) {
1341
- container = container.previousSibling;
1342
- }
1343
- }
1344
- }
1345
- if (!start && isTextNode$1(container)) {
1346
- if (isZwsp(container.textContent)) {
1347
- container = findBetterContainer(container, true).getOr(container);
1348
- } else {
1349
- if (container.parentNode !== null && isInline(editor, container.parentNode)) {
1350
- container = container.parentNode;
1351
- }
1352
- while (container.nextSibling !== null && (isInline(editor, container.nextSibling) || isTextNode$1(container.nextSibling))) {
1621
+ if (!start && isBr(container.nextSibling)) {
1353
1622
  container = container.nextSibling;
1354
- }
1355
1623
  }
1356
- }
1357
- while (container.parentNode !== root) {
1358
- const parent = container.parentNode;
1359
- if (isTextBlock(editor, container)) {
1360
- return container;
1624
+ const findBlockAncestor = (node) => {
1625
+ while (!editor.dom.isBlock(node) && node.parentNode && root !== node) {
1626
+ node = node.parentNode;
1627
+ }
1628
+ return node;
1629
+ };
1630
+ // The reason why the next two if statements exist is because when the root node is a table cell (possibly some other node types)
1631
+ // then the highest we can go up the dom hierarchy is one level below the table cell.
1632
+ // So what happens when we have a bunch of inline nodes and text nodes in the table cell
1633
+ // and when the selection is collapsed inside one of the inline nodes then only that inline node (or text node) will be included
1634
+ // in the created list because that would be one level below td node and the other inline nodes won't be included.
1635
+ // So the fix proposed is to traverse left when looking for start node (and traverse right when looking for end node)
1636
+ // and keep traversing as long as we have an inline or text node (same for traversing right).
1637
+ // This way we end up including all the inline elements in the created list.
1638
+ // For more info look at #TINY-6853
1639
+ const findBetterContainer = (container, forward) => {
1640
+ var _a;
1641
+ const walker = new global$5(container, findBlockAncestor(container));
1642
+ const dir = forward ? 'next' : 'prev';
1643
+ let node;
1644
+ while ((node = walker[dir]())) {
1645
+ if (!(isVoid(editor, node) || isZwsp(node.textContent) || ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) === 0)) {
1646
+ return Optional.some(node);
1647
+ }
1648
+ }
1649
+ return Optional.none();
1650
+ };
1651
+ // Traverse left to include inline/text nodes
1652
+ if (start && isTextNode$1(container)) {
1653
+ if (isZwsp(container.textContent)) {
1654
+ container = findBetterContainer(container, false).getOr(container);
1655
+ }
1656
+ else {
1657
+ if (container.parentNode !== null && isInline(editor, container.parentNode)) {
1658
+ container = container.parentNode;
1659
+ }
1660
+ while (container.previousSibling !== null && (isInline(editor, container.previousSibling) || isTextNode$1(container.previousSibling))) {
1661
+ container = container.previousSibling;
1662
+ }
1663
+ }
1664
+ }
1665
+ // Traverse right to include inline/text nodes
1666
+ if (!start && isTextNode$1(container)) {
1667
+ if (isZwsp(container.textContent)) {
1668
+ container = findBetterContainer(container, true).getOr(container);
1669
+ }
1670
+ else {
1671
+ if (container.parentNode !== null && isInline(editor, container.parentNode)) {
1672
+ container = container.parentNode;
1673
+ }
1674
+ while (container.nextSibling !== null && (isInline(editor, container.nextSibling) || isTextNode$1(container.nextSibling))) {
1675
+ container = container.nextSibling;
1676
+ }
1677
+ }
1361
1678
  }
1362
- if (/^(TD|TH)$/.test(parent.nodeName)) {
1363
- return container;
1679
+ while (container.parentNode !== root) {
1680
+ const parent = container.parentNode;
1681
+ if (isTextBlock(editor, container)) {
1682
+ return container;
1683
+ }
1684
+ if (/^(TD|TH)$/.test(parent.nodeName)) {
1685
+ return container;
1686
+ }
1687
+ container = parent;
1364
1688
  }
1365
- container = parent;
1366
- }
1367
- return container;
1689
+ return container;
1368
1690
  };
1369
1691
  const getSelectedTextBlocks = (editor, rng, root) => {
1370
- const textBlocks = [];
1371
- const dom = editor.dom;
1372
- const startNode = getEndPointNode(editor, rng, true, root);
1373
- const endNode = getEndPointNode(editor, rng, false, root);
1374
- let block;
1375
- const siblings = [];
1376
- for (let node = startNode; node; node = node.nextSibling) {
1377
- siblings.push(node);
1378
- if (node === endNode) {
1379
- break;
1380
- }
1381
- }
1382
- global$2.each(siblings, node => {
1383
- var _a;
1384
- if (isTextBlock(editor, node)) {
1385
- textBlocks.push(node);
1386
- block = null;
1387
- return;
1388
- }
1389
- if (dom.isBlock(node) || isBr(node)) {
1390
- if (isBr(node)) {
1391
- dom.remove(node);
1392
- }
1393
- block = null;
1394
- return;
1395
- }
1396
- const nextSibling = node.nextSibling;
1397
- if (global$1.isBookmarkNode(node)) {
1398
- if (isListNode(nextSibling) || isTextBlock(editor, nextSibling) || !nextSibling && node.parentNode === root) {
1399
- block = null;
1400
- return;
1401
- }
1402
- }
1403
- if (!block) {
1404
- block = dom.create('p');
1405
- (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(block, node);
1406
- textBlocks.push(block);
1692
+ const textBlocks = [];
1693
+ const dom = editor.dom;
1694
+ const startNode = getEndPointNode(editor, rng, true, root);
1695
+ const endNode = getEndPointNode(editor, rng, false, root);
1696
+ let block;
1697
+ const siblings = [];
1698
+ for (let node = startNode; node; node = node.nextSibling) {
1699
+ siblings.push(node);
1700
+ if (node === endNode) {
1701
+ break;
1702
+ }
1407
1703
  }
1408
- block.appendChild(node);
1409
- });
1410
- return textBlocks;
1704
+ global$2.each(siblings, (node) => {
1705
+ var _a;
1706
+ if (isTextBlock(editor, node)) {
1707
+ textBlocks.push(node);
1708
+ block = null;
1709
+ return;
1710
+ }
1711
+ if (dom.isBlock(node) || isBr(node)) {
1712
+ if (isBr(node)) {
1713
+ dom.remove(node);
1714
+ }
1715
+ block = null;
1716
+ return;
1717
+ }
1718
+ const nextSibling = node.nextSibling;
1719
+ if (global$1.isBookmarkNode(node)) {
1720
+ if (isListNode(nextSibling) || isTextBlock(editor, nextSibling) || (!nextSibling && node.parentNode === root)) {
1721
+ block = null;
1722
+ return;
1723
+ }
1724
+ }
1725
+ if (!block) {
1726
+ block = dom.create('p');
1727
+ (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(block, node);
1728
+ textBlocks.push(block);
1729
+ }
1730
+ block.appendChild(node);
1731
+ });
1732
+ return textBlocks;
1411
1733
  };
1412
1734
  const hasCompatibleStyle = (dom, sib, detail) => {
1413
- const sibStyle = dom.getStyle(sib, 'list-style-type');
1414
- let detailStyle = detail ? detail['list-style-type'] : '';
1415
- detailStyle = detailStyle === null ? '' : detailStyle;
1416
- return sibStyle === detailStyle;
1417
- };
1735
+ const sibStyle = dom.getStyle(sib, 'list-style-type');
1736
+ let detailStyle = detail ? detail['list-style-type'] : '';
1737
+ detailStyle = detailStyle === null ? '' : detailStyle;
1738
+ return sibStyle === detailStyle;
1739
+ };
1740
+ /*
1741
+ Find the first element we would transform into a li-element if given no constraints.
1742
+ If the common ancestor is higher up than that provide it as the starting-point for the search for the root instead of the first selected element.
1743
+ This helps avoid issues with divs that should become li-elements are detected as the root when they should not be.
1744
+ */
1418
1745
  const getRootSearchStart = (editor, range) => {
1419
- const start = editor.selection.getStart(true);
1420
- const startPoint = getEndPointNode(editor, range, true, editor.getBody());
1421
- if (ancestor(SugarElement.fromDom(startPoint), SugarElement.fromDom(range.commonAncestorContainer))) {
1422
- return range.commonAncestorContainer;
1423
- } else {
1424
- return start;
1425
- }
1746
+ const start = editor.selection.getStart(true);
1747
+ const startPoint = getEndPointNode(editor, range, true, editor.getBody());
1748
+ if (ancestor(SugarElement.fromDom(startPoint), SugarElement.fromDom(range.commonAncestorContainer))) {
1749
+ return range.commonAncestorContainer;
1750
+ }
1751
+ else {
1752
+ return start;
1753
+ }
1426
1754
  };
1427
1755
  const applyList = (editor, listName, detail) => {
1428
- const rng = editor.selection.getRng();
1429
- let listItemName = 'LI';
1430
- const root = getClosestListHost(editor, getRootSearchStart(editor, rng));
1431
- const dom = editor.dom;
1432
- if (dom.getContentEditable(editor.selection.getNode()) === 'false') {
1433
- return;
1434
- }
1435
- listName = listName.toUpperCase();
1436
- if (listName === 'DL') {
1437
- listItemName = 'DT';
1438
- }
1439
- const bookmark = createBookmark(rng);
1440
- const selectedTextBlocks = filter$1(getSelectedTextBlocks(editor, rng, root), editor.dom.isEditable);
1441
- global$2.each(selectedTextBlocks, block => {
1442
- let listBlock;
1443
- const sibling = block.previousSibling;
1444
- const parent = block.parentNode;
1445
- if (!isListItemNode(parent)) {
1446
- if (sibling && isListNode(sibling) && sibling.nodeName === listName && hasCompatibleStyle(dom, sibling, detail)) {
1447
- listBlock = sibling;
1448
- block = dom.rename(block, listItemName);
1449
- sibling.appendChild(block);
1450
- } else {
1451
- listBlock = dom.create(listName);
1452
- parent.insertBefore(listBlock, block);
1453
- listBlock.appendChild(block);
1454
- block = dom.rename(block, listItemName);
1455
- }
1456
- removeStyles(dom, block, [
1457
- 'margin',
1458
- 'margin-right',
1459
- 'margin-bottom',
1460
- 'margin-left',
1461
- 'margin-top',
1462
- 'padding',
1463
- 'padding-right',
1464
- 'padding-bottom',
1465
- 'padding-left',
1466
- 'padding-top'
1467
- ]);
1468
- updateListWithDetails(dom, listBlock, detail);
1469
- mergeWithAdjacentLists(editor.dom, listBlock);
1470
- }
1471
- });
1472
- editor.selection.setRng(resolveBookmark(bookmark));
1756
+ const rng = editor.selection.getRng();
1757
+ let listItemName = 'LI';
1758
+ const root = getClosestListHost(editor, getRootSearchStart(editor, rng));
1759
+ const dom = editor.dom;
1760
+ if (dom.getContentEditable(editor.selection.getNode()) === 'false') {
1761
+ return;
1762
+ }
1763
+ listName = listName.toUpperCase();
1764
+ if (listName === 'DL') {
1765
+ listItemName = 'DT';
1766
+ }
1767
+ const bookmark = createBookmark(rng);
1768
+ const selectedTextBlocks = filter$1(getSelectedTextBlocks(editor, rng, root), editor.dom.isEditable);
1769
+ global$2.each(selectedTextBlocks, (block) => {
1770
+ let listBlock;
1771
+ const sibling = block.previousSibling;
1772
+ const parent = block.parentNode;
1773
+ if (!isListItemNode(parent)) {
1774
+ if (sibling && isListNode(sibling) && sibling.nodeName === listName && hasCompatibleStyle(dom, sibling, detail)) {
1775
+ listBlock = sibling;
1776
+ block = dom.rename(block, listItemName);
1777
+ sibling.appendChild(block);
1778
+ }
1779
+ else {
1780
+ listBlock = dom.create(listName);
1781
+ parent.insertBefore(listBlock, block);
1782
+ listBlock.appendChild(block);
1783
+ block = dom.rename(block, listItemName);
1784
+ }
1785
+ removeStyles(dom, block, [
1786
+ 'margin', 'margin-right', 'margin-bottom', 'margin-left', 'margin-top',
1787
+ 'padding', 'padding-right', 'padding-bottom', 'padding-left', 'padding-top'
1788
+ ]);
1789
+ updateListWithDetails(dom, listBlock, detail);
1790
+ mergeWithAdjacentLists(editor.dom, listBlock);
1791
+ }
1792
+ });
1793
+ editor.selection.setRng(resolveBookmark(bookmark));
1473
1794
  };
1474
1795
  const isValidLists = (list1, list2) => {
1475
- return isListNode(list1) && list1.nodeName === (list2 === null || list2 === void 0 ? void 0 : list2.nodeName);
1796
+ return isListNode(list1) && list1.nodeName === (list2 === null || list2 === void 0 ? void 0 : list2.nodeName);
1476
1797
  };
1477
1798
  const hasSameListStyle = (dom, list1, list2) => {
1478
- const targetStyle = dom.getStyle(list1, 'list-style-type', true);
1479
- const style = dom.getStyle(list2, 'list-style-type', true);
1480
- return targetStyle === style;
1799
+ const targetStyle = dom.getStyle(list1, 'list-style-type', true);
1800
+ const style = dom.getStyle(list2, 'list-style-type', true);
1801
+ return targetStyle === style;
1481
1802
  };
1482
1803
  const hasSameClasses = (elm1, elm2) => {
1483
- return elm1.className === elm2.className;
1804
+ return elm1.className === elm2.className;
1484
1805
  };
1485
1806
  const shouldMerge = (dom, list1, list2) => {
1486
- return isValidLists(list1, list2) && hasSameListStyle(dom, list1, list2) && hasSameClasses(list1, list2);
1807
+ return isValidLists(list1, list2) &&
1808
+ // Note: isValidLists will ensure list1 and list2 are a HTMLElement. Unfortunately TypeScript doesn't
1809
+ // support type guards on multiple variables. See https://github.com/microsoft/TypeScript/issues/26916
1810
+ hasSameListStyle(dom, list1, list2) &&
1811
+ hasSameClasses(list1, list2);
1487
1812
  };
1488
1813
  const mergeWithAdjacentLists = (dom, listBlock) => {
1489
- let node;
1490
- let sibling = listBlock.nextSibling;
1491
- if (shouldMerge(dom, listBlock, sibling)) {
1492
- const liSibling = sibling;
1493
- while (node = liSibling.firstChild) {
1494
- listBlock.appendChild(node);
1495
- }
1496
- dom.remove(liSibling);
1497
- }
1498
- sibling = listBlock.previousSibling;
1499
- if (shouldMerge(dom, listBlock, sibling)) {
1500
- const liSibling = sibling;
1501
- while (node = liSibling.lastChild) {
1502
- listBlock.insertBefore(node, listBlock.firstChild);
1503
- }
1504
- dom.remove(liSibling);
1505
- }
1814
+ let node;
1815
+ let sibling = listBlock.nextSibling;
1816
+ if (shouldMerge(dom, listBlock, sibling)) {
1817
+ const liSibling = sibling;
1818
+ while ((node = liSibling.firstChild)) {
1819
+ listBlock.appendChild(node);
1820
+ }
1821
+ dom.remove(liSibling);
1822
+ }
1823
+ sibling = listBlock.previousSibling;
1824
+ if (shouldMerge(dom, listBlock, sibling)) {
1825
+ const liSibling = sibling;
1826
+ while ((node = liSibling.lastChild)) {
1827
+ listBlock.insertBefore(node, listBlock.firstChild);
1828
+ }
1829
+ dom.remove(liSibling);
1830
+ }
1506
1831
  };
1507
1832
  const updateList$1 = (editor, list, listName, detail) => {
1508
- if (list.nodeName !== listName) {
1509
- const newList = editor.dom.rename(list, listName);
1510
- updateListWithDetails(editor.dom, newList, detail);
1511
- fireListEvent(editor, listToggleActionFromListName(listName), newList);
1512
- } else {
1513
- updateListWithDetails(editor.dom, list, detail);
1514
- fireListEvent(editor, listToggleActionFromListName(listName), list);
1515
- }
1833
+ if (list.nodeName !== listName) {
1834
+ const newList = editor.dom.rename(list, listName);
1835
+ updateListWithDetails(editor.dom, newList, detail);
1836
+ fireListEvent(editor, listToggleActionFromListName(listName), newList);
1837
+ }
1838
+ else {
1839
+ updateListWithDetails(editor.dom, list, detail);
1840
+ fireListEvent(editor, listToggleActionFromListName(listName), list);
1841
+ }
1516
1842
  };
1517
1843
  const updateCustomList = (editor, list, listName, detail) => {
1518
- list.classList.forEach((cls, _, classList) => {
1519
- if (cls.startsWith('tox-')) {
1520
- classList.remove(cls);
1521
- if (classList.length === 0) {
1522
- list.removeAttribute('class');
1523
- }
1524
- }
1525
- });
1526
- if (list.nodeName !== listName) {
1527
- const newList = editor.dom.rename(list, listName);
1528
- updateListWithDetails(editor.dom, newList, detail);
1529
- fireListEvent(editor, listToggleActionFromListName(listName), newList);
1530
- } else {
1531
- updateListWithDetails(editor.dom, list, detail);
1532
- fireListEvent(editor, listToggleActionFromListName(listName), list);
1533
- }
1844
+ list.classList.forEach((cls, _, classList) => {
1845
+ if (cls.startsWith('tox-')) {
1846
+ classList.remove(cls);
1847
+ if (classList.length === 0) {
1848
+ list.removeAttribute('class');
1849
+ }
1850
+ }
1851
+ });
1852
+ if (list.nodeName !== listName) {
1853
+ const newList = editor.dom.rename(list, listName);
1854
+ updateListWithDetails(editor.dom, newList, detail);
1855
+ fireListEvent(editor, listToggleActionFromListName(listName), newList);
1856
+ }
1857
+ else {
1858
+ updateListWithDetails(editor.dom, list, detail);
1859
+ fireListEvent(editor, listToggleActionFromListName(listName), list);
1860
+ }
1534
1861
  };
1535
1862
  const toggleMultipleLists = (editor, parentList, lists, listName, detail) => {
1536
- const parentIsList = isListNode(parentList);
1537
- if (parentIsList && parentList.nodeName === listName && !hasListStyleDetail(detail) && !isCustomList(parentList)) {
1538
- flattenListSelection(editor);
1539
- } else {
1540
- applyList(editor, listName, detail);
1541
- const bookmark = createBookmark(editor.selection.getRng());
1542
- const allLists = parentIsList ? [
1543
- parentList,
1544
- ...lists
1545
- ] : lists;
1546
- const updateFunction = parentIsList && isCustomList(parentList) ? updateCustomList : updateList$1;
1547
- global$2.each(allLists, elm => {
1548
- updateFunction(editor, elm, listName, detail);
1549
- });
1550
- editor.selection.setRng(resolveBookmark(bookmark));
1551
- }
1863
+ const parentIsList = isListNode(parentList);
1864
+ if (parentIsList && parentList.nodeName === listName && !hasListStyleDetail(detail) && !isCustomList(parentList)) {
1865
+ flattenListSelection(editor);
1866
+ }
1867
+ else {
1868
+ applyList(editor, listName, detail);
1869
+ const bookmark = createBookmark(editor.selection.getRng());
1870
+ const allLists = parentIsList ? [parentList, ...lists] : lists;
1871
+ const updateFunction = (parentIsList && isCustomList(parentList)) ? updateCustomList : updateList$1;
1872
+ global$2.each(allLists, (elm) => {
1873
+ updateFunction(editor, elm, listName, detail);
1874
+ });
1875
+ editor.selection.setRng(resolveBookmark(bookmark));
1876
+ }
1552
1877
  };
1553
- const hasListStyleDetail = detail => {
1554
- return 'list-style-type' in detail;
1878
+ const hasListStyleDetail = (detail) => {
1879
+ return 'list-style-type' in detail;
1555
1880
  };
1556
1881
  const toggleSingleList = (editor, parentList, listName, detail) => {
1557
- if (parentList === editor.getBody()) {
1558
- return;
1559
- }
1560
- if (parentList) {
1561
- if (parentList.nodeName === listName && !hasListStyleDetail(detail) && !isCustomList(parentList)) {
1562
- flattenListSelection(editor);
1563
- } else {
1564
- const bookmark = createBookmark(editor.selection.getRng());
1565
- if (isCustomList(parentList)) {
1566
- parentList.classList.forEach((cls, _, classList) => {
1567
- if (cls.startsWith('tox-')) {
1568
- classList.remove(cls);
1569
- if (classList.length === 0) {
1570
- parentList.removeAttribute('class');
1882
+ if (parentList === editor.getBody()) {
1883
+ return;
1884
+ }
1885
+ if (parentList) {
1886
+ if (parentList.nodeName === listName && !hasListStyleDetail(detail) && !isCustomList(parentList)) {
1887
+ flattenListSelection(editor);
1888
+ }
1889
+ else {
1890
+ const bookmark = createBookmark(editor.selection.getRng());
1891
+ if (isCustomList(parentList)) {
1892
+ parentList.classList.forEach((cls, _, classList) => {
1893
+ if (cls.startsWith('tox-')) {
1894
+ classList.remove(cls);
1895
+ if (classList.length === 0) {
1896
+ parentList.removeAttribute('class');
1897
+ }
1898
+ }
1899
+ });
1571
1900
  }
1572
- }
1573
- });
1574
- }
1575
- updateListWithDetails(editor.dom, parentList, detail);
1576
- const newList = editor.dom.rename(parentList, listName);
1577
- mergeWithAdjacentLists(editor.dom, newList);
1578
- editor.selection.setRng(resolveBookmark(bookmark));
1579
- applyList(editor, listName, detail);
1580
- fireListEvent(editor, listToggleActionFromListName(listName), newList);
1581
- }
1582
- } else {
1583
- applyList(editor, listName, detail);
1584
- fireListEvent(editor, listToggleActionFromListName(listName), parentList);
1585
- }
1901
+ updateListWithDetails(editor.dom, parentList, detail);
1902
+ const newList = editor.dom.rename(parentList, listName);
1903
+ mergeWithAdjacentLists(editor.dom, newList);
1904
+ editor.selection.setRng(resolveBookmark(bookmark));
1905
+ applyList(editor, listName, detail);
1906
+ fireListEvent(editor, listToggleActionFromListName(listName), newList);
1907
+ }
1908
+ }
1909
+ else {
1910
+ applyList(editor, listName, detail);
1911
+ fireListEvent(editor, listToggleActionFromListName(listName), parentList);
1912
+ }
1586
1913
  };
1587
1914
  const toggleList = (editor, listName, _detail) => {
1588
- const parentList = getParentList(editor);
1589
- if (isWithinNonEditableList(editor, parentList)) {
1590
- return;
1591
- }
1592
- const selectedSubLists = getSelectedSubLists(editor);
1593
- const detail = isObject(_detail) ? _detail : {};
1594
- if (selectedSubLists.length > 0) {
1595
- toggleMultipleLists(editor, parentList, selectedSubLists, listName, detail);
1596
- } else {
1597
- toggleSingleList(editor, parentList, listName, detail);
1598
- }
1915
+ const parentList = getParentList(editor);
1916
+ if (isWithinNonEditableList(editor, parentList)) {
1917
+ return;
1918
+ }
1919
+ const selectedSubLists = getSelectedSubLists(editor);
1920
+ const detail = isObject(_detail) ? _detail : {};
1921
+ if (selectedSubLists.length > 0) {
1922
+ toggleMultipleLists(editor, parentList, selectedSubLists, listName, detail);
1923
+ }
1924
+ else {
1925
+ toggleSingleList(editor, parentList, listName, detail);
1926
+ }
1599
1927
  };
1600
1928
 
1601
1929
  const DOM = global$3.DOM;
1602
1930
  const normalizeList = (dom, list) => {
1603
- const parentNode = list.parentElement;
1604
- if (parentNode && parentNode.nodeName === 'LI' && parentNode.firstChild === list) {
1605
- const sibling = parentNode.previousSibling;
1606
- if (sibling && sibling.nodeName === 'LI') {
1607
- sibling.appendChild(list);
1608
- if (isEmpty$2(dom, parentNode)) {
1609
- DOM.remove(parentNode);
1610
- }
1611
- } else {
1612
- DOM.setStyle(parentNode, 'listStyleType', 'none');
1613
- }
1614
- }
1615
- if (isListNode(parentNode)) {
1616
- const sibling = parentNode.previousSibling;
1617
- if (sibling && sibling.nodeName === 'LI') {
1618
- sibling.appendChild(list);
1619
- }
1620
- }
1931
+ const parentNode = list.parentElement;
1932
+ // Move UL/OL to previous LI if it's the only child of a LI
1933
+ if (parentNode && parentNode.nodeName === 'LI' && parentNode.firstChild === list) {
1934
+ const sibling = parentNode.previousSibling;
1935
+ if (sibling && sibling.nodeName === 'LI') {
1936
+ sibling.appendChild(list);
1937
+ if (isEmpty$1(dom, parentNode)) {
1938
+ DOM.remove(parentNode);
1939
+ }
1940
+ }
1941
+ else {
1942
+ DOM.setStyle(parentNode, 'listStyleType', 'none');
1943
+ }
1944
+ }
1945
+ // Append OL/UL to previous LI if it's in a parent OL/UL i.e. old HTML4
1946
+ if (isListNode(parentNode)) {
1947
+ const sibling = parentNode.previousSibling;
1948
+ if (sibling && sibling.nodeName === 'LI') {
1949
+ sibling.appendChild(list);
1950
+ }
1951
+ }
1621
1952
  };
1622
1953
  const normalizeLists = (dom, element) => {
1623
- const lists = global$2.grep(dom.select('ol,ul', element));
1624
- global$2.each(lists, list => {
1625
- normalizeList(dom, list);
1626
- });
1954
+ const lists = global$2.grep(dom.select('ol,ul', element));
1955
+ global$2.each(lists, (list) => {
1956
+ normalizeList(dom, list);
1957
+ });
1627
1958
  };
1628
1959
 
1629
1960
  const findNextCaretContainer = (editor, rng, isForward, root) => {
1630
- let node = rng.startContainer;
1631
- const offset = rng.startOffset;
1632
- if (isTextNode$1(node) && (isForward ? offset < node.data.length : offset > 0)) {
1633
- return node;
1634
- }
1635
- const nonEmptyBlocks = editor.schema.getNonEmptyElements();
1636
- if (isElement(node)) {
1637
- node = global$6.getNode(node, offset);
1638
- }
1639
- const walker = new global$5(node, root);
1640
- if (isForward) {
1641
- if (isBogusBr(editor.dom, node)) {
1642
- walker.next();
1643
- }
1644
- }
1645
- const walkFn = isForward ? walker.next.bind(walker) : walker.prev2.bind(walker);
1646
- while (node = walkFn()) {
1647
- if (node.nodeName === 'LI' && !node.hasChildNodes()) {
1648
- return node;
1649
- }
1650
- if (nonEmptyBlocks[node.nodeName]) {
1651
- return node;
1652
- }
1653
- if (isTextNode$1(node) && node.data.length > 0) {
1654
- return node;
1655
- }
1656
- }
1657
- return null;
1961
+ let node = rng.startContainer;
1962
+ const offset = rng.startOffset;
1963
+ if (isTextNode$1(node) && (isForward ? offset < node.data.length : offset > 0)) {
1964
+ return node;
1965
+ }
1966
+ const nonEmptyBlocks = editor.schema.getNonEmptyElements();
1967
+ if (isElement(node)) {
1968
+ node = global$6.getNode(node, offset);
1969
+ }
1970
+ const walker = new global$5(node, root);
1971
+ // Delete at <li>|<br></li> then jump over the bogus br
1972
+ if (isForward) {
1973
+ if (isBogusBr(editor.dom, node)) {
1974
+ walker.next();
1975
+ }
1976
+ }
1977
+ const walkFn = isForward ? walker.next.bind(walker) : walker.prev2.bind(walker);
1978
+ while ((node = walkFn())) {
1979
+ if (node.nodeName === 'LI' && !node.hasChildNodes()) {
1980
+ return node;
1981
+ }
1982
+ if (nonEmptyBlocks[node.nodeName]) {
1983
+ return node;
1984
+ }
1985
+ if (isTextNode$1(node) && node.data.length > 0) {
1986
+ return node;
1987
+ }
1988
+ }
1989
+ return null;
1658
1990
  };
1659
1991
  const hasOnlyOneBlockChild = (dom, elm) => {
1660
- const childNodes = elm.childNodes;
1661
- return childNodes.length === 1 && !isListNode(childNodes[0]) && dom.isBlock(childNodes[0]);
1992
+ const childNodes = elm.childNodes;
1993
+ return childNodes.length === 1 && !isListNode(childNodes[0]) && dom.isBlock(childNodes[0]);
1662
1994
  };
1663
- const isUnwrappable = node => Optional.from(node).map(SugarElement.fromDom).filter(isHTMLElement).exists(el => isEditable(el) && !contains$1(['details'], name(el)));
1995
+ const isUnwrappable = (node) => Optional.from(node)
1996
+ .map(SugarElement.fromDom)
1997
+ .filter(isHTMLElement)
1998
+ .exists((el) => isEditable(el) && !contains$1(['details'], name(el)));
1664
1999
  const unwrapSingleBlockChild = (dom, elm) => {
1665
- if (hasOnlyOneBlockChild(dom, elm) && isUnwrappable(elm.firstChild)) {
1666
- dom.remove(elm.firstChild, true);
1667
- }
2000
+ if (hasOnlyOneBlockChild(dom, elm) && isUnwrappable(elm.firstChild)) {
2001
+ dom.remove(elm.firstChild, true);
2002
+ }
1668
2003
  };
1669
2004
  const moveChildren = (dom, fromElm, toElm) => {
1670
- let node;
1671
- const targetElm = hasOnlyOneBlockChild(dom, toElm) ? toElm.firstChild : toElm;
1672
- unwrapSingleBlockChild(dom, fromElm);
1673
- if (!isEmpty$2(dom, fromElm, true)) {
1674
- while (node = fromElm.firstChild) {
1675
- targetElm.appendChild(node);
2005
+ let node;
2006
+ const targetElm = hasOnlyOneBlockChild(dom, toElm) ? toElm.firstChild : toElm;
2007
+ unwrapSingleBlockChild(dom, fromElm);
2008
+ if (!isEmpty$1(dom, fromElm, true)) {
2009
+ while ((node = fromElm.firstChild)) {
2010
+ targetElm.appendChild(node);
2011
+ }
1676
2012
  }
1677
- }
1678
2013
  };
1679
2014
  const mergeLiElements = (dom, fromElm, toElm) => {
1680
- let listNode;
1681
- const ul = fromElm.parentNode;
1682
- if (!isChildOfBody(dom, fromElm) || !isChildOfBody(dom, toElm)) {
1683
- return;
1684
- }
1685
- if (isListNode(toElm.lastChild)) {
1686
- listNode = toElm.lastChild;
1687
- }
1688
- if (ul === toElm.lastChild) {
1689
- if (isBr(ul.previousSibling)) {
1690
- dom.remove(ul.previousSibling);
1691
- }
1692
- }
1693
- const node = toElm.lastChild;
1694
- if (node && isBr(node) && fromElm.hasChildNodes()) {
1695
- dom.remove(node);
1696
- }
1697
- if (isEmpty$2(dom, toElm, true)) {
1698
- empty(SugarElement.fromDom(toElm));
1699
- }
1700
- moveChildren(dom, fromElm, toElm);
1701
- if (listNode) {
1702
- toElm.appendChild(listNode);
1703
- }
1704
- const contains$1 = contains(SugarElement.fromDom(toElm), SugarElement.fromDom(fromElm));
1705
- const nestedLists = contains$1 ? dom.getParents(fromElm, isListNode, toElm) : [];
1706
- dom.remove(fromElm);
1707
- each$1(nestedLists, list => {
1708
- if (isEmpty$2(dom, list) && list !== dom.getRoot()) {
1709
- dom.remove(list);
1710
- }
1711
- });
2015
+ let listNode;
2016
+ const ul = fromElm.parentNode;
2017
+ if (!isChildOfBody(dom, fromElm) || !isChildOfBody(dom, toElm)) {
2018
+ return;
2019
+ }
2020
+ if (isListNode(toElm.lastChild)) {
2021
+ listNode = toElm.lastChild;
2022
+ }
2023
+ if (ul === toElm.lastChild) {
2024
+ if (isBr(ul.previousSibling)) {
2025
+ dom.remove(ul.previousSibling);
2026
+ }
2027
+ }
2028
+ const node = toElm.lastChild;
2029
+ if (node && isBr(node) && fromElm.hasChildNodes()) {
2030
+ dom.remove(node);
2031
+ }
2032
+ if (isEmpty$1(dom, toElm, true)) {
2033
+ empty(SugarElement.fromDom(toElm));
2034
+ }
2035
+ moveChildren(dom, fromElm, toElm);
2036
+ if (listNode) {
2037
+ toElm.appendChild(listNode);
2038
+ }
2039
+ const contains$1 = contains(SugarElement.fromDom(toElm), SugarElement.fromDom(fromElm));
2040
+ const nestedLists = contains$1 ? dom.getParents(fromElm, isListNode, toElm) : [];
2041
+ dom.remove(fromElm);
2042
+ each$1(nestedLists, (list) => {
2043
+ if (isEmpty$1(dom, list) && list !== dom.getRoot()) {
2044
+ dom.remove(list);
2045
+ }
2046
+ });
1712
2047
  };
1713
2048
  const mergeIntoEmptyLi = (editor, fromLi, toLi) => {
1714
- empty(SugarElement.fromDom(toLi));
1715
- mergeLiElements(editor.dom, fromLi, toLi);
1716
- editor.selection.setCursorLocation(toLi, 0);
2049
+ empty(SugarElement.fromDom(toLi));
2050
+ mergeLiElements(editor.dom, fromLi, toLi);
2051
+ editor.selection.setCursorLocation(toLi, 0);
1717
2052
  };
1718
2053
  const mergeForward = (editor, rng, fromLi, toLi) => {
1719
- const dom = editor.dom;
1720
- if (dom.isEmpty(toLi)) {
1721
- mergeIntoEmptyLi(editor, fromLi, toLi);
1722
- } else {
1723
- const bookmark = createBookmark(rng);
1724
- mergeLiElements(dom, fromLi, toLi);
1725
- editor.selection.setRng(resolveBookmark(bookmark));
1726
- }
2054
+ const dom = editor.dom;
2055
+ if (dom.isEmpty(toLi)) {
2056
+ mergeIntoEmptyLi(editor, fromLi, toLi);
2057
+ }
2058
+ else {
2059
+ const bookmark = createBookmark(rng);
2060
+ mergeLiElements(dom, fromLi, toLi);
2061
+ editor.selection.setRng(resolveBookmark(bookmark));
2062
+ }
1727
2063
  };
1728
2064
  const mergeBackward = (editor, rng, fromLi, toLi) => {
1729
- const bookmark = createBookmark(rng);
1730
- mergeLiElements(editor.dom, fromLi, toLi);
1731
- const resolvedBookmark = resolveBookmark(bookmark);
1732
- editor.selection.setRng(resolvedBookmark);
2065
+ const bookmark = createBookmark(rng);
2066
+ mergeLiElements(editor.dom, fromLi, toLi);
2067
+ const resolvedBookmark = resolveBookmark(bookmark);
2068
+ editor.selection.setRng(resolvedBookmark);
1733
2069
  };
1734
2070
  const backspaceDeleteFromListToListCaret = (editor, isForward) => {
1735
- const dom = editor.dom, selection = editor.selection;
1736
- const selectionStartElm = selection.getStart();
1737
- const root = getClosestEditingHost(editor, selectionStartElm);
1738
- const li = dom.getParent(selection.getStart(), 'LI', root);
1739
- if (li) {
1740
- const ul = li.parentElement;
1741
- if (ul === editor.getBody() && isEmpty$2(dom, ul)) {
1742
- return true;
1743
- }
1744
- const rng = normalizeRange(selection.getRng());
1745
- const otherLi = dom.getParent(findNextCaretContainer(editor, rng, isForward, root), 'LI', root);
1746
- const willMergeParentIntoChild = otherLi && (isForward ? dom.isChildOf(li, otherLi) : dom.isChildOf(otherLi, li));
1747
- if (otherLi && otherLi !== li && !willMergeParentIntoChild) {
1748
- editor.undoManager.transact(() => {
1749
- if (isForward) {
1750
- mergeForward(editor, rng, otherLi, li);
1751
- } else {
1752
- if (isFirstChild(li)) {
1753
- outdentListSelection(editor);
1754
- } else {
1755
- mergeBackward(editor, rng, li, otherLi);
1756
- }
1757
- }
1758
- });
1759
- return true;
1760
- } else if (willMergeParentIntoChild && !isForward && otherLi !== li) {
1761
- editor.undoManager.transact(() => {
1762
- if (rng.commonAncestorContainer.parentElement) {
1763
- const bookmark = createBookmark(rng);
1764
- const oldParentElRef = rng.commonAncestorContainer.parentElement;
1765
- moveChildren(dom, rng.commonAncestorContainer.parentElement, otherLi);
1766
- oldParentElRef.remove();
1767
- const resolvedBookmark = resolveBookmark(bookmark);
1768
- editor.selection.setRng(resolvedBookmark);
1769
- }
1770
- });
1771
- return true;
1772
- } else if (!otherLi) {
1773
- if (!isForward && rng.startOffset === 0 && rng.endOffset === 0) {
1774
- editor.undoManager.transact(() => {
1775
- flattenListSelection(editor);
1776
- });
1777
- return true;
1778
- }
2071
+ const dom = editor.dom, selection = editor.selection;
2072
+ const selectionStartElm = selection.getStart();
2073
+ const root = getClosestEditingHost(editor, selectionStartElm);
2074
+ const li = dom.getParent(selection.getStart(), 'LI', root);
2075
+ if (li) {
2076
+ const ul = li.parentElement;
2077
+ if (ul === editor.getBody() && isEmpty$1(dom, ul)) {
2078
+ return true;
2079
+ }
2080
+ const rng = normalizeRange(selection.getRng());
2081
+ const otherLi = dom.getParent(findNextCaretContainer(editor, rng, isForward, root), 'LI', root);
2082
+ const willMergeParentIntoChild = otherLi && (isForward ? dom.isChildOf(li, otherLi) : dom.isChildOf(otherLi, li));
2083
+ if (otherLi && otherLi !== li && !willMergeParentIntoChild) {
2084
+ editor.undoManager.transact(() => {
2085
+ if (isForward) {
2086
+ mergeForward(editor, rng, otherLi, li);
2087
+ }
2088
+ else {
2089
+ if (isFirstChild(li)) {
2090
+ outdentListSelection(editor);
2091
+ }
2092
+ else {
2093
+ mergeBackward(editor, rng, li, otherLi);
2094
+ }
2095
+ }
2096
+ });
2097
+ return true;
2098
+ }
2099
+ else if (willMergeParentIntoChild && !isForward && otherLi !== li) {
2100
+ const commonAncestorParent = rng.commonAncestorContainer.parentElement;
2101
+ if (!commonAncestorParent || dom.isChildOf(otherLi, commonAncestorParent)) {
2102
+ return false;
2103
+ }
2104
+ editor.undoManager.transact(() => {
2105
+ const bookmark = createBookmark(rng);
2106
+ moveChildren(dom, commonAncestorParent, otherLi);
2107
+ commonAncestorParent.remove();
2108
+ const resolvedBookmark = resolveBookmark(bookmark);
2109
+ editor.selection.setRng(resolvedBookmark);
2110
+ });
2111
+ return true;
2112
+ }
2113
+ else if (!otherLi) {
2114
+ if (!isForward && rng.startOffset === 0 && rng.endOffset === 0) {
2115
+ editor.undoManager.transact(() => {
2116
+ flattenListSelection(editor);
2117
+ });
2118
+ return true;
2119
+ }
2120
+ }
1779
2121
  }
1780
- }
1781
- return false;
2122
+ return false;
1782
2123
  };
1783
2124
  const removeBlock = (dom, block, root) => {
1784
- const parentBlock = dom.getParent(block.parentNode, dom.isBlock, root);
1785
- dom.remove(block);
1786
- if (parentBlock && dom.isEmpty(parentBlock)) {
1787
- dom.remove(parentBlock);
1788
- }
2125
+ const parentBlock = dom.getParent(block.parentNode, dom.isBlock, root);
2126
+ dom.remove(block);
2127
+ if (parentBlock && dom.isEmpty(parentBlock)) {
2128
+ dom.remove(parentBlock);
2129
+ }
1789
2130
  };
1790
2131
  const backspaceDeleteIntoListCaret = (editor, isForward) => {
1791
- const dom = editor.dom;
1792
- const selectionStartElm = editor.selection.getStart();
1793
- const root = getClosestEditingHost(editor, selectionStartElm);
1794
- const block = dom.getParent(selectionStartElm, dom.isBlock, root);
1795
- if (block && dom.isEmpty(block)) {
1796
- const rng = normalizeRange(editor.selection.getRng());
1797
- const otherLi = dom.getParent(findNextCaretContainer(editor, rng, isForward, root), 'LI', root);
1798
- if (otherLi) {
1799
- const findValidElement = element => contains$1([
1800
- 'td',
1801
- 'th',
1802
- 'caption'
1803
- ], name(element));
1804
- const findRoot = node => node.dom === root;
1805
- const otherLiCell = closest$2(SugarElement.fromDom(otherLi), findValidElement, findRoot);
1806
- const caretCell = closest$2(SugarElement.fromDom(rng.startContainer), findValidElement, findRoot);
1807
- if (!equals(otherLiCell, caretCell, eq)) {
1808
- return false;
1809
- }
1810
- editor.undoManager.transact(() => {
1811
- const parentNode = otherLi.parentNode;
1812
- removeBlock(dom, block, root);
1813
- mergeWithAdjacentLists(dom, parentNode);
1814
- editor.selection.select(otherLi, true);
1815
- editor.selection.collapse(isForward);
1816
- });
1817
- return true;
1818
- }
1819
- }
1820
- return false;
2132
+ const dom = editor.dom;
2133
+ const selectionStartElm = editor.selection.getStart();
2134
+ const root = getClosestEditingHost(editor, selectionStartElm);
2135
+ const block = dom.getParent(selectionStartElm, dom.isBlock, root);
2136
+ if (block && dom.isEmpty(block, undefined, { checkRootAsContent: true })) {
2137
+ const rng = normalizeRange(editor.selection.getRng());
2138
+ const nextCaretContainer = findNextCaretContainer(editor, rng, isForward, root);
2139
+ const otherLi = dom.getParent(nextCaretContainer, 'LI', root);
2140
+ if (nextCaretContainer && otherLi) {
2141
+ const findValidElement = (element) => contains$1(['td', 'th', 'caption'], name(element));
2142
+ const findRoot = (node) => node.dom === root;
2143
+ const otherLiCell = closest$2(SugarElement.fromDom(otherLi), findValidElement, findRoot);
2144
+ const caretCell = closest$2(SugarElement.fromDom(rng.startContainer), findValidElement, findRoot);
2145
+ if (!equals(otherLiCell, caretCell, eq)) {
2146
+ return false;
2147
+ }
2148
+ editor.undoManager.transact(() => {
2149
+ const parentNode = otherLi.parentNode;
2150
+ removeBlock(dom, block, root);
2151
+ mergeWithAdjacentLists(dom, parentNode);
2152
+ editor.selection.select(nextCaretContainer, true);
2153
+ editor.selection.collapse(isForward);
2154
+ });
2155
+ return true;
2156
+ }
2157
+ }
2158
+ return false;
1821
2159
  };
1822
2160
  const backspaceDeleteCaret = (editor, isForward) => {
1823
- return backspaceDeleteFromListToListCaret(editor, isForward) || backspaceDeleteIntoListCaret(editor, isForward);
2161
+ return backspaceDeleteFromListToListCaret(editor, isForward) || backspaceDeleteIntoListCaret(editor, isForward);
1824
2162
  };
1825
- const hasListSelection = editor => {
1826
- const selectionStartElm = editor.selection.getStart();
1827
- const root = getClosestEditingHost(editor, selectionStartElm);
1828
- const startListParent = editor.dom.getParent(selectionStartElm, 'LI,DT,DD', root);
1829
- return startListParent || getSelectedListItems(editor).length > 0;
2163
+ const hasListSelection = (editor) => {
2164
+ const selectionStartElm = editor.selection.getStart();
2165
+ const root = getClosestEditingHost(editor, selectionStartElm);
2166
+ const startListParent = editor.dom.getParent(selectionStartElm, 'LI,DT,DD', root);
2167
+ return startListParent || getSelectedListItems(editor).length > 0;
1830
2168
  };
1831
- const backspaceDeleteRange = editor => {
1832
- if (hasListSelection(editor)) {
1833
- editor.undoManager.transact(() => {
1834
- editor.execCommand('Delete');
1835
- normalizeLists(editor.dom, editor.getBody());
1836
- });
1837
- return true;
1838
- }
1839
- return false;
2169
+ const backspaceDeleteRange = (editor) => {
2170
+ if (hasListSelection(editor)) {
2171
+ editor.undoManager.transact(() => {
2172
+ // Some delete actions may prevent the input event from being fired. If we do not detect it, we fire it ourselves.
2173
+ let shouldFireInput = true;
2174
+ const inputHandler = () => shouldFireInput = false;
2175
+ editor.on('input', inputHandler);
2176
+ editor.execCommand('Delete');
2177
+ editor.off('input', inputHandler);
2178
+ if (shouldFireInput) {
2179
+ editor.dispatch('input');
2180
+ }
2181
+ normalizeLists(editor.dom, editor.getBody());
2182
+ });
2183
+ return true;
2184
+ }
2185
+ return false;
1840
2186
  };
1841
2187
  const backspaceDelete = (editor, isForward) => {
1842
- const selection = editor.selection;
1843
- return !isWithinNonEditableList(editor, selection.getNode()) && (selection.isCollapsed() ? backspaceDeleteCaret(editor, isForward) : backspaceDeleteRange(editor));
1844
- };
1845
- const setup$2 = editor => {
1846
- editor.on('ExecCommand', e => {
1847
- const cmd = e.command.toLowerCase();
1848
- if ((cmd === 'delete' || cmd === 'forwarddelete') && hasListSelection(editor)) {
1849
- normalizeLists(editor.dom, editor.getBody());
1850
- }
1851
- });
1852
- editor.on('keydown', e => {
1853
- if (e.keyCode === global$4.BACKSPACE) {
1854
- if (backspaceDelete(editor, false)) {
1855
- e.preventDefault();
1856
- }
1857
- } else if (e.keyCode === global$4.DELETE) {
1858
- if (backspaceDelete(editor, true)) {
1859
- e.preventDefault();
1860
- }
1861
- }
1862
- });
1863
- };
1864
-
1865
- const get = editor => ({
1866
- backspaceDelete: isForward => {
1867
- backspaceDelete(editor, isForward);
1868
- }
2188
+ const selection = editor.selection;
2189
+ return !isWithinNonEditableList(editor, selection.getNode()) && (selection.isCollapsed() ?
2190
+ backspaceDeleteCaret(editor, isForward) : backspaceDeleteRange(editor));
2191
+ };
2192
+ const setup$2 = (editor) => {
2193
+ editor.on('ExecCommand', (e) => {
2194
+ const cmd = e.command.toLowerCase();
2195
+ if ((cmd === 'delete' || cmd === 'forwarddelete') && hasListSelection(editor)) {
2196
+ normalizeLists(editor.dom, editor.getBody());
2197
+ }
2198
+ });
2199
+ editor.on('keydown', (e) => {
2200
+ if (e.keyCode === global$4.BACKSPACE) {
2201
+ if (backspaceDelete(editor, false)) {
2202
+ e.preventDefault();
2203
+ }
2204
+ }
2205
+ else if (e.keyCode === global$4.DELETE) {
2206
+ if (backspaceDelete(editor, true)) {
2207
+ e.preventDefault();
2208
+ }
2209
+ }
2210
+ });
2211
+ };
2212
+
2213
+ const get = (editor) => ({
2214
+ backspaceDelete: (isForward) => {
2215
+ backspaceDelete(editor, isForward);
2216
+ }
1869
2217
  });
1870
2218
 
1871
2219
  const updateList = (editor, update) => {
1872
- const parentList = getParentList(editor);
1873
- if (parentList === null || isWithinNonEditableList(editor, parentList)) {
1874
- return;
1875
- }
1876
- editor.undoManager.transact(() => {
1877
- if (isObject(update.styles)) {
1878
- editor.dom.setStyles(parentList, update.styles);
1879
- }
1880
- if (isObject(update.attrs)) {
1881
- each(update.attrs, (v, k) => editor.dom.setAttrib(parentList, k, v));
1882
- }
1883
- });
1884
- };
1885
-
1886
- const parseAlphabeticBase26 = str => {
1887
- const chars = reverse(trim(str).split(''));
1888
- const values = map(chars, (char, i) => {
1889
- const charValue = char.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0) + 1;
1890
- return Math.pow(26, i) * charValue;
1891
- });
1892
- return foldl(values, (sum, v) => sum + v, 0);
1893
- };
1894
- const composeAlphabeticBase26 = value => {
1895
- value--;
1896
- if (value < 0) {
1897
- return '';
1898
- } else {
1899
- const remainder = value % 26;
1900
- const quotient = Math.floor(value / 26);
1901
- const rest = composeAlphabeticBase26(quotient);
1902
- const char = String.fromCharCode('A'.charCodeAt(0) + remainder);
1903
- return rest + char;
1904
- }
1905
- };
1906
- const isUppercase = str => /^[A-Z]+$/.test(str);
1907
- const isLowercase = str => /^[a-z]+$/.test(str);
1908
- const isNumeric = str => /^[0-9]+$/.test(str);
1909
- const deduceListType = start => {
1910
- if (isNumeric(start)) {
1911
- return 2;
1912
- } else if (isUppercase(start)) {
1913
- return 0;
1914
- } else if (isLowercase(start)) {
1915
- return 1;
1916
- } else if (isEmpty$1(start)) {
1917
- return 3;
1918
- } else {
1919
- return 4;
1920
- }
1921
- };
1922
- const parseStartValue = start => {
1923
- switch (deduceListType(start)) {
1924
- case 2:
1925
- return Optional.some({
1926
- listStyleType: Optional.none(),
1927
- start
1928
- });
1929
- case 0:
1930
- return Optional.some({
1931
- listStyleType: Optional.some('upper-alpha'),
1932
- start: parseAlphabeticBase26(start).toString()
1933
- });
1934
- case 1:
1935
- return Optional.some({
1936
- listStyleType: Optional.some('lower-alpha'),
1937
- start: parseAlphabeticBase26(start).toString()
2220
+ const parentList = getParentList(editor);
2221
+ if (parentList === null || isWithinNonEditableList(editor, parentList)) {
2222
+ return;
2223
+ }
2224
+ editor.undoManager.transact(() => {
2225
+ if (isObject(update.styles)) {
2226
+ editor.dom.setStyles(parentList, update.styles);
2227
+ }
2228
+ if (isObject(update.attrs)) {
2229
+ each(update.attrs, (v, k) => editor.dom.setAttrib(parentList, k, v));
2230
+ }
1938
2231
  });
1939
- case 3:
1940
- return Optional.some({
1941
- listStyleType: Optional.none(),
1942
- start: ''
2232
+ };
2233
+
2234
+ // Example: 'AB' -> 28
2235
+ const parseAlphabeticBase26 = (str) => {
2236
+ const chars = reverse(trim(str).split(''));
2237
+ const values = map(chars, (char, i) => {
2238
+ const charValue = char.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0) + 1;
2239
+ return Math.pow(26, i) * charValue;
1943
2240
  });
1944
- case 4:
1945
- return Optional.none();
1946
- }
1947
- };
1948
- const parseDetail = detail => {
1949
- const start = parseInt(detail.start, 10);
1950
- if (is$2(detail.listStyleType, 'upper-alpha')) {
1951
- return composeAlphabeticBase26(start);
1952
- } else if (is$2(detail.listStyleType, 'lower-alpha')) {
1953
- return composeAlphabeticBase26(start).toLowerCase();
1954
- } else {
1955
- return detail.start;
1956
- }
1957
- };
1958
-
1959
- const open = editor => {
1960
- const currentList = getParentList(editor);
1961
- if (!isOlNode(currentList) || isWithinNonEditableList(editor, currentList)) {
1962
- return;
1963
- }
1964
- editor.windowManager.open({
1965
- title: 'List Properties',
1966
- body: {
1967
- type: 'panel',
1968
- items: [{
1969
- type: 'input',
1970
- name: 'start',
1971
- label: 'Start list at number',
1972
- inputMode: 'numeric'
1973
- }]
1974
- },
1975
- initialData: {
1976
- start: parseDetail({
1977
- start: editor.dom.getAttrib(currentList, 'start', '1'),
1978
- listStyleType: Optional.from(editor.dom.getStyle(currentList, 'list-style-type'))
1979
- })
1980
- },
1981
- buttons: [
1982
- {
1983
- type: 'cancel',
1984
- name: 'cancel',
1985
- text: 'Cancel'
1986
- },
1987
- {
1988
- type: 'submit',
1989
- name: 'save',
1990
- text: 'Save',
1991
- primary: true
1992
- }
1993
- ],
1994
- onSubmit: api => {
1995
- const data = api.getData();
1996
- parseStartValue(data.start).each(detail => {
1997
- editor.execCommand('mceListUpdate', false, {
1998
- attrs: { start: detail.start === '1' ? '' : detail.start },
1999
- styles: { 'list-style-type': detail.listStyleType.getOr('') }
2000
- });
2001
- });
2002
- api.close();
2241
+ return foldl(values, (sum, v) => sum + v, 0);
2242
+ };
2243
+ // Example: 28 -> 'AB'
2244
+ const composeAlphabeticBase26 = (value) => {
2245
+ value--;
2246
+ if (value < 0) {
2247
+ return '';
2248
+ }
2249
+ else {
2250
+ const remainder = value % 26;
2251
+ const quotient = Math.floor(value / 26);
2252
+ const rest = composeAlphabeticBase26(quotient);
2253
+ const char = String.fromCharCode('A'.charCodeAt(0) + remainder);
2254
+ return rest + char;
2255
+ }
2256
+ };
2257
+ const isUppercase = (str) => /^[A-Z]+$/.test(str);
2258
+ const isLowercase = (str) => /^[a-z]+$/.test(str);
2259
+ const isNumeric = (str) => /^[0-9]+$/.test(str);
2260
+ const deduceListType = (start) => {
2261
+ if (isNumeric(start)) {
2262
+ return 2 /* ListType.Numeric */;
2263
+ }
2264
+ else if (isUppercase(start)) {
2265
+ return 0 /* ListType.UpperAlpha */;
2266
+ }
2267
+ else if (isLowercase(start)) {
2268
+ return 1 /* ListType.LowerAlpha */;
2269
+ }
2270
+ else if (isEmpty$2(start)) {
2271
+ return 3 /* ListType.None */;
2272
+ }
2273
+ else {
2274
+ return 4 /* ListType.Unknown */;
2275
+ }
2276
+ };
2277
+ const parseStartValue = (start) => {
2278
+ switch (deduceListType(start)) {
2279
+ case 2 /* ListType.Numeric */:
2280
+ return Optional.some({
2281
+ listStyleType: Optional.none(),
2282
+ start
2283
+ });
2284
+ case 0 /* ListType.UpperAlpha */:
2285
+ return Optional.some({
2286
+ listStyleType: Optional.some('upper-alpha'),
2287
+ start: parseAlphabeticBase26(start).toString()
2288
+ });
2289
+ case 1 /* ListType.LowerAlpha */:
2290
+ return Optional.some({
2291
+ listStyleType: Optional.some('lower-alpha'),
2292
+ start: parseAlphabeticBase26(start).toString()
2293
+ });
2294
+ case 3 /* ListType.None */:
2295
+ return Optional.some({
2296
+ listStyleType: Optional.none(),
2297
+ start: ''
2298
+ });
2299
+ case 4 /* ListType.Unknown */:
2300
+ return Optional.none();
2301
+ }
2302
+ };
2303
+ const parseDetail = (detail) => {
2304
+ const start = parseInt(detail.start, 10);
2305
+ if (is$2(detail.listStyleType, 'upper-alpha')) {
2306
+ return composeAlphabeticBase26(start);
2307
+ }
2308
+ else if (is$2(detail.listStyleType, 'lower-alpha')) {
2309
+ return composeAlphabeticBase26(start).toLowerCase();
2310
+ }
2311
+ else {
2312
+ return detail.start;
2313
+ }
2314
+ };
2315
+
2316
+ const open = (editor) => {
2317
+ // Find the current list and skip opening if the selection isn't in an ordered list
2318
+ const currentList = getParentList(editor);
2319
+ if (!isOlNode(currentList) || isWithinNonEditableList(editor, currentList)) {
2320
+ return;
2003
2321
  }
2004
- });
2322
+ editor.windowManager.open({
2323
+ title: 'List Properties',
2324
+ body: {
2325
+ type: 'panel',
2326
+ items: [
2327
+ {
2328
+ type: 'input',
2329
+ name: 'start',
2330
+ label: 'Start list at number',
2331
+ inputMode: 'numeric'
2332
+ }
2333
+ ]
2334
+ },
2335
+ initialData: {
2336
+ start: parseDetail({
2337
+ start: editor.dom.getAttrib(currentList, 'start', '1'),
2338
+ listStyleType: Optional.from(editor.dom.getStyle(currentList, 'list-style-type'))
2339
+ })
2340
+ },
2341
+ buttons: [
2342
+ {
2343
+ type: 'cancel',
2344
+ name: 'cancel',
2345
+ text: 'Cancel'
2346
+ },
2347
+ {
2348
+ type: 'submit',
2349
+ name: 'save',
2350
+ text: 'Save',
2351
+ primary: true
2352
+ }
2353
+ ],
2354
+ onSubmit: (api) => {
2355
+ const data = api.getData();
2356
+ parseStartValue(data.start).each((detail) => {
2357
+ editor.execCommand('mceListUpdate', false, {
2358
+ attrs: {
2359
+ start: detail.start === '1' ? '' : detail.start
2360
+ },
2361
+ styles: {
2362
+ 'list-style-type': detail.listStyleType.getOr('')
2363
+ }
2364
+ });
2365
+ });
2366
+ api.close();
2367
+ }
2368
+ });
2005
2369
  };
2006
2370
 
2007
2371
  const queryListCommandState = (editor, listName) => () => {
2008
- const parentList = getParentList(editor);
2009
- return isNonNullable(parentList) && parentList.nodeName === listName;
2010
- };
2011
- const registerDialog = editor => {
2012
- editor.addCommand('mceListProps', () => {
2013
- open(editor);
2014
- });
2015
- };
2016
- const register$2 = editor => {
2017
- editor.on('BeforeExecCommand', e => {
2018
- const cmd = e.command.toLowerCase();
2019
- if (cmd === 'indent') {
2020
- indentListSelection(editor);
2021
- } else if (cmd === 'outdent') {
2022
- outdentListSelection(editor);
2023
- }
2024
- });
2025
- editor.addCommand('InsertUnorderedList', (ui, detail) => {
2026
- toggleList(editor, 'UL', detail);
2027
- });
2028
- editor.addCommand('InsertOrderedList', (ui, detail) => {
2029
- toggleList(editor, 'OL', detail);
2030
- });
2031
- editor.addCommand('InsertDefinitionList', (ui, detail) => {
2032
- toggleList(editor, 'DL', detail);
2033
- });
2034
- editor.addCommand('RemoveList', () => {
2035
- flattenListSelection(editor);
2036
- });
2037
- registerDialog(editor);
2038
- editor.addCommand('mceListUpdate', (ui, detail) => {
2039
- if (isObject(detail)) {
2040
- updateList(editor, detail);
2041
- }
2042
- });
2043
- editor.addQueryStateHandler('InsertUnorderedList', queryListCommandState(editor, 'UL'));
2044
- editor.addQueryStateHandler('InsertOrderedList', queryListCommandState(editor, 'OL'));
2045
- editor.addQueryStateHandler('InsertDefinitionList', queryListCommandState(editor, 'DL'));
2372
+ const parentList = getParentList(editor);
2373
+ return isNonNullable(parentList) && parentList.nodeName === listName;
2374
+ };
2375
+ const registerDialog = (editor) => {
2376
+ editor.addCommand('mceListProps', () => {
2377
+ open(editor);
2378
+ });
2379
+ };
2380
+ const register$2 = (editor) => {
2381
+ editor.on('BeforeExecCommand', (e) => {
2382
+ const cmd = e.command.toLowerCase();
2383
+ if (cmd === 'indent') {
2384
+ indentListSelection(editor);
2385
+ }
2386
+ else if (cmd === 'outdent') {
2387
+ outdentListSelection(editor);
2388
+ }
2389
+ });
2390
+ editor.addCommand('InsertUnorderedList', (ui, detail) => {
2391
+ toggleList(editor, 'UL', detail);
2392
+ });
2393
+ editor.addCommand('InsertOrderedList', (ui, detail) => {
2394
+ toggleList(editor, 'OL', detail);
2395
+ });
2396
+ editor.addCommand('InsertDefinitionList', (ui, detail) => {
2397
+ toggleList(editor, 'DL', detail);
2398
+ });
2399
+ editor.addCommand('RemoveList', () => {
2400
+ flattenListSelection(editor);
2401
+ });
2402
+ registerDialog(editor);
2403
+ editor.addCommand('mceListUpdate', (ui, detail) => {
2404
+ if (isObject(detail)) {
2405
+ updateList(editor, detail);
2406
+ }
2407
+ });
2408
+ editor.addQueryStateHandler('InsertUnorderedList', queryListCommandState(editor, 'UL'));
2409
+ editor.addQueryStateHandler('InsertOrderedList', queryListCommandState(editor, 'OL'));
2410
+ editor.addQueryStateHandler('InsertDefinitionList', queryListCommandState(editor, 'DL'));
2046
2411
  };
2047
2412
 
2048
2413
  var global = tinymce.util.Tools.resolve('tinymce.html.Node');
2049
2414
 
2050
- const isTextNode = node => node.type === 3;
2051
- const isEmpty = nodeBuffer => nodeBuffer.length === 0;
2052
- const wrapInvalidChildren = list => {
2053
- const insertListItem = (buffer, refNode) => {
2054
- const li = global.create('li');
2055
- each$1(buffer, node => li.append(node));
2056
- if (refNode) {
2057
- list.insert(li, refNode, true);
2058
- } else {
2059
- list.append(li);
2060
- }
2061
- };
2062
- const reducer = (buffer, node) => {
2063
- if (isTextNode(node)) {
2064
- return [
2065
- ...buffer,
2066
- node
2067
- ];
2068
- } else if (!isEmpty(buffer) && !isTextNode(node)) {
2069
- insertListItem(buffer, node);
2070
- return [];
2071
- } else {
2072
- return buffer;
2073
- }
2074
- };
2075
- const restBuffer = foldl(list.children(), reducer, []);
2076
- if (!isEmpty(restBuffer)) {
2077
- insertListItem(restBuffer);
2078
- }
2079
- };
2080
- const setup$1 = editor => {
2081
- editor.on('PreInit', () => {
2082
- const {parser} = editor;
2083
- parser.addNodeFilter('ul,ol', nodes => each$1(nodes, wrapInvalidChildren));
2084
- });
2085
- };
2086
-
2087
- const setupTabKey = editor => {
2088
- editor.on('keydown', e => {
2089
- if (e.keyCode !== global$4.TAB || global$4.metaKeyPressed(e)) {
2090
- return;
2415
+ const isTextNode = (node) => node.type === 3;
2416
+ const isEmpty = (nodeBuffer) => nodeBuffer.length === 0;
2417
+ const wrapInvalidChildren = (list) => {
2418
+ const insertListItem = (buffer, refNode) => {
2419
+ const li = global.create('li');
2420
+ each$1(buffer, (node) => li.append(node));
2421
+ if (refNode) {
2422
+ list.insert(li, refNode, true);
2423
+ }
2424
+ else {
2425
+ list.append(li);
2426
+ }
2427
+ };
2428
+ const reducer = (buffer, node) => {
2429
+ if (isTextNode(node)) {
2430
+ return [...buffer, node];
2431
+ }
2432
+ else if (!isEmpty(buffer) && !isTextNode(node)) {
2433
+ insertListItem(buffer, node);
2434
+ return [];
2435
+ }
2436
+ else {
2437
+ return buffer;
2438
+ }
2439
+ };
2440
+ const restBuffer = foldl(list.children(), reducer, []);
2441
+ if (!isEmpty(restBuffer)) {
2442
+ insertListItem(restBuffer);
2091
2443
  }
2092
- editor.undoManager.transact(() => {
2093
- if (e.shiftKey ? outdentListSelection(editor) : indentListSelection(editor)) {
2094
- e.preventDefault();
2095
- }
2096
- });
2097
- });
2098
- };
2099
- const setup = editor => {
2100
- if (shouldIndentOnTab(editor)) {
2101
- setupTabKey(editor);
2102
- }
2103
- setup$2(editor);
2104
- };
2105
-
2106
- const setupToggleButtonHandler = (editor, listName) => api => {
2107
- const toggleButtonHandler = e => {
2108
- api.setActive(inList(e.parents, listName));
2109
- api.setEnabled(!isWithinNonEditableList(editor, e.element) && editor.selection.isEditable());
2110
- };
2111
- api.setEnabled(editor.selection.isEditable());
2112
- return setNodeChangeHandler(editor, toggleButtonHandler);
2113
- };
2114
- const register$1 = editor => {
2115
- const exec = command => () => editor.execCommand(command);
2116
- if (!editor.hasPlugin('advlist')) {
2117
- editor.ui.registry.addToggleButton('numlist', {
2118
- icon: 'ordered-list',
2119
- active: false,
2120
- tooltip: 'Numbered list',
2121
- onAction: exec('InsertOrderedList'),
2122
- onSetup: setupToggleButtonHandler(editor, 'OL')
2123
- });
2124
- editor.ui.registry.addToggleButton('bullist', {
2125
- icon: 'unordered-list',
2126
- active: false,
2127
- tooltip: 'Bullet list',
2128
- onAction: exec('InsertUnorderedList'),
2129
- onSetup: setupToggleButtonHandler(editor, 'UL')
2444
+ };
2445
+ const setup$1 = (editor) => {
2446
+ editor.on('PreInit', () => {
2447
+ const { parser } = editor;
2448
+ parser.addNodeFilter('ul,ol', (nodes) => each$1(nodes, wrapInvalidChildren));
2130
2449
  });
2131
- }
2132
2450
  };
2133
2451
 
2134
- const setupMenuButtonHandler = (editor, listName) => api => {
2135
- const menuButtonHandler = e => api.setEnabled(inList(e.parents, listName) && !isWithinNonEditableList(editor, e.element));
2136
- return setNodeChangeHandler(editor, menuButtonHandler);
2452
+ const setupTabKey = (editor) => {
2453
+ editor.on('keydown', (e) => {
2454
+ // Check for tab but not ctrl/cmd+tab since it switches browser tabs
2455
+ if (e.keyCode !== global$4.TAB || global$4.metaKeyPressed(e)) {
2456
+ return;
2457
+ }
2458
+ editor.undoManager.transact(() => {
2459
+ if (e.shiftKey ? outdentListSelection(editor) : indentListSelection(editor)) {
2460
+ e.preventDefault();
2461
+ }
2462
+ });
2463
+ });
2137
2464
  };
2138
- const register = editor => {
2139
- const listProperties = {
2140
- text: 'List properties...',
2141
- icon: 'ordered-list',
2142
- onAction: () => editor.execCommand('mceListProps'),
2143
- onSetup: setupMenuButtonHandler(editor, 'OL')
2144
- };
2145
- editor.ui.registry.addMenuItem('listprops', listProperties);
2146
- editor.ui.registry.addContextMenu('lists', {
2147
- update: node => {
2148
- const parentList = getParentList(editor, node);
2149
- return isOlNode(parentList) ? ['listprops'] : [];
2465
+ const setup = (editor) => {
2466
+ if (shouldIndentOnTab(editor)) {
2467
+ setupTabKey(editor);
2150
2468
  }
2151
- });
2469
+ setup$2(editor);
2152
2470
  };
2153
2471
 
2154
- var Plugin = () => {
2155
- global$7.add('lists', editor => {
2156
- register$3(editor);
2157
- setup$1(editor);
2158
- if (!editor.hasPlugin('rtc', true)) {
2159
- setup(editor);
2160
- register$2(editor);
2161
- } else {
2162
- registerDialog(editor);
2472
+ const setupToggleButtonHandler = (editor, listName) => (api) => {
2473
+ const toggleButtonHandler = (e) => {
2474
+ api.setActive(inList(e.parents, listName));
2475
+ api.setEnabled(!isWithinNonEditableList(editor, e.element) && editor.selection.isEditable());
2476
+ };
2477
+ api.setEnabled(editor.selection.isEditable());
2478
+ return setNodeChangeHandler(editor, toggleButtonHandler);
2479
+ };
2480
+ const register$1 = (editor) => {
2481
+ const exec = (command) => () => editor.execCommand(command);
2482
+ if (!editor.hasPlugin('advlist')) {
2483
+ editor.ui.registry.addToggleButton('numlist', {
2484
+ icon: 'ordered-list',
2485
+ active: false,
2486
+ tooltip: 'Numbered list',
2487
+ onAction: exec('InsertOrderedList'),
2488
+ onSetup: setupToggleButtonHandler(editor, 'OL')
2489
+ });
2490
+ editor.ui.registry.addToggleButton('bullist', {
2491
+ icon: 'unordered-list',
2492
+ active: false,
2493
+ tooltip: 'Bullet list',
2494
+ onAction: exec('InsertUnorderedList'),
2495
+ onSetup: setupToggleButtonHandler(editor, 'UL')
2496
+ });
2163
2497
  }
2164
- register$1(editor);
2165
- register(editor);
2166
- return get(editor);
2167
- });
2498
+ };
2499
+
2500
+ const setupMenuButtonHandler = (editor, listName) => (api) => {
2501
+ const menuButtonHandler = (e) => api.setEnabled(inList(e.parents, listName) && !isWithinNonEditableList(editor, e.element));
2502
+ return setNodeChangeHandler(editor, menuButtonHandler);
2503
+ };
2504
+ const register = (editor) => {
2505
+ const listProperties = {
2506
+ text: 'List properties...',
2507
+ icon: 'ordered-list',
2508
+ onAction: () => editor.execCommand('mceListProps'),
2509
+ onSetup: setupMenuButtonHandler(editor, 'OL')
2510
+ };
2511
+ editor.ui.registry.addMenuItem('listprops', listProperties);
2512
+ editor.ui.registry.addContextMenu('lists', {
2513
+ update: (node) => {
2514
+ const parentList = getParentList(editor, node);
2515
+ return isOlNode(parentList) ? ['listprops'] : [];
2516
+ }
2517
+ });
2518
+ };
2519
+
2520
+ var Plugin = () => {
2521
+ global$7.add('lists', (editor) => {
2522
+ register$3(editor);
2523
+ setup$1(editor);
2524
+ if (!editor.hasPlugin('rtc', true)) {
2525
+ setup(editor);
2526
+ register$2(editor);
2527
+ }
2528
+ else {
2529
+ registerDialog(editor);
2530
+ }
2531
+ register$1(editor);
2532
+ register(editor);
2533
+ return get(editor);
2534
+ });
2168
2535
  };
2169
2536
 
2170
2537
  Plugin();
2538
+ /** *****
2539
+ * DO NOT EXPORT ANYTHING
2540
+ *
2541
+ * IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
2542
+ *******/
2171
2543
 
2172
2544
  })();