@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,302 +7,507 @@
7
7
 
8
8
  var global$4 = tinymce.util.Tools.resolve('tinymce.PluginManager');
9
9
 
10
+ /* eslint-disable @typescript-eslint/no-wrapper-object-types */
10
11
  const getPrototypeOf = Object.getPrototypeOf;
11
12
  const hasProto = (v, constructor, predicate) => {
12
- var _a;
13
- if (predicate(v, constructor.prototype)) {
14
- return true;
15
- } else {
16
- return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
17
- }
18
- };
19
- const typeOf = x => {
20
- const t = typeof x;
21
- if (x === null) {
22
- return 'null';
23
- } else if (t === 'object' && Array.isArray(x)) {
24
- return 'array';
25
- } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
26
- return 'string';
27
- } else {
28
- return t;
29
- }
13
+ var _a;
14
+ if (predicate(v, constructor.prototype)) {
15
+ return true;
16
+ }
17
+ else {
18
+ // String-based fallback time
19
+ return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
20
+ }
30
21
  };
31
- const isType = type => value => typeOf(value) === type;
32
- const isSimpleType = type => value => typeof value === type;
33
- const eq = t => a => t === a;
22
+ const typeOf = (x) => {
23
+ const t = typeof x;
24
+ if (x === null) {
25
+ return 'null';
26
+ }
27
+ else if (t === 'object' && Array.isArray(x)) {
28
+ return 'array';
29
+ }
30
+ else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
31
+ return 'string';
32
+ }
33
+ else {
34
+ return t;
35
+ }
36
+ };
37
+ const isType = (type) => (value) => typeOf(value) === type;
38
+ const isSimpleType = (type) => (value) => typeof value === type;
39
+ const eq = (t) => (a) => t === a;
34
40
  const is = (value, constructor) => isObject(value) && hasProto(value, constructor, (o, proto) => getPrototypeOf(o) === proto);
35
41
  const isString = isType('string');
36
42
  const isObject = isType('object');
37
- const isPlainObject = value => is(value, Object);
43
+ const isPlainObject = (value) => is(value, Object);
38
44
  const isArray = isType('array');
39
45
  const isNull = eq(null);
40
46
  const isBoolean = isSimpleType('boolean');
41
- const isNullable = a => a === null || a === undefined;
42
- const isNonNullable = a => !isNullable(a);
47
+ const isNullable = (a) => a === null || a === undefined;
48
+ const isNonNullable = (a) => !isNullable(a);
43
49
  const isFunction = isSimpleType('function');
44
50
  const isNumber = isSimpleType('number');
45
51
  const isArrayOf = (value, pred) => {
46
- if (isArray(value)) {
47
- for (let i = 0, len = value.length; i < len; ++i) {
48
- if (!pred(value[i])) {
49
- return false;
50
- }
52
+ if (isArray(value)) {
53
+ for (let i = 0, len = value.length; i < len; ++i) {
54
+ if (!(pred(value[i]))) {
55
+ return false;
56
+ }
57
+ }
58
+ return true;
51
59
  }
52
- return true;
53
- }
54
- return false;
60
+ return false;
55
61
  };
56
62
 
57
- const noop = () => {
58
- };
63
+ const noop = () => { };
59
64
 
65
+ /**
66
+ * The `Optional` type represents a value (of any type) that potentially does
67
+ * not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
68
+ * value does exist) or a `None` (in which case the value does not exist). This
69
+ * module defines a whole lot of FP-inspired utility functions for dealing with
70
+ * `Optional` objects.
71
+ *
72
+ * Comparison with null or undefined:
73
+ * - We don't get fancy null coalescing operators with `Optional`
74
+ * - We do get fancy helper functions with `Optional`
75
+ * - `Optional` support nesting, and allow for the type to still be nullable (or
76
+ * another `Optional`)
77
+ * - There is no option to turn off strict-optional-checks like there is for
78
+ * strict-null-checks
79
+ */
60
80
  class Optional {
61
- constructor(tag, value) {
62
- this.tag = tag;
63
- this.value = value;
64
- }
65
- static some(value) {
66
- return new Optional(true, value);
67
- }
68
- static none() {
69
- return Optional.singletonNone;
70
- }
71
- fold(onNone, onSome) {
72
- if (this.tag) {
73
- return onSome(this.value);
74
- } else {
75
- return onNone();
76
- }
77
- }
78
- isSome() {
79
- return this.tag;
80
- }
81
- isNone() {
82
- return !this.tag;
83
- }
84
- map(mapper) {
85
- if (this.tag) {
86
- return Optional.some(mapper(this.value));
87
- } else {
88
- return Optional.none();
89
- }
90
- }
91
- bind(binder) {
92
- if (this.tag) {
93
- return binder(this.value);
94
- } else {
95
- return Optional.none();
96
- }
97
- }
98
- exists(predicate) {
99
- return this.tag && predicate(this.value);
100
- }
101
- forall(predicate) {
102
- return !this.tag || predicate(this.value);
103
- }
104
- filter(predicate) {
105
- if (!this.tag || predicate(this.value)) {
106
- return this;
107
- } else {
108
- return Optional.none();
109
- }
110
- }
111
- getOr(replacement) {
112
- return this.tag ? this.value : replacement;
113
- }
114
- or(replacement) {
115
- return this.tag ? this : replacement;
116
- }
117
- getOrThunk(thunk) {
118
- return this.tag ? this.value : thunk();
119
- }
120
- orThunk(thunk) {
121
- return this.tag ? this : thunk();
122
- }
123
- getOrDie(message) {
124
- if (!this.tag) {
125
- throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
126
- } else {
127
- return this.value;
128
- }
129
- }
130
- static from(value) {
131
- return isNonNullable(value) ? Optional.some(value) : Optional.none();
132
- }
133
- getOrNull() {
134
- return this.tag ? this.value : null;
135
- }
136
- getOrUndefined() {
137
- return this.value;
138
- }
139
- each(worker) {
140
- if (this.tag) {
141
- worker(this.value);
142
- }
143
- }
144
- toArray() {
145
- return this.tag ? [this.value] : [];
146
- }
147
- toString() {
148
- return this.tag ? `some(${ this.value })` : 'none()';
149
- }
81
+ // The internal representation has a `tag` and a `value`, but both are
82
+ // private: able to be console.logged, but not able to be accessed by code
83
+ constructor(tag, value) {
84
+ this.tag = tag;
85
+ this.value = value;
86
+ }
87
+ // --- Identities ---
88
+ /**
89
+ * Creates a new `Optional<T>` that **does** contain a value.
90
+ */
91
+ static some(value) {
92
+ return new Optional(true, value);
93
+ }
94
+ /**
95
+ * Create a new `Optional<T>` that **does not** contain a value. `T` can be
96
+ * any type because we don't actually have a `T`.
97
+ */
98
+ static none() {
99
+ return Optional.singletonNone;
100
+ }
101
+ /**
102
+ * Perform a transform on an `Optional` type. Regardless of whether this
103
+ * `Optional` contains a value or not, `fold` will return a value of type `U`.
104
+ * If this `Optional` does not contain a value, the `U` will be created by
105
+ * calling `onNone`. If this `Optional` does contain a value, the `U` will be
106
+ * created by calling `onSome`.
107
+ *
108
+ * For the FP enthusiasts in the room, this function:
109
+ * 1. Could be used to implement all of the functions below
110
+ * 2. Forms a catamorphism
111
+ */
112
+ fold(onNone, onSome) {
113
+ if (this.tag) {
114
+ return onSome(this.value);
115
+ }
116
+ else {
117
+ return onNone();
118
+ }
119
+ }
120
+ /**
121
+ * Determine if this `Optional` object contains a value.
122
+ */
123
+ isSome() {
124
+ return this.tag;
125
+ }
126
+ /**
127
+ * Determine if this `Optional` object **does not** contain a value.
128
+ */
129
+ isNone() {
130
+ return !this.tag;
131
+ }
132
+ // --- Functor (name stolen from Haskell / maths) ---
133
+ /**
134
+ * Perform a transform on an `Optional` object, **if** there is a value. If
135
+ * you provide a function to turn a T into a U, this is the function you use
136
+ * to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
137
+ * a value then the output will also contain a value (that value being the
138
+ * output of `mapper(this.value)`), and if this **does not** contain a value
139
+ * then neither will the output.
140
+ */
141
+ map(mapper) {
142
+ if (this.tag) {
143
+ return Optional.some(mapper(this.value));
144
+ }
145
+ else {
146
+ return Optional.none();
147
+ }
148
+ }
149
+ // --- Monad (name stolen from Haskell / maths) ---
150
+ /**
151
+ * Perform a transform on an `Optional` object, **if** there is a value.
152
+ * Unlike `map`, here the transform itself also returns an `Optional`.
153
+ */
154
+ bind(binder) {
155
+ if (this.tag) {
156
+ return binder(this.value);
157
+ }
158
+ else {
159
+ return Optional.none();
160
+ }
161
+ }
162
+ // --- Traversable (name stolen from Haskell / maths) ---
163
+ /**
164
+ * For a given predicate, this function finds out if there **exists** a value
165
+ * inside this `Optional` object that meets the predicate. In practice, this
166
+ * means that for `Optional`s that do not contain a value it returns false (as
167
+ * no predicate-meeting value exists).
168
+ */
169
+ exists(predicate) {
170
+ return this.tag && predicate(this.value);
171
+ }
172
+ /**
173
+ * For a given predicate, this function finds out if **all** the values inside
174
+ * this `Optional` object meet the predicate. In practice, this means that
175
+ * for `Optional`s that do not contain a value it returns true (as all 0
176
+ * objects do meet the predicate).
177
+ */
178
+ forall(predicate) {
179
+ return !this.tag || predicate(this.value);
180
+ }
181
+ filter(predicate) {
182
+ if (!this.tag || predicate(this.value)) {
183
+ return this;
184
+ }
185
+ else {
186
+ return Optional.none();
187
+ }
188
+ }
189
+ // --- Getters ---
190
+ /**
191
+ * Get the value out of the inside of the `Optional` object, using a default
192
+ * `replacement` value if the provided `Optional` object does not contain a
193
+ * value.
194
+ */
195
+ getOr(replacement) {
196
+ return this.tag ? this.value : replacement;
197
+ }
198
+ /**
199
+ * Get the value out of the inside of the `Optional` object, using a default
200
+ * `replacement` value if the provided `Optional` object does not contain a
201
+ * value. Unlike `getOr`, in this method the `replacement` object is also
202
+ * `Optional` - meaning that this method will always return an `Optional`.
203
+ */
204
+ or(replacement) {
205
+ return this.tag ? this : replacement;
206
+ }
207
+ /**
208
+ * Get the value out of the inside of the `Optional` object, using a default
209
+ * `replacement` value if the provided `Optional` object does not contain a
210
+ * value. Unlike `getOr`, in this method the `replacement` value is
211
+ * "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
212
+ * pass a function which (if called) will **return** the `value` you want to
213
+ * use.
214
+ */
215
+ getOrThunk(thunk) {
216
+ return this.tag ? this.value : thunk();
217
+ }
218
+ /**
219
+ * Get the value out of the inside of the `Optional` object, using a default
220
+ * `replacement` value if the provided Optional object does not contain a
221
+ * value.
222
+ *
223
+ * Unlike `or`, in this method the `replacement` value is "thunked" - that is
224
+ * to say that you don't pass a value to `orThunk`, you pass a function which
225
+ * (if called) will **return** the `value` you want to use.
226
+ *
227
+ * Unlike `getOrThunk`, in this method the `replacement` value is also
228
+ * `Optional`, meaning that this method will always return an `Optional`.
229
+ */
230
+ orThunk(thunk) {
231
+ return this.tag ? this : thunk();
232
+ }
233
+ /**
234
+ * Get the value out of the inside of the `Optional` object, throwing an
235
+ * exception if the provided `Optional` object does not contain a value.
236
+ *
237
+ * WARNING:
238
+ * You should only be using this function if you know that the `Optional`
239
+ * object **is not** empty (otherwise you're throwing exceptions in production
240
+ * code, which is bad).
241
+ *
242
+ * In tests this is more acceptable.
243
+ *
244
+ * Prefer other methods to this, such as `.each`.
245
+ */
246
+ getOrDie(message) {
247
+ if (!this.tag) {
248
+ throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
249
+ }
250
+ else {
251
+ return this.value;
252
+ }
253
+ }
254
+ // --- Interop with null and undefined ---
255
+ /**
256
+ * Creates an `Optional` value from a nullable (or undefined-able) input.
257
+ * Null, or undefined, is converted to `None`, and anything else is converted
258
+ * to `Some`.
259
+ */
260
+ static from(value) {
261
+ return isNonNullable(value) ? Optional.some(value) : Optional.none();
262
+ }
263
+ /**
264
+ * Converts an `Optional` to a nullable type, by getting the value if it
265
+ * exists, or returning `null` if it does not.
266
+ */
267
+ getOrNull() {
268
+ return this.tag ? this.value : null;
269
+ }
270
+ /**
271
+ * Converts an `Optional` to an undefined-able type, by getting the value if
272
+ * it exists, or returning `undefined` if it does not.
273
+ */
274
+ getOrUndefined() {
275
+ return this.value;
276
+ }
277
+ // --- Utilities ---
278
+ /**
279
+ * If the `Optional` contains a value, perform an action on that value.
280
+ * Unlike the rest of the methods on this type, `.each` has side-effects. If
281
+ * you want to transform an `Optional<T>` **into** something, then this is not
282
+ * the method for you. If you want to use an `Optional<T>` to **do**
283
+ * something, then this is the method for you - provided you're okay with not
284
+ * doing anything in the case where the `Optional` doesn't have a value inside
285
+ * it. If you're not sure whether your use-case fits into transforming
286
+ * **into** something or **doing** something, check whether it has a return
287
+ * value. If it does, you should be performing a transform.
288
+ */
289
+ each(worker) {
290
+ if (this.tag) {
291
+ worker(this.value);
292
+ }
293
+ }
294
+ /**
295
+ * Turn the `Optional` object into an array that contains all of the values
296
+ * stored inside the `Optional`. In practice, this means the output will have
297
+ * either 0 or 1 elements.
298
+ */
299
+ toArray() {
300
+ return this.tag ? [this.value] : [];
301
+ }
302
+ /**
303
+ * Turn the `Optional` object into a string for debugging or printing. Not
304
+ * recommended for production code, but good for debugging. Also note that
305
+ * these days an `Optional` object can be logged to the console directly, and
306
+ * its inner value (if it exists) will be visible.
307
+ */
308
+ toString() {
309
+ return this.tag ? `some(${this.value})` : 'none()';
310
+ }
150
311
  }
312
+ // Sneaky optimisation: every instance of Optional.none is identical, so just
313
+ // reuse the same object
151
314
  Optional.singletonNone = new Optional(false);
152
315
 
316
+ /* eslint-disable @typescript-eslint/unbound-method */
317
+ const nativeSlice = Array.prototype.slice;
318
+ const nativePush = Array.prototype.push;
319
+ const flatten = (xs) => {
320
+ // Note, this is possible because push supports multiple arguments:
321
+ // http://jsperf.com/concat-push/6
322
+ // Note that in the past, concat() would silently work (very slowly) for array-like objects.
323
+ // With this change it will throw an error.
324
+ const r = [];
325
+ for (let i = 0, len = xs.length; i < len; ++i) {
326
+ // Ensure that each value is an array itself
327
+ if (!isArray(xs[i])) {
328
+ throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
329
+ }
330
+ nativePush.apply(r, xs[i]);
331
+ }
332
+ return r;
333
+ };
334
+ const get = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
335
+ const head = (xs) => get(xs, 0);
336
+ isFunction(Array.from) ? Array.from : (x) => nativeSlice.call(x);
337
+ const findMap = (arr, f) => {
338
+ for (let i = 0; i < arr.length; i++) {
339
+ const r = f(arr[i], i);
340
+ if (r.isSome()) {
341
+ return r;
342
+ }
343
+ }
344
+ return Optional.none();
345
+ };
346
+
347
+ // There are many variations of Object iteration that are faster than the 'for-in' style:
348
+ // http://jsperf.com/object-keys-iteration/107
349
+ //
350
+ // Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
153
351
  const keys = Object.keys;
352
+ // eslint-disable-next-line @typescript-eslint/unbound-method
154
353
  const hasOwnProperty = Object.hasOwnProperty;
155
354
  const each = (obj, f) => {
156
- const props = keys(obj);
157
- for (let k = 0, len = props.length; k < len; k++) {
158
- const i = props[k];
159
- const x = obj[i];
160
- f(x, i);
161
- }
355
+ const props = keys(obj);
356
+ for (let k = 0, len = props.length; k < len; k++) {
357
+ const i = props[k];
358
+ const x = obj[i];
359
+ f(x, i);
360
+ }
162
361
  };
163
- const objAcc = r => (x, i) => {
164
- r[i] = x;
362
+ const objAcc = (r) => (x, i) => {
363
+ r[i] = x;
165
364
  };
166
365
  const internalFilter = (obj, pred, onTrue, onFalse) => {
167
- each(obj, (x, i) => {
168
- (pred(x, i) ? onTrue : onFalse)(x, i);
169
- });
366
+ each(obj, (x, i) => {
367
+ (pred(x, i) ? onTrue : onFalse)(x, i);
368
+ });
170
369
  };
171
370
  const filter = (obj, pred) => {
172
- const t = {};
173
- internalFilter(obj, pred, objAcc(t), noop);
174
- return t;
371
+ const t = {};
372
+ internalFilter(obj, pred, objAcc(t), noop);
373
+ return t;
175
374
  };
176
375
  const has = (obj, key) => hasOwnProperty.call(obj, key);
177
376
  const hasNonNullableKey = (obj, key) => has(obj, key) && obj[key] !== undefined && obj[key] !== null;
178
377
 
179
- const nativePush = Array.prototype.push;
180
- const flatten = xs => {
181
- const r = [];
182
- for (let i = 0, len = xs.length; i < len; ++i) {
183
- if (!isArray(xs[i])) {
184
- throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
185
- }
186
- nativePush.apply(r, xs[i]);
187
- }
188
- return r;
378
+ const deep = (old, nu) => {
379
+ const bothObjects = isPlainObject(old) && isPlainObject(nu);
380
+ return bothObjects ? deepMerge(old, nu) : nu;
189
381
  };
190
- const get = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
191
- const head = xs => get(xs, 0);
192
- const findMap = (arr, f) => {
193
- for (let i = 0; i < arr.length; i++) {
194
- const r = f(arr[i], i);
195
- if (r.isSome()) {
196
- return r;
197
- }
198
- }
199
- return Optional.none();
382
+ const baseMerge = (merger) => {
383
+ return (...objects) => {
384
+ if (objects.length === 0) {
385
+ throw new Error(`Can't merge zero objects`);
386
+ }
387
+ const ret = {};
388
+ for (let j = 0; j < objects.length; j++) {
389
+ const curObject = objects[j];
390
+ for (const key in curObject) {
391
+ if (has(curObject, key)) {
392
+ ret[key] = merger(ret[key], curObject[key]);
393
+ }
394
+ }
395
+ }
396
+ return ret;
397
+ };
200
398
  };
399
+ const deepMerge = baseMerge(deep);
201
400
 
202
- typeof window !== 'undefined' ? window : Function('return this;')();
203
-
204
- const rawSet = (dom, key, value) => {
205
- if (isString(value) || isBoolean(value) || isNumber(value)) {
206
- dom.setAttribute(key, value + '');
207
- } else {
208
- console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
209
- throw new Error('Attribute value was not simple');
210
- }
211
- };
212
- const set = (element, key, value) => {
213
- rawSet(element.dom, key, value);
214
- };
215
- const remove = (element, key) => {
216
- element.dom.removeAttribute(key);
217
- };
401
+ const isNotEmpty = (s) => s.length > 0;
218
402
 
219
403
  const fromHtml = (html, scope) => {
220
- const doc = scope || document;
221
- const div = doc.createElement('div');
222
- div.innerHTML = html;
223
- if (!div.hasChildNodes() || div.childNodes.length > 1) {
224
- const message = 'HTML does not have a single root node';
225
- console.error(message, html);
226
- throw new Error(message);
227
- }
228
- return fromDom(div.childNodes[0]);
404
+ const doc = scope || document;
405
+ const div = doc.createElement('div');
406
+ div.innerHTML = html;
407
+ if (!div.hasChildNodes() || div.childNodes.length > 1) {
408
+ const message = 'HTML does not have a single root node';
409
+ // eslint-disable-next-line no-console
410
+ console.error(message, html);
411
+ throw new Error(message);
412
+ }
413
+ return fromDom(div.childNodes[0]);
229
414
  };
230
415
  const fromTag = (tag, scope) => {
231
- const doc = scope || document;
232
- const node = doc.createElement(tag);
233
- return fromDom(node);
416
+ const doc = scope || document;
417
+ const node = doc.createElement(tag);
418
+ return fromDom(node);
234
419
  };
235
420
  const fromText = (text, scope) => {
236
- const doc = scope || document;
237
- const node = doc.createTextNode(text);
238
- return fromDom(node);
239
- };
240
- const fromDom = node => {
241
- if (node === null || node === undefined) {
242
- throw new Error('Node cannot be null or undefined');
243
- }
244
- return { dom: node };
421
+ const doc = scope || document;
422
+ const node = doc.createTextNode(text);
423
+ return fromDom(node);
424
+ };
425
+ const fromDom = (node) => {
426
+ // TODO: Consider removing this check, but left atm for safety
427
+ if (node === null || node === undefined) {
428
+ throw new Error('Node cannot be null or undefined');
429
+ }
430
+ return {
431
+ dom: node
432
+ };
245
433
  };
246
434
  const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
435
+ // tslint:disable-next-line:variable-name
247
436
  const SugarElement = {
248
- fromHtml,
249
- fromTag,
250
- fromText,
251
- fromDom,
252
- fromPoint
437
+ fromHtml,
438
+ fromTag,
439
+ fromText,
440
+ fromDom,
441
+ fromPoint
442
+ };
443
+
444
+ const rawSet = (dom, key, value) => {
445
+ /*
446
+ * JQuery coerced everything to a string, and silently did nothing on text node/null/undefined.
447
+ *
448
+ * We fail on those invalid cases, only allowing numbers and booleans.
449
+ */
450
+ if (isString(value) || isBoolean(value) || isNumber(value)) {
451
+ dom.setAttribute(key, value + '');
452
+ }
453
+ else {
454
+ // eslint-disable-next-line no-console
455
+ console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
456
+ throw new Error('Attribute value was not simple');
457
+ }
458
+ };
459
+ const set = (element, key, value) => {
460
+ rawSet(element.dom, key, value);
461
+ };
462
+ const remove = (element, key) => {
463
+ element.dom.removeAttribute(key);
253
464
  };
254
465
 
255
466
  var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
256
467
 
257
468
  var global$2 = tinymce.util.Tools.resolve('tinymce.util.URI');
258
469
 
259
- const isNotEmpty = s => s.length > 0;
260
-
261
- const option = name => editor => editor.options.get(name);
262
- const register$2 = editor => {
263
- const registerOption = editor.options.register;
264
- registerOption('image_dimensions', {
265
- processor: 'boolean',
266
- default: true
267
- });
268
- registerOption('image_advtab', {
269
- processor: 'boolean',
270
- default: false
271
- });
272
- registerOption('image_uploadtab', {
273
- processor: 'boolean',
274
- default: true
275
- });
276
- registerOption('image_prepend_url', {
277
- processor: 'string',
278
- default: ''
279
- });
280
- registerOption('image_class_list', { processor: 'object[]' });
281
- registerOption('image_description', {
282
- processor: 'boolean',
283
- default: true
284
- });
285
- registerOption('image_title', {
286
- processor: 'boolean',
287
- default: false
288
- });
289
- registerOption('image_caption', {
290
- processor: 'boolean',
291
- default: false
292
- });
293
- registerOption('image_list', {
294
- processor: value => {
295
- const valid = value === false || isString(value) || isArrayOf(value, isObject) || isFunction(value);
296
- return valid ? {
297
- value,
298
- valid
299
- } : {
300
- valid: false,
301
- message: 'Must be false, a string, an array or a function.'
302
- };
303
- },
304
- default: false
305
- });
470
+ const option = (name) => (editor) => editor.options.get(name);
471
+ const register$2 = (editor) => {
472
+ const registerOption = editor.options.register;
473
+ registerOption('image_dimensions', {
474
+ processor: 'boolean',
475
+ default: true
476
+ });
477
+ registerOption('image_advtab', {
478
+ processor: 'boolean',
479
+ default: false
480
+ });
481
+ registerOption('image_uploadtab', {
482
+ processor: 'boolean',
483
+ default: true
484
+ });
485
+ registerOption('image_prepend_url', {
486
+ processor: 'string',
487
+ default: ''
488
+ });
489
+ registerOption('image_class_list', {
490
+ processor: 'object[]'
491
+ });
492
+ registerOption('image_description', {
493
+ processor: 'boolean',
494
+ default: true
495
+ });
496
+ registerOption('image_title', {
497
+ processor: 'boolean',
498
+ default: false
499
+ });
500
+ registerOption('image_caption', {
501
+ processor: 'boolean',
502
+ default: false
503
+ });
504
+ registerOption('image_list', {
505
+ processor: (value) => {
506
+ const valid = value === false || isString(value) || isArrayOf(value, isObject) || isFunction(value);
507
+ return valid ? { value, valid } : { valid: false, message: 'Must be false, a string, an array or a function.' };
508
+ },
509
+ default: false
510
+ });
306
511
  };
307
512
  const hasDimensions = option('image_dimensions');
308
513
  const hasAdvTab = option('image_advtab');
@@ -315,1191 +520,1170 @@
315
520
  const getImageList = option('image_list');
316
521
  const showAccessibilityOptions = option('a11y_advanced_options');
317
522
  const isAutomaticUploadsEnabled = option('automatic_uploads');
318
- const hasUploadUrl = editor => isNotEmpty(editor.options.get('images_upload_url'));
319
- const hasUploadHandler = editor => isNonNullable(editor.options.get('images_upload_handler'));
523
+ const hasUploadUrl = (editor) => isNotEmpty(editor.options.get('images_upload_url'));
524
+ const hasUploadHandler = (editor) => isNonNullable(editor.options.get('images_upload_handler'));
320
525
 
526
+ // TODO: Figure out if these would ever be something other than numbers. This was added in: #TINY-1350
321
527
  const parseIntAndGetMax = (val1, val2) => Math.max(parseInt(val1, 10), parseInt(val2, 10));
322
- const getImageSize = url => new Promise(callback => {
323
- const img = document.createElement('img');
324
- const done = dimensions => {
325
- img.onload = img.onerror = null;
326
- if (img.parentNode) {
327
- img.parentNode.removeChild(img);
328
- }
329
- callback(dimensions);
330
- };
331
- img.onload = () => {
332
- const width = parseIntAndGetMax(img.width, img.clientWidth);
333
- const height = parseIntAndGetMax(img.height, img.clientHeight);
334
- const dimensions = {
335
- width,
336
- height
528
+ const getImageSize = (url) => new Promise((callback) => {
529
+ const img = document.createElement('img');
530
+ const done = (dimensions) => {
531
+ if (img.parentNode) {
532
+ img.parentNode.removeChild(img);
533
+ }
534
+ callback(dimensions);
337
535
  };
338
- done(Promise.resolve(dimensions));
339
- };
340
- img.onerror = () => {
341
- done(Promise.reject(`Failed to get image dimensions for: ${ url }`));
342
- };
343
- const style = img.style;
344
- style.visibility = 'hidden';
345
- style.position = 'fixed';
346
- style.bottom = style.left = '0px';
347
- style.width = style.height = 'auto';
348
- document.body.appendChild(img);
349
- img.src = url;
536
+ img.addEventListener('load', () => {
537
+ const width = parseIntAndGetMax(img.width, img.clientWidth);
538
+ const height = parseIntAndGetMax(img.height, img.clientHeight);
539
+ const dimensions = { width, height };
540
+ done(Promise.resolve(dimensions));
541
+ });
542
+ img.addEventListener('error', () => {
543
+ done(Promise.reject(`Failed to get image dimensions for: ${url}`));
544
+ });
545
+ const style = img.style;
546
+ style.visibility = 'hidden';
547
+ style.position = 'fixed';
548
+ style.bottom = style.left = '0px';
549
+ style.width = style.height = 'auto';
550
+ document.body.appendChild(img);
551
+ img.src = url;
350
552
  });
351
- const removePixelSuffix = value => {
352
- if (value) {
353
- value = value.replace(/px$/, '');
354
- }
355
- return value;
356
- };
357
- const addPixelSuffix = value => {
358
- if (value.length > 0 && /^[0-9]+$/.test(value)) {
359
- value += 'px';
360
- }
361
- return value;
362
- };
363
- const mergeMargins = css => {
364
- if (css.margin) {
365
- const splitMargin = String(css.margin).split(' ');
366
- switch (splitMargin.length) {
367
- case 1:
368
- css['margin-top'] = css['margin-top'] || splitMargin[0];
369
- css['margin-right'] = css['margin-right'] || splitMargin[0];
370
- css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
371
- css['margin-left'] = css['margin-left'] || splitMargin[0];
372
- break;
373
- case 2:
374
- css['margin-top'] = css['margin-top'] || splitMargin[0];
375
- css['margin-right'] = css['margin-right'] || splitMargin[1];
376
- css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
377
- css['margin-left'] = css['margin-left'] || splitMargin[1];
378
- break;
379
- case 3:
380
- css['margin-top'] = css['margin-top'] || splitMargin[0];
381
- css['margin-right'] = css['margin-right'] || splitMargin[1];
382
- css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
383
- css['margin-left'] = css['margin-left'] || splitMargin[1];
384
- break;
385
- case 4:
386
- css['margin-top'] = css['margin-top'] || splitMargin[0];
387
- css['margin-right'] = css['margin-right'] || splitMargin[1];
388
- css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
389
- css['margin-left'] = css['margin-left'] || splitMargin[3];
390
- }
391
- delete css.margin;
392
- }
393
- return css;
553
+ const removePixelSuffix = (value) => {
554
+ if (value) {
555
+ value = value.replace(/px$/, '');
556
+ }
557
+ return value;
558
+ };
559
+ const addPixelSuffix = (value) => {
560
+ if (value.length > 0 && /^[0-9]+$/.test(value)) {
561
+ value += 'px';
562
+ }
563
+ return value;
564
+ };
565
+ const mergeMargins = (css) => {
566
+ if (css.margin) {
567
+ const splitMargin = String(css.margin).split(' ');
568
+ switch (splitMargin.length) {
569
+ case 1: // margin: toprightbottomleft;
570
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
571
+ css['margin-right'] = css['margin-right'] || splitMargin[0];
572
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
573
+ css['margin-left'] = css['margin-left'] || splitMargin[0];
574
+ break;
575
+ case 2: // margin: topbottom rightleft;
576
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
577
+ css['margin-right'] = css['margin-right'] || splitMargin[1];
578
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[0];
579
+ css['margin-left'] = css['margin-left'] || splitMargin[1];
580
+ break;
581
+ case 3: // margin: top rightleft bottom;
582
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
583
+ css['margin-right'] = css['margin-right'] || splitMargin[1];
584
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
585
+ css['margin-left'] = css['margin-left'] || splitMargin[1];
586
+ break;
587
+ case 4: // margin: top right bottom left;
588
+ css['margin-top'] = css['margin-top'] || splitMargin[0];
589
+ css['margin-right'] = css['margin-right'] || splitMargin[1];
590
+ css['margin-bottom'] = css['margin-bottom'] || splitMargin[2];
591
+ css['margin-left'] = css['margin-left'] || splitMargin[3];
592
+ }
593
+ delete css.margin;
594
+ }
595
+ return css;
394
596
  };
597
+ // TODO: Input on this callback should really be validated
395
598
  const createImageList = (editor, callback) => {
396
- const imageList = getImageList(editor);
397
- if (isString(imageList)) {
398
- fetch(imageList).then(res => {
399
- if (res.ok) {
400
- res.json().then(callback);
401
- }
402
- });
403
- } else if (isFunction(imageList)) {
404
- imageList(callback);
405
- } else {
406
- callback(imageList);
407
- }
599
+ const imageList = getImageList(editor);
600
+ if (isString(imageList)) {
601
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
602
+ fetch(imageList)
603
+ .then((res) => {
604
+ if (res.ok) {
605
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
606
+ res.json().then(callback);
607
+ }
608
+ });
609
+ }
610
+ else if (isFunction(imageList)) {
611
+ imageList(callback);
612
+ }
613
+ else {
614
+ callback(imageList);
615
+ }
408
616
  };
409
617
  const waitLoadImage = (editor, data, imgElm) => {
410
- const selectImage = () => {
411
- imgElm.onload = imgElm.onerror = null;
412
- if (editor.selection) {
413
- editor.selection.select(imgElm);
414
- editor.nodeChanged();
415
- }
416
- };
417
- imgElm.onload = () => {
418
- if (!data.width && !data.height && hasDimensions(editor)) {
419
- editor.dom.setAttribs(imgElm, {
420
- width: String(imgElm.clientWidth),
421
- height: String(imgElm.clientHeight)
422
- });
423
- }
424
- selectImage();
425
- };
426
- imgElm.onerror = selectImage;
427
- };
428
- const blobToDataUri = blob => new Promise((resolve, reject) => {
429
- const reader = new FileReader();
430
- reader.onload = () => {
431
- resolve(reader.result);
432
- };
433
- reader.onerror = () => {
434
- var _a;
435
- reject((_a = reader.error) === null || _a === void 0 ? void 0 : _a.message);
436
- };
437
- reader.readAsDataURL(blob);
618
+ const selectImage = () => {
619
+ imgElm.onload = imgElm.onerror = null;
620
+ if (editor.selection) {
621
+ editor.selection.select(imgElm);
622
+ editor.nodeChanged();
623
+ }
624
+ };
625
+ imgElm.onload = () => {
626
+ if (!data.width && !data.height && hasDimensions(editor)) {
627
+ editor.dom.setAttribs(imgElm, {
628
+ width: String(imgElm.clientWidth),
629
+ height: String(imgElm.clientHeight)
630
+ });
631
+ }
632
+ selectImage();
633
+ };
634
+ imgElm.onerror = selectImage;
635
+ };
636
+ const blobToDataUri = (blob) => new Promise((resolve, reject) => {
637
+ const reader = new FileReader();
638
+ reader.onload = () => {
639
+ resolve(reader.result);
640
+ };
641
+ reader.onerror = () => {
642
+ var _a;
643
+ reject((_a = reader.error) === null || _a === void 0 ? void 0 : _a.message);
644
+ };
645
+ reader.readAsDataURL(blob);
438
646
  });
439
- const isPlaceholderImage = imgElm => imgElm.nodeName === 'IMG' && (imgElm.hasAttribute('data-mce-object') || imgElm.hasAttribute('data-mce-placeholder'));
647
+ const isPlaceholderImage = (imgElm) => imgElm.nodeName === 'IMG' && (imgElm.hasAttribute('data-mce-object') || imgElm.hasAttribute('data-mce-placeholder'));
440
648
  const isSafeImageUrl = (editor, src) => {
441
- const getOption = editor.options.get;
442
- return global$2.isDomSafe(src, 'img', {
443
- allow_html_data_urls: getOption('allow_html_data_urls'),
444
- allow_script_urls: getOption('allow_script_urls'),
445
- allow_svg_data_urls: getOption('allow_svg_data_urls')
446
- });
649
+ const getOption = editor.options.get;
650
+ return global$2.isDomSafe(src, 'img', {
651
+ allow_html_data_urls: getOption('allow_html_data_urls'),
652
+ allow_script_urls: getOption('allow_script_urls'),
653
+ allow_svg_data_urls: getOption('allow_svg_data_urls')
654
+ });
447
655
  };
448
656
 
449
657
  const DOM = global$3.DOM;
450
- const getHspace = image => {
451
- if (image.style.marginLeft && image.style.marginRight && image.style.marginLeft === image.style.marginRight) {
452
- return removePixelSuffix(image.style.marginLeft);
453
- } else {
454
- return '';
455
- }
456
- };
457
- const getVspace = image => {
458
- if (image.style.marginTop && image.style.marginBottom && image.style.marginTop === image.style.marginBottom) {
459
- return removePixelSuffix(image.style.marginTop);
460
- } else {
461
- return '';
462
- }
463
- };
464
- const getBorder = image => {
465
- if (image.style.borderWidth) {
466
- return removePixelSuffix(image.style.borderWidth);
467
- } else {
468
- return '';
469
- }
658
+ const getHspace = (image) => {
659
+ if (image.style.marginLeft && image.style.marginRight && image.style.marginLeft === image.style.marginRight) {
660
+ return removePixelSuffix(image.style.marginLeft);
661
+ }
662
+ else {
663
+ return '';
664
+ }
665
+ };
666
+ const getVspace = (image) => {
667
+ if (image.style.marginTop && image.style.marginBottom && image.style.marginTop === image.style.marginBottom) {
668
+ return removePixelSuffix(image.style.marginTop);
669
+ }
670
+ else {
671
+ return '';
672
+ }
673
+ };
674
+ const getBorder = (image) => {
675
+ if (image.style.borderWidth) {
676
+ return removePixelSuffix(image.style.borderWidth);
677
+ }
678
+ else {
679
+ return '';
680
+ }
470
681
  };
471
682
  const getAttrib = (image, name) => {
472
- var _a;
473
- if (image.hasAttribute(name)) {
474
- return (_a = image.getAttribute(name)) !== null && _a !== void 0 ? _a : '';
475
- } else {
476
- return '';
477
- }
478
- };
479
- const hasCaption = image => image.parentNode !== null && image.parentNode.nodeName === 'FIGURE';
683
+ var _a;
684
+ if (image.hasAttribute(name)) {
685
+ return (_a = image.getAttribute(name)) !== null && _a !== void 0 ? _a : '';
686
+ }
687
+ else {
688
+ return '';
689
+ }
690
+ };
691
+ const hasCaption = (image) => image.parentNode !== null && image.parentNode.nodeName === 'FIGURE';
480
692
  const updateAttrib = (image, name, value) => {
481
- if (value === '' || value === null) {
482
- image.removeAttribute(name);
483
- } else {
484
- image.setAttribute(name, value);
485
- }
486
- };
487
- const wrapInFigure = image => {
488
- const figureElm = DOM.create('figure', { class: 'image' });
489
- DOM.insertAfter(figureElm, image);
490
- figureElm.appendChild(image);
491
- figureElm.appendChild(DOM.create('figcaption', { contentEditable: 'true' }, 'Caption'));
492
- figureElm.contentEditable = 'false';
493
- };
494
- const removeFigure = image => {
495
- const figureElm = image.parentNode;
496
- if (isNonNullable(figureElm)) {
497
- DOM.insertAfter(image, figureElm);
498
- DOM.remove(figureElm);
499
- }
500
- };
501
- const toggleCaption = image => {
502
- if (hasCaption(image)) {
503
- removeFigure(image);
504
- } else {
505
- wrapInFigure(image);
506
- }
693
+ if (value === '' || value === null) {
694
+ image.removeAttribute(name);
695
+ }
696
+ else {
697
+ image.setAttribute(name, value);
698
+ }
699
+ };
700
+ const wrapInFigure = (image) => {
701
+ const figureElm = DOM.create('figure', { class: 'image' });
702
+ DOM.insertAfter(figureElm, image);
703
+ figureElm.appendChild(image);
704
+ figureElm.appendChild(DOM.create('figcaption', { contentEditable: 'true' }, 'Caption'));
705
+ figureElm.contentEditable = 'false';
706
+ };
707
+ const removeFigure = (image) => {
708
+ const figureElm = image.parentNode;
709
+ if (isNonNullable(figureElm)) {
710
+ DOM.insertAfter(image, figureElm);
711
+ DOM.remove(figureElm);
712
+ }
713
+ };
714
+ const toggleCaption = (image) => {
715
+ if (hasCaption(image)) {
716
+ removeFigure(image);
717
+ }
718
+ else {
719
+ wrapInFigure(image);
720
+ }
507
721
  };
508
722
  const normalizeStyle = (image, normalizeCss) => {
509
- const attrValue = image.getAttribute('style');
510
- const value = normalizeCss(attrValue !== null ? attrValue : '');
511
- if (value.length > 0) {
512
- image.setAttribute('style', value);
513
- image.setAttribute('data-mce-style', value);
514
- } else {
515
- image.removeAttribute('style');
516
- }
723
+ const attrValue = image.getAttribute('style');
724
+ const value = normalizeCss(attrValue !== null ? attrValue : '');
725
+ if (value.length > 0) {
726
+ image.setAttribute('style', value);
727
+ image.setAttribute('data-mce-style', value);
728
+ }
729
+ else {
730
+ image.removeAttribute('style');
731
+ }
517
732
  };
518
733
  const setSize = (name, normalizeCss) => (image, name, value) => {
519
- const styles = image.style;
520
- if (styles[name]) {
521
- styles[name] = addPixelSuffix(value);
522
- normalizeStyle(image, normalizeCss);
523
- } else {
524
- updateAttrib(image, name, value);
525
- }
734
+ const styles = image.style;
735
+ if (styles[name]) {
736
+ styles[name] = addPixelSuffix(value);
737
+ normalizeStyle(image, normalizeCss);
738
+ }
739
+ else {
740
+ updateAttrib(image, name, value);
741
+ }
526
742
  };
527
743
  const getSize = (image, name) => {
528
- if (image.style[name]) {
529
- return removePixelSuffix(image.style[name]);
530
- } else {
531
- return getAttrib(image, name);
532
- }
744
+ if (image.style[name]) {
745
+ return removePixelSuffix(image.style[name]);
746
+ }
747
+ else {
748
+ return getAttrib(image, name);
749
+ }
533
750
  };
534
751
  const setHspace = (image, value) => {
535
- const pxValue = addPixelSuffix(value);
536
- image.style.marginLeft = pxValue;
537
- image.style.marginRight = pxValue;
752
+ const pxValue = addPixelSuffix(value);
753
+ image.style.marginLeft = pxValue;
754
+ image.style.marginRight = pxValue;
538
755
  };
539
756
  const setVspace = (image, value) => {
540
- const pxValue = addPixelSuffix(value);
541
- image.style.marginTop = pxValue;
542
- image.style.marginBottom = pxValue;
757
+ const pxValue = addPixelSuffix(value);
758
+ image.style.marginTop = pxValue;
759
+ image.style.marginBottom = pxValue;
543
760
  };
544
761
  const setBorder = (image, value) => {
545
- const pxValue = addPixelSuffix(value);
546
- image.style.borderWidth = pxValue;
762
+ const pxValue = addPixelSuffix(value);
763
+ image.style.borderWidth = pxValue;
547
764
  };
548
765
  const setBorderStyle = (image, value) => {
549
- image.style.borderStyle = value;
550
- };
551
- const getBorderStyle = image => {
552
- var _a;
553
- return (_a = image.style.borderStyle) !== null && _a !== void 0 ? _a : '';
554
- };
555
- const isFigure = elm => isNonNullable(elm) && elm.nodeName === 'FIGURE';
556
- const isImage = elm => elm.nodeName === 'IMG';
557
- const getIsDecorative = image => DOM.getAttrib(image, 'alt').length === 0 && DOM.getAttrib(image, 'role') === 'presentation';
558
- const getAlt = image => {
559
- if (getIsDecorative(image)) {
560
- return '';
561
- } else {
562
- return getAttrib(image, 'alt');
563
- }
766
+ image.style.borderStyle = value;
767
+ };
768
+ const getBorderStyle = (image) => { var _a; return (_a = image.style.borderStyle) !== null && _a !== void 0 ? _a : ''; };
769
+ const isFigure = (elm) => isNonNullable(elm) && elm.nodeName === 'FIGURE';
770
+ const isImage = (elm) => elm.nodeName === 'IMG';
771
+ const getIsDecorative = (image) => DOM.getAttrib(image, 'alt').length === 0 && DOM.getAttrib(image, 'role') === 'presentation';
772
+ const getAlt = (image) => {
773
+ if (getIsDecorative(image)) {
774
+ return '';
775
+ }
776
+ else {
777
+ return getAttrib(image, 'alt');
778
+ }
564
779
  };
565
780
  const defaultData = () => ({
566
- src: '',
567
- alt: '',
568
- title: '',
569
- width: '',
570
- height: '',
571
- class: '',
572
- style: '',
573
- caption: false,
574
- hspace: '',
575
- vspace: '',
576
- border: '',
577
- borderStyle: '',
578
- isDecorative: false
781
+ src: '',
782
+ alt: '',
783
+ title: '',
784
+ width: '',
785
+ height: '',
786
+ class: '',
787
+ style: '',
788
+ caption: false,
789
+ hspace: '',
790
+ vspace: '',
791
+ border: '',
792
+ borderStyle: '',
793
+ isDecorative: false
579
794
  });
580
795
  const getStyleValue = (normalizeCss, data) => {
581
- var _a;
582
- const image = document.createElement('img');
583
- updateAttrib(image, 'style', data.style);
584
- if (getHspace(image) || data.hspace !== '') {
585
- setHspace(image, data.hspace);
586
- }
587
- if (getVspace(image) || data.vspace !== '') {
588
- setVspace(image, data.vspace);
589
- }
590
- if (getBorder(image) || data.border !== '') {
591
- setBorder(image, data.border);
592
- }
593
- if (getBorderStyle(image) || data.borderStyle !== '') {
594
- setBorderStyle(image, data.borderStyle);
595
- }
596
- return normalizeCss((_a = image.getAttribute('style')) !== null && _a !== void 0 ? _a : '');
796
+ var _a;
797
+ const image = document.createElement('img');
798
+ updateAttrib(image, 'style', data.style);
799
+ if (getHspace(image) || data.hspace !== '') {
800
+ setHspace(image, data.hspace);
801
+ }
802
+ if (getVspace(image) || data.vspace !== '') {
803
+ setVspace(image, data.vspace);
804
+ }
805
+ if (getBorder(image) || data.border !== '') {
806
+ setBorder(image, data.border);
807
+ }
808
+ if (getBorderStyle(image) || data.borderStyle !== '') {
809
+ setBorderStyle(image, data.borderStyle);
810
+ }
811
+ return normalizeCss((_a = image.getAttribute('style')) !== null && _a !== void 0 ? _a : '');
597
812
  };
598
813
  const create = (normalizeCss, data) => {
599
- const image = document.createElement('img');
600
- write(normalizeCss, {
601
- ...data,
602
- caption: false
603
- }, image);
604
- setAlt(image, data.alt, data.isDecorative);
605
- if (data.caption) {
606
- const figure = DOM.create('figure', { class: 'image' });
607
- figure.appendChild(image);
608
- figure.appendChild(DOM.create('figcaption', { contentEditable: 'true' }, 'Caption'));
609
- figure.contentEditable = 'false';
610
- return figure;
611
- } else {
612
- return image;
613
- }
814
+ const image = document.createElement('img');
815
+ write(normalizeCss, { ...data, caption: false }, image);
816
+ // Always set alt even if data.alt is an empty string
817
+ setAlt(image, data.alt, data.isDecorative);
818
+ if (data.caption) {
819
+ const figure = DOM.create('figure', { class: 'image' });
820
+ figure.appendChild(image);
821
+ figure.appendChild(DOM.create('figcaption', { contentEditable: 'true' }, 'Caption'));
822
+ figure.contentEditable = 'false';
823
+ return figure;
824
+ }
825
+ else {
826
+ return image;
827
+ }
614
828
  };
615
829
  const read = (normalizeCss, image) => ({
616
- src: getAttrib(image, 'src'),
617
- alt: getAlt(image),
618
- title: getAttrib(image, 'title'),
619
- width: getSize(image, 'width'),
620
- height: getSize(image, 'height'),
621
- class: getAttrib(image, 'class'),
622
- style: normalizeCss(getAttrib(image, 'style')),
623
- caption: hasCaption(image),
624
- hspace: getHspace(image),
625
- vspace: getVspace(image),
626
- border: getBorder(image),
627
- borderStyle: getBorderStyle(image),
628
- isDecorative: getIsDecorative(image)
830
+ src: getAttrib(image, 'src'),
831
+ alt: getAlt(image),
832
+ title: getAttrib(image, 'title'),
833
+ width: getSize(image, 'width'),
834
+ height: getSize(image, 'height'),
835
+ class: getAttrib(image, 'class'),
836
+ style: normalizeCss(getAttrib(image, 'style')),
837
+ caption: hasCaption(image),
838
+ hspace: getHspace(image),
839
+ vspace: getVspace(image),
840
+ border: getBorder(image),
841
+ borderStyle: getBorderStyle(image),
842
+ isDecorative: getIsDecorative(image)
629
843
  });
630
844
  const updateProp = (image, oldData, newData, name, set) => {
631
- if (newData[name] !== oldData[name]) {
632
- set(image, name, String(newData[name]));
633
- }
845
+ if (newData[name] !== oldData[name]) {
846
+ set(image, name, String(newData[name]));
847
+ }
634
848
  };
635
849
  const setAlt = (image, alt, isDecorative) => {
636
- if (isDecorative) {
637
- DOM.setAttrib(image, 'role', 'presentation');
638
- const sugarImage = SugarElement.fromDom(image);
639
- set(sugarImage, 'alt', '');
640
- } else {
641
- if (isNull(alt)) {
642
- const sugarImage = SugarElement.fromDom(image);
643
- remove(sugarImage, 'alt');
644
- } else {
645
- const sugarImage = SugarElement.fromDom(image);
646
- set(sugarImage, 'alt', alt);
647
- }
648
- if (DOM.getAttrib(image, 'role') === 'presentation') {
649
- DOM.setAttrib(image, 'role', '');
650
- }
651
- }
850
+ if (isDecorative) {
851
+ DOM.setAttrib(image, 'role', 'presentation');
852
+ // unfortunately can't set "" attr value with domutils
853
+ const sugarImage = SugarElement.fromDom(image);
854
+ set(sugarImage, 'alt', '');
855
+ }
856
+ else {
857
+ if (isNull(alt)) {
858
+ const sugarImage = SugarElement.fromDom(image);
859
+ remove(sugarImage, 'alt');
860
+ }
861
+ else {
862
+ // unfortunately can't set "" attr value with domutils
863
+ const sugarImage = SugarElement.fromDom(image);
864
+ set(sugarImage, 'alt', alt);
865
+ }
866
+ if (DOM.getAttrib(image, 'role') === 'presentation') {
867
+ DOM.setAttrib(image, 'role', '');
868
+ }
869
+ }
652
870
  };
653
871
  const updateAlt = (image, oldData, newData) => {
654
- if (newData.alt !== oldData.alt || newData.isDecorative !== oldData.isDecorative) {
655
- setAlt(image, newData.alt, newData.isDecorative);
656
- }
872
+ if (newData.alt !== oldData.alt || newData.isDecorative !== oldData.isDecorative) {
873
+ setAlt(image, newData.alt, newData.isDecorative);
874
+ }
657
875
  };
658
876
  const normalized = (set, normalizeCss) => (image, name, value) => {
659
- set(image, value);
660
- normalizeStyle(image, normalizeCss);
877
+ set(image, value);
878
+ normalizeStyle(image, normalizeCss);
661
879
  };
662
880
  const write = (normalizeCss, newData, image) => {
663
- const oldData = read(normalizeCss, image);
664
- updateProp(image, oldData, newData, 'caption', (image, _name, _value) => toggleCaption(image));
665
- updateProp(image, oldData, newData, 'src', updateAttrib);
666
- updateProp(image, oldData, newData, 'title', updateAttrib);
667
- updateProp(image, oldData, newData, 'width', setSize('width', normalizeCss));
668
- updateProp(image, oldData, newData, 'height', setSize('height', normalizeCss));
669
- updateProp(image, oldData, newData, 'class', updateAttrib);
670
- updateProp(image, oldData, newData, 'style', normalized((image, value) => updateAttrib(image, 'style', value), normalizeCss));
671
- updateProp(image, oldData, newData, 'hspace', normalized(setHspace, normalizeCss));
672
- updateProp(image, oldData, newData, 'vspace', normalized(setVspace, normalizeCss));
673
- updateProp(image, oldData, newData, 'border', normalized(setBorder, normalizeCss));
674
- updateProp(image, oldData, newData, 'borderStyle', normalized(setBorderStyle, normalizeCss));
675
- updateAlt(image, oldData, newData);
881
+ const oldData = read(normalizeCss, image);
882
+ updateProp(image, oldData, newData, 'caption', (image, _name, _value) => toggleCaption(image));
883
+ updateProp(image, oldData, newData, 'src', updateAttrib);
884
+ updateProp(image, oldData, newData, 'title', updateAttrib);
885
+ updateProp(image, oldData, newData, 'width', setSize('width', normalizeCss));
886
+ updateProp(image, oldData, newData, 'height', setSize('height', normalizeCss));
887
+ updateProp(image, oldData, newData, 'class', updateAttrib);
888
+ updateProp(image, oldData, newData, 'style', normalized((image, value) => updateAttrib(image, 'style', value), normalizeCss));
889
+ updateProp(image, oldData, newData, 'hspace', normalized(setHspace, normalizeCss));
890
+ updateProp(image, oldData, newData, 'vspace', normalized(setVspace, normalizeCss));
891
+ updateProp(image, oldData, newData, 'border', normalized(setBorder, normalizeCss));
892
+ updateProp(image, oldData, newData, 'borderStyle', normalized(setBorderStyle, normalizeCss));
893
+ updateAlt(image, oldData, newData);
676
894
  };
677
895
 
678
896
  const normalizeCss$1 = (editor, cssText) => {
679
- const css = editor.dom.styles.parse(cssText);
680
- const mergedCss = mergeMargins(css);
681
- const compressed = editor.dom.styles.parse(editor.dom.styles.serialize(mergedCss));
682
- return editor.dom.styles.serialize(compressed);
683
- };
684
- const getSelectedImage = editor => {
685
- const imgElm = editor.selection.getNode();
686
- const figureElm = editor.dom.getParent(imgElm, 'figure.image');
687
- if (figureElm) {
688
- return editor.dom.select('img', figureElm)[0];
689
- }
690
- if (imgElm && (imgElm.nodeName !== 'IMG' || isPlaceholderImage(imgElm))) {
691
- return null;
692
- }
693
- return imgElm;
897
+ const css = editor.dom.styles.parse(cssText);
898
+ const mergedCss = mergeMargins(css);
899
+ const compressed = editor.dom.styles.parse(editor.dom.styles.serialize(mergedCss));
900
+ return editor.dom.styles.serialize(compressed);
901
+ };
902
+ const getSelectedImage = (editor) => {
903
+ const imgElm = editor.selection.getNode();
904
+ const figureElm = editor.dom.getParent(imgElm, 'figure.image');
905
+ if (figureElm) {
906
+ return editor.dom.select('img', figureElm)[0];
907
+ }
908
+ if (imgElm && (imgElm.nodeName !== 'IMG' || isPlaceholderImage(imgElm))) {
909
+ return null;
910
+ }
911
+ return imgElm;
694
912
  };
695
913
  const splitTextBlock = (editor, figure) => {
696
- var _a;
697
- const dom = editor.dom;
698
- const textBlockElements = filter(editor.schema.getTextBlockElements(), (_, parentElm) => !editor.schema.isValidChild(parentElm, 'figure'));
699
- const textBlock = dom.getParent(figure.parentNode, node => hasNonNullableKey(textBlockElements, node.nodeName), editor.getBody());
700
- if (textBlock) {
701
- return (_a = dom.split(textBlock, figure)) !== null && _a !== void 0 ? _a : figure;
702
- } else {
703
- return figure;
704
- }
705
- };
706
- const readImageDataFromSelection = editor => {
707
- const image = getSelectedImage(editor);
708
- return image ? read(css => normalizeCss$1(editor, css), image) : defaultData();
914
+ var _a;
915
+ const dom = editor.dom;
916
+ const textBlockElements = filter(editor.schema.getTextBlockElements(), (_, parentElm) => !editor.schema.isValidChild(parentElm, 'figure'));
917
+ const textBlock = dom.getParent(figure.parentNode, (node) => hasNonNullableKey(textBlockElements, node.nodeName), editor.getBody());
918
+ if (textBlock) {
919
+ return (_a = dom.split(textBlock, figure)) !== null && _a !== void 0 ? _a : figure;
920
+ }
921
+ else {
922
+ return figure;
923
+ }
924
+ };
925
+ const readImageDataFromSelection = (editor) => {
926
+ const image = getSelectedImage(editor);
927
+ return image ? read((css) => normalizeCss$1(editor, css), image) : defaultData();
709
928
  };
710
929
  const insertImageAtCaret = (editor, data) => {
711
- const elm = create(css => normalizeCss$1(editor, css), data);
712
- editor.dom.setAttrib(elm, 'data-mce-id', '__mcenew');
713
- editor.focus();
714
- editor.selection.setContent(elm.outerHTML);
715
- const insertedElm = editor.dom.select('*[data-mce-id="__mcenew"]')[0];
716
- editor.dom.setAttrib(insertedElm, 'data-mce-id', null);
717
- if (isFigure(insertedElm)) {
718
- const figure = splitTextBlock(editor, insertedElm);
719
- editor.selection.select(figure);
720
- } else {
721
- editor.selection.select(insertedElm);
722
- }
930
+ const elm = create((css) => normalizeCss$1(editor, css), data);
931
+ editor.dom.setAttrib(elm, 'data-mce-id', '__mcenew');
932
+ editor.focus();
933
+ editor.selection.setContent(elm.outerHTML);
934
+ const insertedElm = editor.dom.select('*[data-mce-id="__mcenew"]')[0];
935
+ editor.dom.setAttrib(insertedElm, 'data-mce-id', null);
936
+ if (isFigure(insertedElm)) {
937
+ const figure = splitTextBlock(editor, insertedElm);
938
+ editor.selection.select(figure);
939
+ }
940
+ else {
941
+ editor.selection.select(insertedElm);
942
+ }
723
943
  };
724
944
  const syncSrcAttr = (editor, image) => {
725
- editor.dom.setAttrib(image, 'src', image.getAttribute('src'));
945
+ editor.dom.setAttrib(image, 'src', image.getAttribute('src'));
726
946
  };
727
947
  const deleteImage = (editor, image) => {
728
- if (image) {
729
- const elm = editor.dom.is(image.parentNode, 'figure.image') ? image.parentNode : image;
730
- editor.dom.remove(elm);
731
- editor.focus();
732
- editor.nodeChanged();
733
- if (editor.dom.isEmpty(editor.getBody())) {
734
- editor.setContent('');
735
- editor.selection.setCursorLocation();
948
+ if (image) {
949
+ const elm = editor.dom.is(image.parentNode, 'figure.image') ? image.parentNode : image;
950
+ editor.dom.remove(elm);
951
+ editor.focus();
952
+ editor.nodeChanged();
953
+ if (editor.dom.isEmpty(editor.getBody())) {
954
+ editor.setContent('');
955
+ editor.selection.setCursorLocation();
956
+ }
736
957
  }
737
- }
738
958
  };
739
959
  const writeImageDataToSelection = (editor, data) => {
740
- const image = getSelectedImage(editor);
741
- if (image) {
742
- write(css => normalizeCss$1(editor, css), data, image);
743
- syncSrcAttr(editor, image);
744
- if (isFigure(image.parentNode)) {
745
- const figure = image.parentNode;
746
- splitTextBlock(editor, figure);
747
- editor.selection.select(image.parentNode);
748
- } else {
749
- editor.selection.select(image);
750
- waitLoadImage(editor, data, image);
751
- }
752
- }
960
+ const image = getSelectedImage(editor);
961
+ if (image) {
962
+ write((css) => normalizeCss$1(editor, css), data, image);
963
+ syncSrcAttr(editor, image);
964
+ if (isFigure(image.parentNode)) {
965
+ editor.dom.setStyle(image, 'float', '');
966
+ const figure = image.parentNode;
967
+ splitTextBlock(editor, figure);
968
+ editor.selection.select(image.parentNode);
969
+ }
970
+ else {
971
+ editor.selection.select(image);
972
+ waitLoadImage(editor, data, image);
973
+ }
974
+ }
753
975
  };
754
976
  const sanitizeImageData = (editor, data) => {
755
- const src = data.src;
756
- return {
757
- ...data,
758
- src: isSafeImageUrl(editor, src) ? src : ''
759
- };
760
- };
761
- const insertOrUpdateImage = (editor, partialData) => {
762
- const image = getSelectedImage(editor);
763
- if (image) {
764
- const selectedImageData = read(css => normalizeCss$1(editor, css), image);
765
- const data = {
766
- ...selectedImageData,
767
- ...partialData
977
+ // Sanitize the URL
978
+ const src = data.src;
979
+ return {
980
+ ...data,
981
+ src: isSafeImageUrl(editor, src) ? src : ''
768
982
  };
769
- const sanitizedData = sanitizeImageData(editor, data);
770
- if (data.src) {
771
- writeImageDataToSelection(editor, sanitizedData);
772
- } else {
773
- deleteImage(editor, image);
774
- }
775
- } else if (partialData.src) {
776
- insertImageAtCaret(editor, {
777
- ...defaultData(),
778
- ...partialData
779
- });
780
- }
781
983
  };
782
-
783
- const deep = (old, nu) => {
784
- const bothObjects = isPlainObject(old) && isPlainObject(nu);
785
- return bothObjects ? deepMerge(old, nu) : nu;
786
- };
787
- const baseMerge = merger => {
788
- return (...objects) => {
789
- if (objects.length === 0) {
790
- throw new Error(`Can't merge zero objects`);
791
- }
792
- const ret = {};
793
- for (let j = 0; j < objects.length; j++) {
794
- const curObject = objects[j];
795
- for (const key in curObject) {
796
- if (has(curObject, key)) {
797
- ret[key] = merger(ret[key], curObject[key]);
984
+ const insertOrUpdateImage = (editor, partialData) => {
985
+ const image = getSelectedImage(editor);
986
+ if (image) {
987
+ const selectedImageData = read((css) => normalizeCss$1(editor, css), image);
988
+ const data = { ...selectedImageData, ...partialData };
989
+ const sanitizedData = sanitizeImageData(editor, data);
990
+ if (data.src) {
991
+ writeImageDataToSelection(editor, sanitizedData);
798
992
  }
799
- }
993
+ else {
994
+ deleteImage(editor, image);
995
+ }
996
+ }
997
+ else if (partialData.src) {
998
+ insertImageAtCaret(editor, { ...defaultData(), ...partialData });
800
999
  }
801
- return ret;
802
- };
803
1000
  };
804
- const deepMerge = baseMerge(deep);
805
1001
 
806
1002
  var global$1 = tinymce.util.Tools.resolve('tinymce.util.ImageUploader');
807
1003
 
808
1004
  var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
809
1005
 
810
- const getValue = item => isString(item.value) ? item.value : '';
811
- const getText = item => {
812
- if (isString(item.text)) {
813
- return item.text;
814
- } else if (isString(item.title)) {
815
- return item.title;
816
- } else {
817
- return '';
818
- }
1006
+ const getValue = (item) => isString(item.value) ? item.value : '';
1007
+ const getText = (item) => {
1008
+ if (isString(item.text)) {
1009
+ return item.text;
1010
+ }
1011
+ else if (isString(item.title)) {
1012
+ return item.title;
1013
+ }
1014
+ else {
1015
+ return '';
1016
+ }
819
1017
  };
820
1018
  const sanitizeList = (list, extractValue) => {
821
- const out = [];
822
- global.each(list, item => {
823
- const text = getText(item);
824
- if (item.menu !== undefined) {
825
- const items = sanitizeList(item.menu, extractValue);
826
- out.push({
827
- text,
828
- items
829
- });
830
- } else {
831
- const value = extractValue(item);
832
- out.push({
833
- text,
834
- value
835
- });
836
- }
837
- });
838
- return out;
839
- };
840
- const sanitizer = (extractor = getValue) => list => {
841
- if (list) {
842
- return Optional.from(list).map(list => sanitizeList(list, extractor));
843
- } else {
844
- return Optional.none();
845
- }
846
- };
847
- const sanitize = list => sanitizer(getValue)(list);
848
- const isGroup = item => has(item, 'items');
849
- const findEntryDelegate = (list, value) => findMap(list, item => {
850
- if (isGroup(item)) {
851
- return findEntryDelegate(item.items, value);
852
- } else if (item.value === value) {
853
- return Optional.some(item);
854
- } else {
855
- return Optional.none();
856
- }
1019
+ const out = [];
1020
+ global.each(list, (item) => {
1021
+ const text = getText(item);
1022
+ if (item.menu !== undefined) {
1023
+ const items = sanitizeList(item.menu, extractValue);
1024
+ out.push({ text, items }); // list group
1025
+ }
1026
+ else {
1027
+ const value = extractValue(item);
1028
+ out.push({ text, value }); // list value
1029
+ }
1030
+ });
1031
+ return out;
1032
+ };
1033
+ const sanitizer = (extractor = getValue) => (list) => {
1034
+ if (list) {
1035
+ return Optional.from(list).map((list) => sanitizeList(list, extractor));
1036
+ }
1037
+ else {
1038
+ return Optional.none();
1039
+ }
1040
+ };
1041
+ const sanitize = (list) => sanitizer(getValue)(list);
1042
+ const isGroup = (item) => has(item, 'items');
1043
+ const findEntryDelegate = (list, value) => findMap(list, (item) => {
1044
+ if (isGroup(item)) {
1045
+ return findEntryDelegate(item.items, value);
1046
+ }
1047
+ else if (item.value === value) {
1048
+ return Optional.some(item);
1049
+ }
1050
+ else {
1051
+ return Optional.none();
1052
+ }
857
1053
  });
858
- const findEntry = (optList, value) => optList.bind(list => findEntryDelegate(list, value));
1054
+ const findEntry = (optList, value) => optList.bind((list) => findEntryDelegate(list, value));
859
1055
  const ListUtils = {
860
- sanitizer,
861
- sanitize,
862
- findEntry
1056
+ sanitizer,
1057
+ sanitize,
1058
+ findEntry
863
1059
  };
864
1060
 
865
- const makeTab$2 = _info => ({
866
- title: 'Advanced',
867
- name: 'advanced',
868
- items: [{
869
- type: 'grid',
870
- columns: 2,
871
- items: [
872
- {
873
- type: 'input',
874
- label: 'Vertical space',
875
- name: 'vspace',
876
- inputMode: 'numeric'
877
- },
878
- {
879
- type: 'input',
880
- label: 'Horizontal space',
881
- name: 'hspace',
882
- inputMode: 'numeric'
883
- },
884
- {
885
- type: 'input',
886
- label: 'Border width',
887
- name: 'border',
888
- inputMode: 'numeric'
889
- },
1061
+ const makeTab$2 = (_info) => ({
1062
+ title: 'Advanced',
1063
+ name: 'advanced',
1064
+ items: [
890
1065
  {
891
- type: 'listbox',
892
- name: 'borderstyle',
893
- label: 'Border style',
894
- items: [
895
- {
896
- text: 'Select...',
897
- value: ''
898
- },
899
- {
900
- text: 'Solid',
901
- value: 'solid'
902
- },
903
- {
904
- text: 'Dotted',
905
- value: 'dotted'
906
- },
907
- {
908
- text: 'Dashed',
909
- value: 'dashed'
910
- },
911
- {
912
- text: 'Double',
913
- value: 'double'
914
- },
915
- {
916
- text: 'Groove',
917
- value: 'groove'
918
- },
919
- {
920
- text: 'Ridge',
921
- value: 'ridge'
922
- },
923
- {
924
- text: 'Inset',
925
- value: 'inset'
926
- },
927
- {
928
- text: 'Outset',
929
- value: 'outset'
930
- },
931
- {
932
- text: 'None',
933
- value: 'none'
934
- },
935
- {
936
- text: 'Hidden',
937
- value: 'hidden'
938
- }
939
- ]
1066
+ type: 'grid',
1067
+ columns: 2,
1068
+ items: [
1069
+ {
1070
+ type: 'input',
1071
+ label: 'Vertical space',
1072
+ name: 'vspace',
1073
+ inputMode: 'numeric'
1074
+ },
1075
+ {
1076
+ type: 'input',
1077
+ label: 'Horizontal space',
1078
+ name: 'hspace',
1079
+ inputMode: 'numeric'
1080
+ },
1081
+ {
1082
+ type: 'input',
1083
+ label: 'Border width',
1084
+ name: 'border',
1085
+ inputMode: 'numeric'
1086
+ },
1087
+ {
1088
+ type: 'listbox',
1089
+ name: 'borderstyle',
1090
+ label: 'Border style',
1091
+ items: [
1092
+ { text: 'Select...', value: '' },
1093
+ { text: 'Solid', value: 'solid' },
1094
+ { text: 'Dotted', value: 'dotted' },
1095
+ { text: 'Dashed', value: 'dashed' },
1096
+ { text: 'Double', value: 'double' },
1097
+ { text: 'Groove', value: 'groove' },
1098
+ { text: 'Ridge', value: 'ridge' },
1099
+ { text: 'Inset', value: 'inset' },
1100
+ { text: 'Outset', value: 'outset' },
1101
+ { text: 'None', value: 'none' },
1102
+ { text: 'Hidden', value: 'hidden' }
1103
+ ]
1104
+ }
1105
+ ]
940
1106
  }
941
- ]
942
- }]
1107
+ ]
943
1108
  });
944
- const AdvTab = { makeTab: makeTab$2 };
1109
+ const AdvTab = {
1110
+ makeTab: makeTab$2
1111
+ };
945
1112
 
946
- const collect = editor => {
947
- const urlListSanitizer = ListUtils.sanitizer(item => editor.convertURL(item.value || item.url || '', 'src'));
948
- const futureImageList = new Promise(completer => {
949
- createImageList(editor, imageList => {
950
- completer(urlListSanitizer(imageList).map(items => flatten([
951
- [{
952
- text: 'None',
953
- value: ''
954
- }],
955
- items
956
- ])));
1113
+ const collect = (editor) => {
1114
+ const urlListSanitizer = ListUtils.sanitizer((item) => editor.convertURL(item.value || item.url || '', 'src'));
1115
+ const futureImageList = new Promise((completer) => {
1116
+ createImageList(editor, (imageList) => {
1117
+ completer(urlListSanitizer(imageList).map((items) => flatten([
1118
+ [{ text: 'None', value: '' }],
1119
+ items
1120
+ ])));
1121
+ });
957
1122
  });
958
- });
959
- const classList = ListUtils.sanitize(getClassList(editor));
960
- const hasAdvTab$1 = hasAdvTab(editor);
961
- const hasUploadTab$1 = hasUploadTab(editor);
962
- const hasUploadUrl$1 = hasUploadUrl(editor);
963
- const hasUploadHandler$1 = hasUploadHandler(editor);
964
- const image = readImageDataFromSelection(editor);
965
- const hasDescription$1 = hasDescription(editor);
966
- const hasImageTitle$1 = hasImageTitle(editor);
967
- const hasDimensions$1 = hasDimensions(editor);
968
- const hasImageCaption$1 = hasImageCaption(editor);
969
- const hasAccessibilityOptions = showAccessibilityOptions(editor);
970
- const automaticUploads = isAutomaticUploadsEnabled(editor);
971
- const prependURL = Optional.some(getPrependUrl(editor)).filter(preUrl => isString(preUrl) && preUrl.length > 0);
972
- return futureImageList.then(imageList => ({
973
- image,
974
- imageList,
975
- classList,
976
- hasAdvTab: hasAdvTab$1,
977
- hasUploadTab: hasUploadTab$1,
978
- hasUploadUrl: hasUploadUrl$1,
979
- hasUploadHandler: hasUploadHandler$1,
980
- hasDescription: hasDescription$1,
981
- hasImageTitle: hasImageTitle$1,
982
- hasDimensions: hasDimensions$1,
983
- hasImageCaption: hasImageCaption$1,
984
- prependURL,
985
- hasAccessibilityOptions,
986
- automaticUploads
987
- }));
1123
+ const classList = ListUtils.sanitize(getClassList(editor));
1124
+ const hasAdvTab$1 = hasAdvTab(editor);
1125
+ const hasUploadTab$1 = hasUploadTab(editor);
1126
+ const hasUploadUrl$1 = hasUploadUrl(editor);
1127
+ const hasUploadHandler$1 = hasUploadHandler(editor);
1128
+ const image = readImageDataFromSelection(editor);
1129
+ const hasDescription$1 = hasDescription(editor);
1130
+ const hasImageTitle$1 = hasImageTitle(editor);
1131
+ const hasDimensions$1 = hasDimensions(editor);
1132
+ const hasImageCaption$1 = hasImageCaption(editor);
1133
+ const hasAccessibilityOptions = showAccessibilityOptions(editor);
1134
+ const automaticUploads = isAutomaticUploadsEnabled(editor);
1135
+ const prependURL = Optional.some(getPrependUrl(editor)).filter((preUrl) => isString(preUrl) && preUrl.length > 0);
1136
+ return futureImageList.then((imageList) => ({
1137
+ image,
1138
+ imageList,
1139
+ classList,
1140
+ hasAdvTab: hasAdvTab$1,
1141
+ hasUploadTab: hasUploadTab$1,
1142
+ hasUploadUrl: hasUploadUrl$1,
1143
+ hasUploadHandler: hasUploadHandler$1,
1144
+ hasDescription: hasDescription$1,
1145
+ hasImageTitle: hasImageTitle$1,
1146
+ hasDimensions: hasDimensions$1,
1147
+ hasImageCaption: hasImageCaption$1,
1148
+ prependURL,
1149
+ hasAccessibilityOptions,
1150
+ automaticUploads
1151
+ }));
988
1152
  };
989
1153
 
990
- const makeItems = info => {
991
- const imageUrl = {
992
- name: 'src',
993
- type: 'urlinput',
994
- filetype: 'image',
995
- label: 'Source',
996
- picker_text: 'Browse files'
997
- };
998
- const imageList = info.imageList.map(items => ({
999
- name: 'images',
1000
- type: 'listbox',
1001
- label: 'Image list',
1002
- items
1003
- }));
1004
- const imageDescription = {
1005
- name: 'alt',
1006
- type: 'input',
1007
- label: 'Alternative description',
1008
- enabled: !(info.hasAccessibilityOptions && info.image.isDecorative)
1009
- };
1010
- const imageTitle = {
1011
- name: 'title',
1012
- type: 'input',
1013
- label: 'Image title'
1014
- };
1015
- const imageDimensions = {
1016
- name: 'dimensions',
1017
- type: 'sizeinput'
1018
- };
1019
- const isDecorative = {
1020
- type: 'label',
1021
- label: 'Accessibility',
1022
- items: [{
1023
- name: 'isDecorative',
1024
- type: 'checkbox',
1025
- label: 'Image is decorative'
1026
- }]
1027
- };
1028
- const classList = info.classList.map(items => ({
1029
- name: 'classes',
1030
- type: 'listbox',
1031
- label: 'Class',
1032
- items
1033
- }));
1034
- const caption = {
1035
- type: 'label',
1036
- label: 'Caption',
1037
- items: [{
1038
- type: 'checkbox',
1039
- name: 'caption',
1040
- label: 'Show caption'
1041
- }]
1042
- };
1043
- const getDialogContainerType = useColumns => useColumns ? {
1044
- type: 'grid',
1045
- columns: 2
1046
- } : { type: 'panel' };
1047
- return flatten([
1048
- [imageUrl],
1049
- imageList.toArray(),
1050
- info.hasAccessibilityOptions && info.hasDescription ? [isDecorative] : [],
1051
- info.hasDescription ? [imageDescription] : [],
1052
- info.hasImageTitle ? [imageTitle] : [],
1053
- info.hasDimensions ? [imageDimensions] : [],
1054
- [{
1055
- ...getDialogContainerType(info.classList.isSome() && info.hasImageCaption),
1056
- items: flatten([
1057
- classList.toArray(),
1058
- info.hasImageCaption ? [caption] : []
1059
- ])
1060
- }]
1061
- ]);
1062
- };
1063
- const makeTab$1 = info => ({
1064
- title: 'General',
1065
- name: 'general',
1066
- items: makeItems(info)
1154
+ const makeItems = (info) => {
1155
+ const imageUrl = {
1156
+ name: 'src',
1157
+ type: 'urlinput',
1158
+ filetype: 'image',
1159
+ label: 'Source',
1160
+ picker_text: 'Browse files'
1161
+ };
1162
+ const imageList = info.imageList.map((items) => ({
1163
+ name: 'images',
1164
+ type: 'listbox',
1165
+ label: 'Image list',
1166
+ items
1167
+ }));
1168
+ const imageDescription = {
1169
+ name: 'alt',
1170
+ type: 'input',
1171
+ label: 'Alternative description',
1172
+ enabled: !(info.hasAccessibilityOptions && info.image.isDecorative)
1173
+ };
1174
+ const imageTitle = {
1175
+ name: 'title',
1176
+ type: 'input',
1177
+ label: 'Image title'
1178
+ };
1179
+ const imageDimensions = {
1180
+ name: 'dimensions',
1181
+ type: 'sizeinput'
1182
+ };
1183
+ const isDecorative = {
1184
+ type: 'label',
1185
+ label: 'Accessibility',
1186
+ items: [{
1187
+ name: 'isDecorative',
1188
+ type: 'checkbox',
1189
+ label: 'Image is decorative'
1190
+ }]
1191
+ };
1192
+ // TODO: the original listbox supported styled items but bridge does not seem to support this
1193
+ const classList = info.classList.map((items) => ({
1194
+ name: 'classes',
1195
+ type: 'listbox',
1196
+ label: 'Class',
1197
+ items
1198
+ }));
1199
+ const caption = {
1200
+ type: 'label',
1201
+ label: 'Caption',
1202
+ items: [
1203
+ {
1204
+ type: 'checkbox',
1205
+ name: 'caption',
1206
+ label: 'Show caption'
1207
+ }
1208
+ ]
1209
+ };
1210
+ const getDialogContainerType = (useColumns) => useColumns ? { type: 'grid', columns: 2 } : { type: 'panel' };
1211
+ return flatten([
1212
+ [imageUrl],
1213
+ imageList.toArray(),
1214
+ info.hasAccessibilityOptions && info.hasDescription ? [isDecorative] : [],
1215
+ info.hasDescription ? [imageDescription] : [],
1216
+ info.hasImageTitle ? [imageTitle] : [],
1217
+ info.hasDimensions ? [imageDimensions] : [],
1218
+ [{
1219
+ ...getDialogContainerType(info.classList.isSome() && info.hasImageCaption),
1220
+ items: flatten([
1221
+ classList.toArray(),
1222
+ info.hasImageCaption ? [caption] : []
1223
+ ])
1224
+ }]
1225
+ ]);
1226
+ };
1227
+ const makeTab$1 = (info) => ({
1228
+ title: 'General',
1229
+ name: 'general',
1230
+ items: makeItems(info)
1067
1231
  });
1068
1232
  const MainTab = {
1069
- makeTab: makeTab$1,
1070
- makeItems
1233
+ makeTab: makeTab$1,
1234
+ makeItems
1071
1235
  };
1072
1236
 
1073
- const makeTab = _info => {
1074
- const items = [{
1075
- type: 'dropzone',
1076
- name: 'fileinput'
1077
- }];
1078
- return {
1079
- title: 'Upload',
1080
- name: 'upload',
1081
- items
1082
- };
1083
- };
1084
- const UploadTab = { makeTab };
1237
+ const makeTab = (_info) => {
1238
+ const items = [
1239
+ {
1240
+ type: 'dropzone',
1241
+ name: 'fileinput'
1242
+ }
1243
+ ];
1244
+ return {
1245
+ title: 'Upload',
1246
+ name: 'upload',
1247
+ items
1248
+ };
1249
+ };
1250
+ const UploadTab = {
1251
+ makeTab
1252
+ };
1085
1253
 
1086
- const createState = info => ({
1087
- prevImage: ListUtils.findEntry(info.imageList, info.image.src),
1088
- prevAlt: info.image.alt,
1089
- open: true
1254
+ const createState = (info) => ({
1255
+ prevImage: ListUtils.findEntry(info.imageList, info.image.src),
1256
+ prevAlt: info.image.alt,
1257
+ open: true
1090
1258
  });
1091
- const fromImageData = image => ({
1092
- src: {
1093
- value: image.src,
1094
- meta: {}
1095
- },
1096
- images: image.src,
1097
- alt: image.alt,
1098
- title: image.title,
1099
- dimensions: {
1100
- width: image.width,
1101
- height: image.height
1102
- },
1103
- classes: image.class,
1104
- caption: image.caption,
1105
- style: image.style,
1106
- vspace: image.vspace,
1107
- border: image.border,
1108
- hspace: image.hspace,
1109
- borderstyle: image.borderStyle,
1110
- fileinput: [],
1111
- isDecorative: image.isDecorative
1259
+ const fromImageData = (image) => ({
1260
+ src: {
1261
+ value: image.src,
1262
+ meta: {}
1263
+ },
1264
+ images: image.src,
1265
+ alt: image.alt,
1266
+ title: image.title,
1267
+ dimensions: {
1268
+ width: image.width,
1269
+ height: image.height
1270
+ },
1271
+ classes: image.class,
1272
+ caption: image.caption,
1273
+ style: image.style,
1274
+ vspace: image.vspace,
1275
+ border: image.border,
1276
+ hspace: image.hspace,
1277
+ borderstyle: image.borderStyle,
1278
+ fileinput: [],
1279
+ isDecorative: image.isDecorative
1112
1280
  });
1113
1281
  const toImageData = (data, removeEmptyAlt) => ({
1114
- src: data.src.value,
1115
- alt: (data.alt === null || data.alt.length === 0) && removeEmptyAlt ? null : data.alt,
1116
- title: data.title,
1117
- width: data.dimensions.width,
1118
- height: data.dimensions.height,
1119
- class: data.classes,
1120
- style: data.style,
1121
- caption: data.caption,
1122
- hspace: data.hspace,
1123
- vspace: data.vspace,
1124
- border: data.border,
1125
- borderStyle: data.borderstyle,
1126
- isDecorative: data.isDecorative
1282
+ src: data.src.value,
1283
+ alt: (data.alt === null || data.alt.length === 0) && removeEmptyAlt ? null : data.alt,
1284
+ title: data.title,
1285
+ width: data.dimensions.width,
1286
+ height: data.dimensions.height,
1287
+ class: data.classes,
1288
+ style: data.style,
1289
+ caption: data.caption,
1290
+ hspace: data.hspace,
1291
+ vspace: data.vspace,
1292
+ border: data.border,
1293
+ borderStyle: data.borderstyle,
1294
+ isDecorative: data.isDecorative
1127
1295
  });
1128
1296
  const addPrependUrl2 = (info, srcURL) => {
1129
- if (!/^(?:[a-zA-Z]+:)?\/\//.test(srcURL)) {
1130
- return info.prependURL.bind(prependUrl => {
1131
- if (srcURL.substring(0, prependUrl.length) !== prependUrl) {
1132
- return Optional.some(prependUrl + srcURL);
1133
- }
1134
- return Optional.none();
1135
- });
1136
- }
1137
- return Optional.none();
1297
+ // Add the prependURL
1298
+ if (!/^(?:[a-zA-Z]+:)?\/\//.test(srcURL)) {
1299
+ return info.prependURL.bind((prependUrl) => {
1300
+ if (srcURL.substring(0, prependUrl.length) !== prependUrl) {
1301
+ return Optional.some(prependUrl + srcURL);
1302
+ }
1303
+ return Optional.none();
1304
+ });
1305
+ }
1306
+ return Optional.none();
1138
1307
  };
1139
1308
  const addPrependUrl = (info, api) => {
1140
- const data = api.getData();
1141
- addPrependUrl2(info, data.src.value).each(srcURL => {
1142
- api.setData({
1143
- src: {
1144
- value: srcURL,
1145
- meta: data.src.meta
1146
- }
1309
+ const data = api.getData();
1310
+ addPrependUrl2(info, data.src.value).each((srcURL) => {
1311
+ api.setData({ src: { value: srcURL, meta: data.src.meta } });
1147
1312
  });
1148
- });
1149
1313
  };
1150
1314
  const formFillFromMeta2 = (info, data, meta) => {
1151
- if (info.hasDescription && isString(meta.alt)) {
1152
- data.alt = meta.alt;
1153
- }
1154
- if (info.hasAccessibilityOptions) {
1155
- data.isDecorative = meta.isDecorative || data.isDecorative || false;
1156
- }
1157
- if (info.hasImageTitle && isString(meta.title)) {
1158
- data.title = meta.title;
1159
- }
1160
- if (info.hasDimensions) {
1161
- if (isString(meta.width)) {
1162
- data.dimensions.width = meta.width;
1163
- }
1164
- if (isString(meta.height)) {
1165
- data.dimensions.height = meta.height;
1166
- }
1167
- }
1168
- if (isString(meta.class)) {
1169
- ListUtils.findEntry(info.classList, meta.class).each(entry => {
1170
- data.classes = entry.value;
1171
- });
1172
- }
1173
- if (info.hasImageCaption) {
1174
- if (isBoolean(meta.caption)) {
1175
- data.caption = meta.caption;
1315
+ if (info.hasDescription && isString(meta.alt)) {
1316
+ data.alt = meta.alt;
1176
1317
  }
1177
- }
1178
- if (info.hasAdvTab) {
1179
- if (isString(meta.style)) {
1180
- data.style = meta.style;
1318
+ if (info.hasAccessibilityOptions) {
1319
+ data.isDecorative = meta.isDecorative || data.isDecorative || false;
1181
1320
  }
1182
- if (isString(meta.vspace)) {
1183
- data.vspace = meta.vspace;
1321
+ if (info.hasImageTitle && isString(meta.title)) {
1322
+ data.title = meta.title;
1184
1323
  }
1185
- if (isString(meta.border)) {
1186
- data.border = meta.border;
1324
+ if (info.hasDimensions) {
1325
+ if (isString(meta.width)) {
1326
+ data.dimensions.width = meta.width;
1327
+ }
1328
+ if (isString(meta.height)) {
1329
+ data.dimensions.height = meta.height;
1330
+ }
1187
1331
  }
1188
- if (isString(meta.hspace)) {
1189
- data.hspace = meta.hspace;
1332
+ if (isString(meta.class)) {
1333
+ ListUtils.findEntry(info.classList, meta.class).each((entry) => {
1334
+ data.classes = entry.value;
1335
+ });
1190
1336
  }
1191
- if (isString(meta.borderstyle)) {
1192
- data.borderstyle = meta.borderstyle;
1337
+ if (info.hasImageCaption) {
1338
+ if (isBoolean(meta.caption)) {
1339
+ data.caption = meta.caption;
1340
+ }
1341
+ }
1342
+ if (info.hasAdvTab) {
1343
+ if (isString(meta.style)) {
1344
+ data.style = meta.style;
1345
+ }
1346
+ if (isString(meta.vspace)) {
1347
+ data.vspace = meta.vspace;
1348
+ }
1349
+ if (isString(meta.border)) {
1350
+ data.border = meta.border;
1351
+ }
1352
+ if (isString(meta.hspace)) {
1353
+ data.hspace = meta.hspace;
1354
+ }
1355
+ if (isString(meta.borderstyle)) {
1356
+ data.borderstyle = meta.borderstyle;
1357
+ }
1193
1358
  }
1194
- }
1195
1359
  };
1196
1360
  const formFillFromMeta = (info, api) => {
1197
- const data = api.getData();
1198
- const meta = data.src.meta;
1199
- if (meta !== undefined) {
1200
- const newData = deepMerge({}, data);
1201
- formFillFromMeta2(info, newData, meta);
1202
- api.setData(newData);
1203
- }
1361
+ const data = api.getData();
1362
+ const meta = data.src.meta;
1363
+ if (meta !== undefined) {
1364
+ const newData = deepMerge({}, data);
1365
+ formFillFromMeta2(info, newData, meta);
1366
+ api.setData(newData);
1367
+ }
1204
1368
  };
1205
1369
  const calculateImageSize = (helpers, info, state, api) => {
1206
- const data = api.getData();
1207
- const url = data.src.value;
1208
- const meta = data.src.meta || {};
1209
- if (!meta.width && !meta.height && info.hasDimensions) {
1210
- if (isNotEmpty(url)) {
1211
- helpers.imageSize(url).then(size => {
1212
- if (state.open) {
1213
- api.setData({ dimensions: size });
1370
+ const data = api.getData();
1371
+ const url = data.src.value;
1372
+ const meta = data.src.meta || {};
1373
+ if (!meta.width && !meta.height && info.hasDimensions) {
1374
+ if (isNotEmpty(url)) {
1375
+ helpers.imageSize(url)
1376
+ .then((size) => {
1377
+ if (state.open) {
1378
+ api.setData({ dimensions: size });
1379
+ }
1380
+ })
1381
+ // eslint-disable-next-line no-console
1382
+ .catch((e) => console.error(e));
1214
1383
  }
1215
- }).catch(e => console.error(e));
1216
- } else {
1217
- api.setData({
1218
- dimensions: {
1219
- width: '',
1220
- height: ''
1384
+ else {
1385
+ api.setData({ dimensions: { width: '', height: '' } });
1221
1386
  }
1222
- });
1223
1387
  }
1224
- }
1225
1388
  };
1226
1389
  const updateImagesDropdown = (info, state, api) => {
1227
- const data = api.getData();
1228
- const image = ListUtils.findEntry(info.imageList, data.src.value);
1229
- state.prevImage = image;
1230
- api.setData({ images: image.map(entry => entry.value).getOr('') });
1390
+ const data = api.getData();
1391
+ const image = ListUtils.findEntry(info.imageList, data.src.value);
1392
+ state.prevImage = image;
1393
+ api.setData({ images: image.map((entry) => entry.value).getOr('') });
1231
1394
  };
1232
1395
  const changeSrc = (helpers, info, state, api) => {
1233
- addPrependUrl(info, api);
1234
- formFillFromMeta(info, api);
1235
- calculateImageSize(helpers, info, state, api);
1236
- updateImagesDropdown(info, state, api);
1396
+ addPrependUrl(info, api);
1397
+ formFillFromMeta(info, api);
1398
+ calculateImageSize(helpers, info, state, api);
1399
+ updateImagesDropdown(info, state, api);
1237
1400
  };
1238
1401
  const changeImages = (helpers, info, state, api) => {
1239
- const data = api.getData();
1240
- const image = ListUtils.findEntry(info.imageList, data.images);
1241
- image.each(img => {
1242
- const updateAlt = data.alt === '' || state.prevImage.map(image => image.text === data.alt).getOr(false);
1243
- if (updateAlt) {
1244
- if (img.value === '') {
1245
- api.setData({
1246
- src: img,
1247
- alt: state.prevAlt
1248
- });
1249
- } else {
1250
- api.setData({
1251
- src: img,
1252
- alt: img.text
1253
- });
1254
- }
1255
- } else {
1256
- api.setData({ src: img });
1257
- }
1258
- });
1259
- state.prevImage = image;
1260
- changeSrc(helpers, info, state, api);
1402
+ const data = api.getData();
1403
+ const image = ListUtils.findEntry(info.imageList, data.images);
1404
+ image.each((img) => {
1405
+ const updateAlt = data.alt === '' || state.prevImage.map((image) => image.text === data.alt).getOr(false);
1406
+ if (updateAlt) {
1407
+ if (img.value === '') {
1408
+ api.setData({ src: img, alt: state.prevAlt });
1409
+ }
1410
+ else {
1411
+ api.setData({ src: img, alt: img.text });
1412
+ }
1413
+ }
1414
+ else {
1415
+ api.setData({ src: img });
1416
+ }
1417
+ });
1418
+ state.prevImage = image;
1419
+ changeSrc(helpers, info, state, api);
1261
1420
  };
1262
1421
  const changeFileInput = (helpers, info, state, api) => {
1263
- const data = api.getData();
1264
- api.block('Uploading image');
1265
- head(data.fileinput).fold(() => {
1266
- api.unblock();
1267
- }, file => {
1268
- const blobUri = URL.createObjectURL(file);
1269
- const finalize = () => {
1270
- api.unblock();
1271
- URL.revokeObjectURL(blobUri);
1272
- };
1273
- const updateSrcAndSwitchTab = url => {
1274
- api.setData({
1275
- src: {
1276
- value: url,
1277
- meta: {}
1278
- }
1279
- });
1280
- api.showTab('general');
1281
- changeSrc(helpers, info, state, api);
1282
- };
1283
- blobToDataUri(file).then(dataUrl => {
1284
- const blobInfo = helpers.createBlobCache(file, blobUri, dataUrl);
1285
- if (info.automaticUploads) {
1286
- helpers.uploadImage(blobInfo).then(result => {
1287
- updateSrcAndSwitchTab(result.url);
1288
- finalize();
1289
- }).catch(err => {
1290
- finalize();
1291
- helpers.alertErr(err);
1292
- });
1293
- } else {
1294
- helpers.addToBlobCache(blobInfo);
1295
- updateSrcAndSwitchTab(blobInfo.blobUri());
1422
+ const data = api.getData();
1423
+ api.block('Uploading image'); // What msg do we pass to the lock?
1424
+ head(data.fileinput)
1425
+ .fold(() => {
1296
1426
  api.unblock();
1297
- }
1427
+ }, (file) => {
1428
+ const blobUri = URL.createObjectURL(file);
1429
+ const finalize = () => {
1430
+ api.unblock();
1431
+ URL.revokeObjectURL(blobUri);
1432
+ };
1433
+ const updateSrcAndSwitchTab = (url) => {
1434
+ api.setData({ src: { value: url, meta: {} } });
1435
+ api.showTab('general');
1436
+ changeSrc(helpers, info, state, api);
1437
+ api.focus('src');
1438
+ };
1439
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1440
+ blobToDataUri(file).then((dataUrl) => {
1441
+ const blobInfo = helpers.createBlobCache(file, blobUri, dataUrl);
1442
+ if (info.automaticUploads) {
1443
+ helpers.uploadImage(blobInfo).then((result) => {
1444
+ updateSrcAndSwitchTab(result.url);
1445
+ finalize();
1446
+ }).catch((err) => {
1447
+ finalize();
1448
+ helpers.alertErr(err, () => {
1449
+ api.focus('fileinput');
1450
+ });
1451
+ });
1452
+ }
1453
+ else {
1454
+ helpers.addToBlobCache(blobInfo);
1455
+ updateSrcAndSwitchTab(blobInfo.blobUri());
1456
+ api.unblock();
1457
+ }
1458
+ });
1298
1459
  });
1299
- });
1300
1460
  };
1301
1461
  const changeHandler = (helpers, info, state) => (api, evt) => {
1302
- if (evt.name === 'src') {
1303
- changeSrc(helpers, info, state, api);
1304
- } else if (evt.name === 'images') {
1305
- changeImages(helpers, info, state, api);
1306
- } else if (evt.name === 'alt') {
1307
- state.prevAlt = api.getData().alt;
1308
- } else if (evt.name === 'fileinput') {
1309
- changeFileInput(helpers, info, state, api);
1310
- } else if (evt.name === 'isDecorative') {
1311
- api.setEnabled('alt', !api.getData().isDecorative);
1312
- }
1313
- };
1314
- const closeHandler = state => () => {
1315
- state.open = false;
1316
- };
1317
- const makeDialogBody = info => {
1318
- if (info.hasAdvTab || info.hasUploadUrl || info.hasUploadHandler) {
1319
- const tabPanel = {
1320
- type: 'tabpanel',
1321
- tabs: flatten([
1322
- [MainTab.makeTab(info)],
1323
- info.hasAdvTab ? [AdvTab.makeTab(info)] : [],
1324
- info.hasUploadTab && (info.hasUploadUrl || info.hasUploadHandler) ? [UploadTab.makeTab(info)] : []
1325
- ])
1326
- };
1327
- return tabPanel;
1328
- } else {
1329
- const panel = {
1330
- type: 'panel',
1331
- items: MainTab.makeItems(info)
1462
+ if (evt.name === 'src') {
1463
+ changeSrc(helpers, info, state, api);
1464
+ }
1465
+ else if (evt.name === 'images') {
1466
+ changeImages(helpers, info, state, api);
1467
+ }
1468
+ else if (evt.name === 'alt') {
1469
+ state.prevAlt = api.getData().alt;
1470
+ }
1471
+ else if (evt.name === 'fileinput') {
1472
+ changeFileInput(helpers, info, state, api);
1473
+ }
1474
+ else if (evt.name === 'isDecorative') {
1475
+ api.setEnabled('alt', !api.getData().isDecorative);
1476
+ }
1477
+ };
1478
+ const closeHandler = (state) => () => {
1479
+ state.open = false;
1480
+ };
1481
+ const makeDialogBody = (info) => {
1482
+ if (info.hasAdvTab || info.hasUploadUrl || info.hasUploadHandler) {
1483
+ const tabPanel = {
1484
+ type: 'tabpanel',
1485
+ tabs: flatten([
1486
+ [MainTab.makeTab(info)],
1487
+ info.hasAdvTab ? [AdvTab.makeTab(info)] : [],
1488
+ info.hasUploadTab && (info.hasUploadUrl || info.hasUploadHandler) ? [UploadTab.makeTab(info)] : []
1489
+ ])
1490
+ };
1491
+ return tabPanel;
1492
+ }
1493
+ else {
1494
+ const panel = {
1495
+ type: 'panel',
1496
+ items: MainTab.makeItems(info)
1497
+ };
1498
+ return panel;
1499
+ }
1500
+ };
1501
+ const submitHandler = (editor, info, helpers) => (api) => {
1502
+ const data = deepMerge(fromImageData(info.image), api.getData());
1503
+ // The data architecture relies on passing everything through the style field for validation.
1504
+ // Since the style field was removed that process must be simulated on submit.
1505
+ const finalData = {
1506
+ ...data,
1507
+ style: getStyleValue(helpers.normalizeCss, toImageData(data, false))
1332
1508
  };
1333
- return panel;
1334
- }
1335
- };
1336
- const submitHandler = (editor, info, helpers) => api => {
1337
- const data = deepMerge(fromImageData(info.image), api.getData());
1338
- const finalData = {
1339
- ...data,
1340
- style: getStyleValue(helpers.normalizeCss, toImageData(data, false))
1341
- };
1342
- editor.execCommand('mceUpdateImage', false, toImageData(finalData, info.hasAccessibilityOptions));
1343
- editor.editorUpload.uploadImagesAuto();
1344
- api.close();
1345
- };
1346
- const imageSize = editor => url => {
1347
- if (!isSafeImageUrl(editor, url)) {
1348
- return Promise.resolve({
1349
- width: '',
1350
- height: ''
1509
+ editor.execCommand('mceUpdateImage', false, toImageData(finalData, info.hasAccessibilityOptions));
1510
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1511
+ editor.editorUpload.uploadImagesAuto();
1512
+ api.close();
1513
+ };
1514
+ const imageSize = (editor) => (url) => {
1515
+ // If the URL isn't safe then don't attempt to load it to get the sizes
1516
+ if (!isSafeImageUrl(editor, url)) {
1517
+ return Promise.resolve({ width: '', height: '' });
1518
+ }
1519
+ else {
1520
+ return getImageSize(editor.documentBaseURI.toAbsolute(url)).then((dimensions) => ({
1521
+ width: String(dimensions.width),
1522
+ height: String(dimensions.height)
1523
+ }));
1524
+ }
1525
+ };
1526
+ const createBlobCache = (editor) => (file, blobUri, dataUrl) => {
1527
+ var _a;
1528
+ return editor.editorUpload.blobCache.create({
1529
+ blob: file,
1530
+ blobUri,
1531
+ name: (_a = file.name) === null || _a === void 0 ? void 0 : _a.replace(/\.[^\.]+$/, ''),
1532
+ filename: file.name,
1533
+ base64: dataUrl.split(',')[1]
1351
1534
  });
1352
- } else {
1353
- return getImageSize(editor.documentBaseURI.toAbsolute(url)).then(dimensions => ({
1354
- width: String(dimensions.width),
1355
- height: String(dimensions.height)
1356
- }));
1357
- }
1358
- };
1359
- const createBlobCache = editor => (file, blobUri, dataUrl) => {
1360
- var _a;
1361
- return editor.editorUpload.blobCache.create({
1362
- blob: file,
1363
- blobUri,
1364
- name: (_a = file.name) === null || _a === void 0 ? void 0 : _a.replace(/\.[^\.]+$/, ''),
1365
- filename: file.name,
1366
- base64: dataUrl.split(',')[1]
1367
- });
1368
- };
1369
- const addToBlobCache = editor => blobInfo => {
1370
- editor.editorUpload.blobCache.add(blobInfo);
1371
- };
1372
- const alertErr = editor => message => {
1373
- editor.windowManager.alert(message);
1374
- };
1375
- const normalizeCss = editor => cssText => normalizeCss$1(editor, cssText);
1376
- const parseStyle = editor => cssText => editor.dom.parseStyle(cssText);
1377
- const serializeStyle = editor => (stylesArg, name) => editor.dom.serializeStyle(stylesArg, name);
1378
- const uploadImage = editor => blobInfo => global$1(editor).upload([blobInfo], false).then(results => {
1379
- var _a;
1380
- if (results.length === 0) {
1381
- return Promise.reject('Failed to upload image');
1382
- } else if (results[0].status === false) {
1383
- return Promise.reject((_a = results[0].error) === null || _a === void 0 ? void 0 : _a.message);
1384
- } else {
1385
- return results[0];
1386
- }
1535
+ };
1536
+ const addToBlobCache = (editor) => (blobInfo) => {
1537
+ editor.editorUpload.blobCache.add(blobInfo);
1538
+ };
1539
+ const alertErr = (editor) => (message, callback) => {
1540
+ editor.windowManager.alert(message, callback);
1541
+ };
1542
+ const normalizeCss = (editor) => (cssText) => normalizeCss$1(editor, cssText);
1543
+ const parseStyle = (editor) => (cssText) => editor.dom.parseStyle(cssText);
1544
+ const serializeStyle = (editor) => (stylesArg, name) => editor.dom.serializeStyle(stylesArg, name);
1545
+ const uploadImage = (editor) => (blobInfo) => global$1(editor).upload([blobInfo], false).then((results) => {
1546
+ var _a;
1547
+ if (results.length === 0) {
1548
+ return Promise.reject('Failed to upload image');
1549
+ }
1550
+ else if (results[0].status === false) {
1551
+ return Promise.reject((_a = results[0].error) === null || _a === void 0 ? void 0 : _a.message);
1552
+ }
1553
+ else {
1554
+ return results[0];
1555
+ }
1387
1556
  });
1388
- const Dialog = editor => {
1389
- const helpers = {
1390
- imageSize: imageSize(editor),
1391
- addToBlobCache: addToBlobCache(editor),
1392
- createBlobCache: createBlobCache(editor),
1393
- alertErr: alertErr(editor),
1394
- normalizeCss: normalizeCss(editor),
1395
- parseStyle: parseStyle(editor),
1396
- serializeStyle: serializeStyle(editor),
1397
- uploadImage: uploadImage(editor)
1398
- };
1399
- const open = () => {
1400
- collect(editor).then(info => {
1401
- const state = createState(info);
1402
- return {
1403
- title: 'Insert/Edit Image',
1404
- size: 'normal',
1405
- body: makeDialogBody(info),
1406
- buttons: [
1407
- {
1408
- type: 'cancel',
1409
- name: 'cancel',
1410
- text: 'Cancel'
1411
- },
1412
- {
1413
- type: 'submit',
1414
- name: 'save',
1415
- text: 'Save',
1416
- primary: true
1417
- }
1418
- ],
1419
- initialData: fromImageData(info.image),
1420
- onSubmit: submitHandler(editor, info, helpers),
1421
- onChange: changeHandler(helpers, info, state),
1422
- onClose: closeHandler(state)
1423
- };
1424
- }).then(editor.windowManager.open);
1425
- };
1426
- return { open };
1557
+ const Dialog = (editor) => {
1558
+ const helpers = {
1559
+ imageSize: imageSize(editor),
1560
+ addToBlobCache: addToBlobCache(editor),
1561
+ createBlobCache: createBlobCache(editor),
1562
+ alertErr: alertErr(editor),
1563
+ normalizeCss: normalizeCss(editor),
1564
+ parseStyle: parseStyle(editor),
1565
+ serializeStyle: serializeStyle(editor),
1566
+ uploadImage: uploadImage(editor)
1567
+ };
1568
+ const open = () => {
1569
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
1570
+ collect(editor)
1571
+ .then((info) => {
1572
+ const state = createState(info);
1573
+ return {
1574
+ title: 'Insert/Edit Image',
1575
+ size: 'normal',
1576
+ body: makeDialogBody(info),
1577
+ buttons: [
1578
+ {
1579
+ type: 'cancel',
1580
+ name: 'cancel',
1581
+ text: 'Cancel'
1582
+ },
1583
+ {
1584
+ type: 'submit',
1585
+ name: 'save',
1586
+ text: 'Save',
1587
+ primary: true
1588
+ }
1589
+ ],
1590
+ initialData: fromImageData(info.image),
1591
+ onSubmit: submitHandler(editor, info, helpers),
1592
+ onChange: changeHandler(helpers, info, state),
1593
+ onClose: closeHandler(state)
1594
+ };
1595
+ })
1596
+ .then(editor.windowManager.open);
1597
+ };
1598
+ return {
1599
+ open
1600
+ };
1427
1601
  };
1428
1602
 
1429
- const register$1 = editor => {
1430
- editor.addCommand('mceImage', Dialog(editor).open);
1431
- editor.addCommand('mceUpdateImage', (_ui, data) => {
1432
- editor.undoManager.transact(() => insertOrUpdateImage(editor, data));
1433
- });
1603
+ const register$1 = (editor) => {
1604
+ editor.addCommand('mceImage', Dialog(editor).open);
1605
+ // TODO: This command is likely to be short lived we only need it until we expose the rtc model though a new api so it shouldn't be documented
1606
+ // it's just a command since that is a convenient method for the rtc plugin to override the default dom mutation behaviour
1607
+ editor.addCommand('mceUpdateImage', (_ui, data) => {
1608
+ editor.undoManager.transact(() => insertOrUpdateImage(editor, data));
1609
+ });
1434
1610
  };
1435
1611
 
1436
- const hasImageClass = node => {
1437
- const className = node.attr('class');
1438
- return isNonNullable(className) && /\bimage\b/.test(className);
1439
- };
1440
- const toggleContentEditableState = state => nodes => {
1441
- let i = nodes.length;
1442
- const toggleContentEditable = node => {
1443
- node.attr('contenteditable', state ? 'true' : null);
1444
- };
1445
- while (i--) {
1446
- const node = nodes[i];
1447
- if (hasImageClass(node)) {
1448
- node.attr('contenteditable', state ? 'false' : null);
1449
- global.each(node.getAll('figcaption'), toggleContentEditable);
1450
- }
1451
- }
1452
- };
1453
- const setup = editor => {
1454
- editor.on('PreInit', () => {
1455
- editor.parser.addNodeFilter('figure', toggleContentEditableState(true));
1456
- editor.serializer.addNodeFilter('figure', toggleContentEditableState(false));
1457
- });
1612
+ const hasImageClass = (node) => {
1613
+ const className = node.attr('class');
1614
+ return isNonNullable(className) && /\bimage\b/.test(className);
1615
+ };
1616
+ const toggleContentEditableState = (state) => (nodes) => {
1617
+ let i = nodes.length;
1618
+ const toggleContentEditable = (node) => {
1619
+ node.attr('contenteditable', state ? 'true' : null);
1620
+ };
1621
+ while (i--) {
1622
+ const node = nodes[i];
1623
+ if (hasImageClass(node)) {
1624
+ node.attr('contenteditable', state ? 'false' : null);
1625
+ global.each(node.getAll('figcaption'), toggleContentEditable);
1626
+ }
1627
+ }
1628
+ };
1629
+ const setup = (editor) => {
1630
+ editor.on('PreInit', () => {
1631
+ editor.parser.addNodeFilter('figure', toggleContentEditableState(true));
1632
+ editor.serializer.addNodeFilter('figure', toggleContentEditableState(false));
1633
+ });
1458
1634
  };
1459
1635
 
1460
- const onSetupEditable = editor => api => {
1461
- const nodeChanged = () => {
1462
- api.setEnabled(editor.selection.isEditable());
1463
- };
1464
- editor.on('NodeChange', nodeChanged);
1465
- nodeChanged();
1466
- return () => {
1467
- editor.off('NodeChange', nodeChanged);
1468
- };
1469
- };
1470
- const register = editor => {
1471
- editor.ui.registry.addToggleButton('image', {
1472
- icon: 'image',
1473
- tooltip: 'Insert/edit image',
1474
- onAction: Dialog(editor).open,
1475
- onSetup: buttonApi => {
1476
- buttonApi.setActive(isNonNullable(getSelectedImage(editor)));
1477
- const unbindSelectorChanged = editor.selection.selectorChangedWithUnbind('img:not([data-mce-object]):not([data-mce-placeholder]),figure.image', buttonApi.setActive).unbind;
1478
- const unbindEditable = onSetupEditable(editor)(buttonApi);
1479
- return () => {
1480
- unbindSelectorChanged();
1481
- unbindEditable();
1482
- };
1483
- }
1484
- });
1485
- editor.ui.registry.addMenuItem('image', {
1486
- icon: 'image',
1487
- text: 'Image...',
1488
- onAction: Dialog(editor).open,
1489
- onSetup: onSetupEditable(editor)
1490
- });
1491
- editor.ui.registry.addContextMenu('image', { update: element => editor.selection.isEditable() && (isFigure(element) || isImage(element) && !isPlaceholderImage(element)) ? ['image'] : [] });
1636
+ const onSetupEditable = (editor) => (api) => {
1637
+ const nodeChanged = () => {
1638
+ api.setEnabled(editor.selection.isEditable());
1639
+ };
1640
+ editor.on('NodeChange', nodeChanged);
1641
+ nodeChanged();
1642
+ return () => {
1643
+ editor.off('NodeChange', nodeChanged);
1644
+ };
1645
+ };
1646
+ const register = (editor) => {
1647
+ editor.ui.registry.addToggleButton('image', {
1648
+ icon: 'image',
1649
+ tooltip: 'Insert/edit image',
1650
+ onAction: Dialog(editor).open,
1651
+ onSetup: (buttonApi) => {
1652
+ // Set the initial state and then bind to selection changes to update the state when the selection changes
1653
+ buttonApi.setActive(isNonNullable(getSelectedImage(editor)));
1654
+ const unbindSelectorChanged = editor.selection.selectorChangedWithUnbind('img:not([data-mce-object]):not([data-mce-placeholder]),figure.image', buttonApi.setActive).unbind;
1655
+ const unbindEditable = onSetupEditable(editor)(buttonApi);
1656
+ return () => {
1657
+ unbindSelectorChanged();
1658
+ unbindEditable();
1659
+ };
1660
+ }
1661
+ });
1662
+ editor.ui.registry.addMenuItem('image', {
1663
+ icon: 'image',
1664
+ text: 'Image...',
1665
+ onAction: Dialog(editor).open,
1666
+ onSetup: onSetupEditable(editor)
1667
+ });
1668
+ editor.ui.registry.addContextMenu('image', {
1669
+ update: (element) => editor.selection.isEditable() && (isFigure(element) || (isImage(element) && !isPlaceholderImage(element))) ? ['image'] : []
1670
+ });
1492
1671
  };
1493
1672
 
1494
1673
  var Plugin = () => {
1495
- global$4.add('image', editor => {
1496
- register$2(editor);
1497
- setup(editor);
1498
- register(editor);
1499
- register$1(editor);
1500
- });
1674
+ global$4.add('image', (editor) => {
1675
+ register$2(editor);
1676
+ setup(editor);
1677
+ register(editor);
1678
+ register$1(editor);
1679
+ });
1501
1680
  };
1502
1681
 
1503
1682
  Plugin();
1683
+ /** *****
1684
+ * DO NOT EXPORT ANYTHING
1685
+ *
1686
+ * IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
1687
+ *******/
1504
1688
 
1505
1689
  })();