opentiny 6.9.35 → 6.9.36

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 (53) hide show
  1. package/icons/default/icons.js +2 -0
  2. package/icons/default/icons.min.js +1 -1
  3. package/package.json +1 -1
  4. package/plugins/advlist/plugin.js +18 -2
  5. package/plugins/advlist/plugin.min.js +1 -1
  6. package/plugins/charmap/plugin.js +17 -4
  7. package/plugins/charmap/plugin.min.js +1 -1
  8. package/plugins/checkbox/plugin.js +616 -0
  9. package/plugins/checkbox/plugin.min.js +4 -0
  10. package/skins/ui/oxide/content.css +24 -0
  11. package/skins/ui/oxide/content.inline.css +24 -0
  12. package/skins/ui/oxide/content.inline.js +1 -1
  13. package/skins/ui/oxide/content.inline.js.map +1 -1
  14. package/skins/ui/oxide/content.inline.min.css +1 -1
  15. package/skins/ui/oxide/content.inline.min.css.map +1 -1
  16. package/skins/ui/oxide/content.js +1 -1
  17. package/skins/ui/oxide/content.js.map +1 -1
  18. package/skins/ui/oxide/content.min.css +1 -1
  19. package/skins/ui/oxide/content.min.css.map +1 -1
  20. package/skins/ui/oxide-dark/content.css +24 -0
  21. package/skins/ui/oxide-dark/content.inline.css +24 -0
  22. package/skins/ui/oxide-dark/content.inline.js +1 -1
  23. package/skins/ui/oxide-dark/content.inline.js.map +1 -1
  24. package/skins/ui/oxide-dark/content.inline.min.css +1 -1
  25. package/skins/ui/oxide-dark/content.inline.min.css.map +1 -1
  26. package/skins/ui/oxide-dark/content.js +1 -1
  27. package/skins/ui/oxide-dark/content.js.map +1 -1
  28. package/skins/ui/oxide-dark/content.min.css +1 -1
  29. package/skins/ui/oxide-dark/content.min.css.map +1 -1
  30. package/skins/ui/tinymce-5/content.css +24 -0
  31. package/skins/ui/tinymce-5/content.inline.css +24 -0
  32. package/skins/ui/tinymce-5/content.inline.js +1 -1
  33. package/skins/ui/tinymce-5/content.inline.js.map +1 -1
  34. package/skins/ui/tinymce-5/content.inline.min.css +1 -1
  35. package/skins/ui/tinymce-5/content.inline.min.css.map +1 -1
  36. package/skins/ui/tinymce-5/content.js +1 -1
  37. package/skins/ui/tinymce-5/content.js.map +1 -1
  38. package/skins/ui/tinymce-5/content.min.css +1 -1
  39. package/skins/ui/tinymce-5/content.min.css.map +1 -1
  40. package/skins/ui/tinymce-5-dark/content.css +24 -0
  41. package/skins/ui/tinymce-5-dark/content.inline.css +24 -0
  42. package/skins/ui/tinymce-5-dark/content.inline.js +1 -1
  43. package/skins/ui/tinymce-5-dark/content.inline.js.map +1 -1
  44. package/skins/ui/tinymce-5-dark/content.inline.min.css +1 -1
  45. package/skins/ui/tinymce-5-dark/content.inline.min.css.map +1 -1
  46. package/skins/ui/tinymce-5-dark/content.js +1 -1
  47. package/skins/ui/tinymce-5-dark/content.js.map +1 -1
  48. package/skins/ui/tinymce-5-dark/content.min.css +1 -1
  49. package/skins/ui/tinymce-5-dark/content.min.css.map +1 -1
  50. package/themes/silver/theme.js +1 -1
  51. package/themes/silver/theme.min.js +1 -1
  52. package/tinymce.js +4 -7
  53. package/tinymce.min.js +1 -1
@@ -0,0 +1,616 @@
1
+ /**
2
+ * TinyMCE version 7.0.0 (TBD)
3
+ */
4
+
5
+ (function () {
6
+ 'use strict';
7
+
8
+ var global$2 = tinymce.util.Tools.resolve('tinymce.PluginManager');
9
+
10
+ const hasProto = (v, constructor, predicate) => {
11
+ var _a;
12
+ if (predicate(v, constructor.prototype)) {
13
+ return true;
14
+ } else {
15
+ return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
16
+ }
17
+ };
18
+ const typeOf = x => {
19
+ const t = typeof x;
20
+ if (x === null) {
21
+ return 'null';
22
+ } else if (t === 'object' && Array.isArray(x)) {
23
+ return 'array';
24
+ } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
25
+ return 'string';
26
+ } else {
27
+ return t;
28
+ }
29
+ };
30
+ const isType = type => value => typeOf(value) === type;
31
+ const isSimpleType = type => value => typeof value === type;
32
+ const eq = t => a => t === a;
33
+ const isArray = isType('array');
34
+ const isUndefined = eq(undefined);
35
+ const isNullable = a => a === null || a === undefined;
36
+ const isNonNullable = a => !isNullable(a);
37
+ const isFunction = isSimpleType('function');
38
+
39
+ class Optional {
40
+ constructor(tag, value) {
41
+ this.tag = tag;
42
+ this.value = value;
43
+ }
44
+ static some(value) {
45
+ return new Optional(true, value);
46
+ }
47
+ static none() {
48
+ return Optional.singletonNone;
49
+ }
50
+ fold(onNone, onSome) {
51
+ if (this.tag) {
52
+ return onSome(this.value);
53
+ } else {
54
+ return onNone();
55
+ }
56
+ }
57
+ isSome() {
58
+ return this.tag;
59
+ }
60
+ isNone() {
61
+ return !this.tag;
62
+ }
63
+ map(mapper) {
64
+ if (this.tag) {
65
+ return Optional.some(mapper(this.value));
66
+ } else {
67
+ return Optional.none();
68
+ }
69
+ }
70
+ bind(binder) {
71
+ if (this.tag) {
72
+ return binder(this.value);
73
+ } else {
74
+ return Optional.none();
75
+ }
76
+ }
77
+ exists(predicate) {
78
+ return this.tag && predicate(this.value);
79
+ }
80
+ forall(predicate) {
81
+ return !this.tag || predicate(this.value);
82
+ }
83
+ filter(predicate) {
84
+ if (!this.tag || predicate(this.value)) {
85
+ return this;
86
+ } else {
87
+ return Optional.none();
88
+ }
89
+ }
90
+ getOr(replacement) {
91
+ return this.tag ? this.value : replacement;
92
+ }
93
+ or(replacement) {
94
+ return this.tag ? this : replacement;
95
+ }
96
+ getOrThunk(thunk) {
97
+ return this.tag ? this.value : thunk();
98
+ }
99
+ orThunk(thunk) {
100
+ return this.tag ? this : thunk();
101
+ }
102
+ getOrDie(message) {
103
+ if (!this.tag) {
104
+ throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
105
+ } else {
106
+ return this.value;
107
+ }
108
+ }
109
+ static from(value) {
110
+ return isNonNullable(value) ? Optional.some(value) : Optional.none();
111
+ }
112
+ getOrNull() {
113
+ return this.tag ? this.value : null;
114
+ }
115
+ getOrUndefined() {
116
+ return this.value;
117
+ }
118
+ each(worker) {
119
+ if (this.tag) {
120
+ worker(this.value);
121
+ }
122
+ }
123
+ toArray() {
124
+ return this.tag ? [this.value] : [];
125
+ }
126
+ toString() {
127
+ return this.tag ? `some(${ this.value })` : 'none()';
128
+ }
129
+ }
130
+ Optional.singletonNone = new Optional(false);
131
+
132
+ const checkboxClass = 'mce-checkbox';
133
+ const uncheckedGlyph = '\u2610';
134
+ const checkedGlyph = '\u2612';
135
+ const checkedAltGlyph = '\u2611';
136
+ const glyphRegExp = /^[\u2610-\u2612]$/;
137
+ const isGlyph = text => glyphRegExp.test(text);
138
+ const isChecked = glyph => glyph === checkedGlyph || glyph === checkedAltGlyph;
139
+ const getToggledGlyph = glyph => isChecked(glyph) ? uncheckedGlyph : checkedGlyph;
140
+ const editorAttributes = {
141
+ 'contenteditable': 'false',
142
+ 'data-mce-cef-wrappable': 'true'
143
+ };
144
+
145
+ const isCheckboxElement = (editor, node) => {
146
+ var _a, _b;
147
+ return editor.dom.is(node, `span.${ checkboxClass }`) && node.childNodes.length === 1 && ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.nodeType) === Node.TEXT_NODE && isGlyph((_b = node.textContent) !== null && _b !== void 0 ? _b : '');
148
+ };
149
+ const createCheckbox = (editor, glyph) => editor.dom.create('span', {
150
+ class: checkboxClass,
151
+ ...editorAttributes
152
+ }, glyph);
153
+ const getToggleableCheckbox = (editor, target) => Optional.from(target).filter(node => isCheckboxElement(editor, node) && editor.getBody().contains(node)).filter(checkbox => !editor.mode.isReadOnly() && editor.dom.isEditable(checkbox.parentNode));
154
+ const isFollowedByWhitespace = editor => {
155
+ const rng = editor.selection.getRng();
156
+ const container = rng.endContainer;
157
+ return rng.collapsed && container.nodeType === Node.TEXT_NODE && /^[ \u00a0]/.test(container.data.slice(rng.endOffset));
158
+ };
159
+ const insertCheckbox = editor => {
160
+ const space = isFollowedByWhitespace(editor) ? '' : ' ';
161
+ editor.insertContent(`<span class="${ checkboxClass }">${ uncheckedGlyph }</span>${ space }`);
162
+ };
163
+ const toggleCheckbox = (editor, checkbox) => {
164
+ editor.undoManager.transact(() => {
165
+ var _a;
166
+ checkbox.textContent = getToggledGlyph((_a = checkbox.textContent) !== null && _a !== void 0 ? _a : '');
167
+ });
168
+ };
169
+
170
+ const constant = value => {
171
+ return () => {
172
+ return value;
173
+ };
174
+ };
175
+ const never = constant(false);
176
+
177
+ const nativeSlice = Array.prototype.slice;
178
+ const nativeIndexOf = Array.prototype.indexOf;
179
+ const nativePush = Array.prototype.push;
180
+ const rawIndexOf = (ts, t) => nativeIndexOf.call(ts, t);
181
+ const contains = (xs, x) => rawIndexOf(xs, x) > -1;
182
+ const exists = (xs, pred) => {
183
+ for (let i = 0, len = xs.length; i < len; i++) {
184
+ const x = xs[i];
185
+ if (pred(x, i)) {
186
+ return true;
187
+ }
188
+ }
189
+ return false;
190
+ };
191
+ const map = (xs, f) => {
192
+ const len = xs.length;
193
+ const r = new Array(len);
194
+ for (let i = 0; i < len; i++) {
195
+ const x = xs[i];
196
+ r[i] = f(x, i);
197
+ }
198
+ return r;
199
+ };
200
+ const each = (xs, f) => {
201
+ for (let i = 0, len = xs.length; i < len; i++) {
202
+ const x = xs[i];
203
+ f(x, i);
204
+ }
205
+ };
206
+ const filter = (xs, pred) => {
207
+ const r = [];
208
+ for (let i = 0, len = xs.length; i < len; i++) {
209
+ const x = xs[i];
210
+ if (pred(x, i)) {
211
+ r.push(x);
212
+ }
213
+ }
214
+ return r;
215
+ };
216
+ const findUntil = (xs, pred, until) => {
217
+ for (let i = 0, len = xs.length; i < len; i++) {
218
+ const x = xs[i];
219
+ if (pred(x, i)) {
220
+ return Optional.some(x);
221
+ } else if (until(x, i)) {
222
+ break;
223
+ }
224
+ }
225
+ return Optional.none();
226
+ };
227
+ const find = (xs, pred) => {
228
+ return findUntil(xs, pred, never);
229
+ };
230
+ const flatten = xs => {
231
+ const r = [];
232
+ for (let i = 0, len = xs.length; i < len; ++i) {
233
+ if (!isArray(xs[i])) {
234
+ throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
235
+ }
236
+ nativePush.apply(r, xs[i]);
237
+ }
238
+ return r;
239
+ };
240
+ const bind = (xs, f) => flatten(map(xs, f));
241
+ const forall = (xs, pred) => {
242
+ for (let i = 0, len = xs.length; i < len; ++i) {
243
+ const x = xs[i];
244
+ if (pred(x, i) !== true) {
245
+ return false;
246
+ }
247
+ }
248
+ return true;
249
+ };
250
+ const from = isFunction(Array.from) ? Array.from : x => nativeSlice.call(x);
251
+ const unique = (xs, comparator) => {
252
+ const r = [];
253
+ const isDuplicated = isFunction(comparator) ? x => exists(r, i => comparator(i, x)) : x => contains(r, x);
254
+ for (let i = 0, len = xs.length; i < len; i++) {
255
+ const x = xs[i];
256
+ if (!isDuplicated(x)) {
257
+ r.push(x);
258
+ }
259
+ }
260
+ return r;
261
+ };
262
+
263
+ var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK');
264
+
265
+ const checklistClass = 'mce-checklist';
266
+ const checklistDetail = {
267
+ 'list-style-type': 'none',
268
+ 'list-attributes': { class: checklistClass }
269
+ };
270
+ const isChecklist = node => (node === null || node === void 0 ? void 0 : node.nodeName) === 'UL' && node.classList.contains(checklistClass);
271
+ const isChecklistItem = node => (node === null || node === void 0 ? void 0 : node.nodeName) === 'LI' && isChecklist(node.parentNode);
272
+ const isBlankText = node => node.nodeType === Node.TEXT_NODE && /^[\s\uFEFF]*$/.test(node.data);
273
+ const getLeadingCheckbox = (editor, item) => find(from(item.childNodes), node => !isBlankText(node)).filter(node => isCheckboxElement(editor, node));
274
+ const isEmptyItem = (editor, item) => forall(from(item.childNodes), node => isBlankText(node) || node.nodeName === 'BR' || isCheckboxElement(editor, node));
275
+ const isInChecklist = editor => isChecklist(editor.dom.getParent(editor.selection.getNode(), 'ul,ol,dl'));
276
+ const getSelectedItems = editor => unique(bind(editor.selection.getSelectedBlocks(), block => Optional.from(editor.dom.getParent(block, 'li')).filter(isChecklistItem).toArray()));
277
+ const moveCaretAfter = (editor, item, space) => {
278
+ const rng = editor.selection.getRng();
279
+ const afterSpace = editor.getDoc().createRange();
280
+ afterSpace.setStart(space, space.length);
281
+ if (rng.collapsed && item.contains(rng.startContainer) && rng.compareBoundaryPoints(window.Range.START_TO_START, afterSpace) < 0) {
282
+ editor.selection.setCursorLocation(space, space.length);
283
+ }
284
+ };
285
+ const addCheckbox = (editor, item) => {
286
+ if (getLeadingCheckbox(editor, item).isNone()) {
287
+ each(from(item.childNodes), node => {
288
+ if (node.nodeName === 'BR' && editor.dom.getAttrib(node, 'data-mce-bogus')) {
289
+ editor.dom.remove(node);
290
+ }
291
+ });
292
+ const space = editor.getDoc().createTextNode('\xA0');
293
+ item.insertBefore(space, item.firstChild);
294
+ item.insertBefore(createCheckbox(editor, uncheckedGlyph), space);
295
+ moveCaretAfter(editor, item, space);
296
+ }
297
+ };
298
+ const removeCheckbox = (editor, item) => {
299
+ getLeadingCheckbox(editor, item).each(checkbox => {
300
+ const next = checkbox.nextSibling;
301
+ if (isNonNullable(next) && next.nodeType === Node.TEXT_NODE && /^[ \u00a0]/.test(next.data)) {
302
+ next.deleteData(0, 1);
303
+ }
304
+ editor.dom.remove(checkbox);
305
+ });
306
+ };
307
+ const isFormerChecklist = (editor, list) => ((list === null || list === void 0 ? void 0 : list.nodeName) === 'UL' || (list === null || list === void 0 ? void 0 : list.nodeName) === 'OL') && list.classList.contains(checklistClass) && !(list.nodeName === 'UL' && editor.dom.getStyle(list, 'list-style-type') === 'none');
308
+ const toNormalList = (editor, list) => {
309
+ each(from(list.children), item => {
310
+ if (item.nodeName === 'LI') {
311
+ removeCheckbox(editor, item);
312
+ }
313
+ });
314
+ list.classList.remove(checklistClass);
315
+ if (list.classList.length === 0) {
316
+ list.removeAttribute('class');
317
+ }
318
+ };
319
+ const toggleChecklist = editor => {
320
+ editor.undoManager.transact(() => {
321
+ if (isInChecklist(editor)) {
322
+ each(getSelectedItems(editor), item => removeCheckbox(editor, item));
323
+ editor.execCommand('RemoveList');
324
+ } else {
325
+ editor.execCommand('InsertUnorderedList', false, checklistDetail);
326
+ const checklists = unique(map(getSelectedItems(editor), item => item.parentNode));
327
+ each(checklists, list => {
328
+ each(filter(from(list.children), isChecklistItem), item => addCheckbox(editor, item));
329
+ });
330
+ }
331
+ });
332
+ };
333
+ const setup$2 = editor => {
334
+ editor.on('ListMutation', e => {
335
+ if (isFormerChecklist(editor, e.element)) {
336
+ toNormalList(editor, e.element);
337
+ }
338
+ });
339
+ editor.on('NewBlock', e => {
340
+ if (isChecklistItem(e.newBlock)) {
341
+ addCheckbox(editor, e.newBlock);
342
+ }
343
+ });
344
+ editor.on('keydown', e => {
345
+ if (e.keyCode !== global$1.ENTER || e.shiftKey || e.isDefaultPrevented() || !editor.selection.isCollapsed()) {
346
+ return;
347
+ }
348
+ Optional.from(editor.dom.getParent(editor.selection.getNode(), 'li')).filter(item => isChecklistItem(item) && isEmptyItem(editor, item) && editor.dom.isEditable(item)).each(item => {
349
+ e.preventDefault();
350
+ const undoManager = editor.undoManager;
351
+ if (undoManager.typing) {
352
+ undoManager.typing = false;
353
+ undoManager.add();
354
+ }
355
+ undoManager.transact(() => {
356
+ item.innerHTML = '<br data-mce-bogus="1">';
357
+ editor.selection.setCursorLocation(item, 0);
358
+ editor.execCommand('mceInsertNewLine', false, e);
359
+ });
360
+ });
361
+ });
362
+ };
363
+
364
+ const register$1 = editor => {
365
+ editor.addCommand('mceInsertCheckbox', () => insertCheckbox(editor));
366
+ if (editor.hasPlugin('lists')) {
367
+ editor.addCommand('mceToggleChecklist', () => toggleChecklist(editor));
368
+ editor.addQueryStateHandler('mceToggleChecklist', () => isInChecklist(editor));
369
+ }
370
+ };
371
+
372
+ const hasModifierKey = e => e.ctrlKey || e.metaKey || e.shiftKey || e.altKey;
373
+ const isCaretContainerText = node => node.nodeType === Node.TEXT_NODE && /^\uFEFF*$/.test(node.data);
374
+ const getSpaceAfter = checkbox => {
375
+ let next = checkbox.nextSibling;
376
+ while (next && isCaretContainerText(next)) {
377
+ next = next.nextSibling;
378
+ }
379
+ return Optional.from(next).filter(node => node.nodeType === Node.TEXT_NODE && /^[ \u00a0]/.test(node.data));
380
+ };
381
+ const moveCaretPastSpace = editor => {
382
+ const rng = editor.selection.getRng();
383
+ const block = editor.dom.getParent(rng.startContainer, node => editor.dom.isBlock(node));
384
+ if (!rng.collapsed || !block) {
385
+ return;
386
+ }
387
+ each(editor.dom.select(`span.${ checkboxClass }`, block), checkbox => {
388
+ getSpaceAfter(checkbox).each(space => {
389
+ const afterCheckbox = editor.dom.createRng();
390
+ afterCheckbox.setStartAfter(checkbox);
391
+ const afterSpace = editor.dom.createRng();
392
+ afterSpace.setStart(space, 1);
393
+ if (rng.compareBoundaryPoints(rng.START_TO_START, afterCheckbox) >= 0 && rng.compareBoundaryPoints(rng.START_TO_START, afterSpace) < 0) {
394
+ editor.selection.setCursorLocation(space, 1);
395
+ }
396
+ });
397
+ });
398
+ };
399
+ const setup$1 = editor => {
400
+ let pointerCheckbox = null;
401
+ editor.on('mousedown', e => {
402
+ pointerCheckbox = e.button === 0 && !hasModifierKey(e) ? getToggleableCheckbox(editor, e.target).getOrNull() : null;
403
+ }, true);
404
+ editor.on('keydown', () => {
405
+ pointerCheckbox = null;
406
+ });
407
+ editor.on('BeforeObjectSelected', e => {
408
+ if (e.target === pointerCheckbox) {
409
+ e.preventDefault();
410
+ const rng = editor.dom.createRng();
411
+ rng.setStartAfter(e.target);
412
+ rng.collapse(true);
413
+ editor.selection.setRng(rng);
414
+ }
415
+ });
416
+ editor.on('dragstart', e => {
417
+ if (e.target === pointerCheckbox) {
418
+ e.preventDefault();
419
+ }
420
+ });
421
+ editor.on('click', e => {
422
+ pointerCheckbox = null;
423
+ if (!hasModifierKey(e)) {
424
+ getToggleableCheckbox(editor, e.target).each(checkbox => {
425
+ e.preventDefault();
426
+ toggleCheckbox(editor, checkbox);
427
+ });
428
+ }
429
+ moveCaretPastSpace(editor);
430
+ });
431
+ };
432
+
433
+ const keys = Object.keys;
434
+ const hasOwnProperty = Object.hasOwnProperty;
435
+ const has = (obj, key) => hasOwnProperty.call(obj, key);
436
+
437
+ var global = tinymce.util.Tools.resolve('tinymce.html.Node');
438
+
439
+ const glyphSplitRegExp = /([\u2610-\u2612](?!\uFE0F))/;
440
+ const hasGlyphRegExp = /[\u2610-\u2612](?!\uFE0F)/;
441
+ const nonWrappingElements = [
442
+ 'audio',
443
+ 'video',
444
+ 'object',
445
+ 'pre',
446
+ 'code',
447
+ 'kbd',
448
+ 'samp'
449
+ ];
450
+ const getClasses = node => {
451
+ var _a, _b;
452
+ return (_b = (_a = node.attr('class')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) !== null && _b !== void 0 ? _b : [];
453
+ };
454
+ const isCheckboxNode = node => node.name === 'span' && contains(getClasses(node), checkboxClass);
455
+ const isValidCheckboxNode = node => {
456
+ var _a;
457
+ const child = node.firstChild;
458
+ return isCheckboxNode(node) && isNonNullable(child) && child === node.lastChild && child.type === 3 && isGlyph((_a = child.value) !== null && _a !== void 0 ? _a : '');
459
+ };
460
+ const removeCheckboxClass = node => {
461
+ const classes = filter(getClasses(node), cls => cls !== checkboxClass);
462
+ node.attr('class', classes.length > 0 ? classes.join(' ') : null);
463
+ };
464
+ const markAsCheckbox = node => {
465
+ node.attr(editorAttributes);
466
+ };
467
+ const isInNonWrappingElement = (schema, node) => {
468
+ const specialElements = schema.getSpecialElements();
469
+ for (let parent = node.parent; parent; parent = parent.parent) {
470
+ if (has(specialElements, parent.name) || contains(nonWrappingElements, parent.name)) {
471
+ return true;
472
+ }
473
+ }
474
+ return false;
475
+ };
476
+ const createTextNode = text => {
477
+ const node = new global('#text', 3);
478
+ node.value = text;
479
+ return node;
480
+ };
481
+ const createCheckboxNode = glyph => {
482
+ const node = global.create('span', { class: checkboxClass });
483
+ markAsCheckbox(node);
484
+ node.append(createTextNode(glyph));
485
+ return node;
486
+ };
487
+ const wrapBareGlyphs = (schema, node) => {
488
+ const text = node.value;
489
+ const parent = node.parent;
490
+ if (!text || !hasGlyphRegExp.test(text) || !parent || isValidCheckboxNode(parent) || !schema.isValidChild(parent.name, 'span') || isInNonWrappingElement(schema, node)) {
491
+ return;
492
+ }
493
+ each(text.split(glyphSplitRegExp), part => {
494
+ if (part.length > 0) {
495
+ parent.insert(isGlyph(part) ? createCheckboxNode(part) : createTextNode(part), node, true);
496
+ }
497
+ });
498
+ node.remove();
499
+ };
500
+ const canSaveCheckboxes = schema => {
501
+ const validClasses = schema.getValidClasses();
502
+ return schema.isValid('span', 'class') && (isUndefined(validClasses) || exists([
503
+ validClasses['*'],
504
+ validClasses.span
505
+ ], classes => isNonNullable(classes) && has(classes, checkboxClass)));
506
+ };
507
+ const markUnparsedCheckboxes = editor => {
508
+ each(editor.dom.select(`span.${ checkboxClass }:not([contenteditable])`), span => {
509
+ if (isCheckboxElement(editor, span)) {
510
+ editor.dom.setAttribs(span, editorAttributes);
511
+ }
512
+ });
513
+ };
514
+ const setup = editor => {
515
+ editor.on('SetContent', () => markUnparsedCheckboxes(editor));
516
+ editor.on('PreInit', () => {
517
+ const {parser, serializer, schema} = editor;
518
+ if (canSaveCheckboxes(schema)) {
519
+ parser.addNodeFilter('#text', nodes => {
520
+ each(nodes, node => wrapBareGlyphs(schema, node));
521
+ });
522
+ }
523
+ parser.addAttributeFilter('class', nodes => {
524
+ each(nodes, node => {
525
+ if (isValidCheckboxNode(node)) {
526
+ markAsCheckbox(node);
527
+ } else if (isCheckboxNode(node)) {
528
+ removeCheckboxClass(node);
529
+ }
530
+ });
531
+ });
532
+ serializer.addNodeFilter('span', nodes => {
533
+ each(nodes, node => {
534
+ if (isCheckboxNode(node)) {
535
+ each(keys(editorAttributes), name => node.attr(name, null));
536
+ node.attr('data-mce-contenteditable', null);
537
+ }
538
+ });
539
+ });
540
+ });
541
+ };
542
+
543
+ const onSetupEditable = editor => api => {
544
+ const nodeChanged = () => {
545
+ api.setEnabled(editor.selection.isEditable());
546
+ };
547
+ editor.on('NodeChange', nodeChanged);
548
+ nodeChanged();
549
+ return () => {
550
+ editor.off('NodeChange', nodeChanged);
551
+ };
552
+ };
553
+ const onSetupChecklist = editor => api => {
554
+ const nodeChanged = () => {
555
+ api.setActive(isInChecklist(editor));
556
+ api.setEnabled(editor.selection.isEditable());
557
+ };
558
+ editor.on('NodeChange', nodeChanged);
559
+ nodeChanged();
560
+ return () => {
561
+ editor.off('NodeChange', nodeChanged);
562
+ };
563
+ };
564
+ const registerChecklist = editor => {
565
+ const onAction = () => editor.execCommand('mceToggleChecklist');
566
+ editor.ui.registry.addToggleButton('checklist', {
567
+ icon: 'checklist',
568
+ tooltip: 'Checklist',
569
+ onAction,
570
+ onSetup: onSetupChecklist(editor)
571
+ });
572
+ editor.ui.registry.addToggleMenuItem('checklist', {
573
+ text: 'Checklist',
574
+ icon: 'checklist',
575
+ onAction,
576
+ onSetup: onSetupChecklist(editor)
577
+ });
578
+ };
579
+ const register = editor => {
580
+ const onAction = () => editor.execCommand('mceInsertCheckbox');
581
+ editor.ui.registry.addButton('checkbox', {
582
+ icon: 'checkbox',
583
+ tooltip: 'Insert checkbox',
584
+ onAction,
585
+ onSetup: onSetupEditable(editor)
586
+ });
587
+ editor.ui.registry.addMenuItem('checkbox', {
588
+ text: 'Checkbox',
589
+ icon: 'checkbox',
590
+ onAction,
591
+ onSetup: onSetupEditable(editor)
592
+ });
593
+ if (editor.hasPlugin('lists')) {
594
+ registerChecklist(editor);
595
+ }
596
+ };
597
+
598
+ var Plugin = () => {
599
+ global$2.add('checkbox', editor => {
600
+ register$1(editor);
601
+ register(editor);
602
+ setup(editor);
603
+ setup$1(editor);
604
+ setup$2(editor);
605
+ return {
606
+ getMetadata: () => ({
607
+ name: 'Checkbox',
608
+ url: 'https://github.com/mild-blue/opentiny/tree/main/modules/tinymce/src/plugins/checkbox'
609
+ })
610
+ };
611
+ });
612
+ };
613
+
614
+ Plugin();
615
+
616
+ })();
@@ -0,0 +1,4 @@
1
+ /**
2
+ * TinyMCE version 7.0.0 (TBD)
3
+ */
4
+ !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>"array"===(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||(null===(s=o.constructor)||void 0===s?void 0:s.name)===r.name)?"string":t;var n,o,r,s})(e);const n=e=>void 0===e;const o=e=>!(e=>null==e)(e),r=e=>"function"==typeof e;class s{constructor(e,t){this.tag=e,this.value=t}static some(e){return new s(!0,e)}static none(){return s.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?s.some(e(this.value)):s.none()}bind(e){return this.tag?e(this.value):s.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:s.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(null!=e?e:"Called getOrDie on None")}static from(e){return o(e)?s.some(e):s.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}s.singletonNone=new s(!1);const a="mce-checkbox",l=/^[\u2610-\u2612]$/,i=e=>l.test(e),c={contenteditable:"false","data-mce-cef-wrappable":"true"},d=(e,t)=>{var n,o;return e.dom.is(t,`span.${a}`)&&1===t.childNodes.length&&(null===(n=t.firstChild)||void 0===n?void 0:n.nodeType)===Node.TEXT_NODE&&i(null!==(o=t.textContent)&&void 0!==o?o:"")},u=(e,t)=>s.from(t).filter(t=>d(e,t)&&e.getBody().contains(t)).filter(t=>!e.mode.isReadOnly()&&e.dom.isEditable(t.parentNode)),g=()=>false;const h=Array.prototype.slice,m=Array.prototype.indexOf,p=Array.prototype.push,f=(e,t)=>((e,t)=>m.call(e,t))(e,t)>-1,y=(e,t)=>{for(let n=0,o=e.length;n<o;n++)if(t(e[n],n))return!0;return!1},v=(e,t)=>{const n=e.length,o=new Array(n);for(let r=0;r<n;r++){const n=e[r];o[r]=t(n,r)}return o},N=(e,t)=>{for(let n=0,o=e.length;n<o;n++)t(e[n],n)},b=(e,t)=>{const n=[];for(let o=0,r=e.length;o<r;o++){const r=e[o];t(r,o)&&n.push(r)}return n},T=r(Array.from)?Array.from:e=>h.call(e),C=(e,t)=>{const n=[],o=r(t)?e=>y(n,n=>t(n,e)):e=>f(n,e);for(let t=0,r=e.length;t<r;t++){const r=e[t];o(r)||n.push(r)}return n};var k=tinymce.util.Tools.resolve("tinymce.util.VK");const x="mce-checklist",A={"list-style-type":"none","list-attributes":{class:x}},E=e=>"UL"===(null==e?void 0:e.nodeName)&&e.classList.contains(x),S=e=>"LI"===(null==e?void 0:e.nodeName)&&E(e.parentNode),O=e=>e.nodeType===Node.TEXT_NODE&&/^[\s\uFEFF]*$/.test(e.data),w=(e,t)=>{return(n=T(t.childNodes),o=e=>!O(e),((e,t,n)=>{for(let o=0,r=e.length;o<r;o++){const r=e[o];if(t(r,o))return s.some(r);if(n(r,o))break}return s.none()})(n,o,g)).filter(t=>d(e,t));var n,o},R=e=>E(e.dom.getParent(e.selection.getNode(),"ul,ol,dl")),L=e=>{return C((n=e.selection.getSelectedBlocks(),(e=>{const n=[];for(let o=0,r=e.length;o<r;++o){if(!t(e[o]))throw new Error("Arr.flatten item "+o+" was not an array, input: "+e);p.apply(n,e[o])}return n})(v(n,t=>s.from(e.dom.getParent(t,"li")).filter(S).toArray()))));var n},B=(e,t)=>{if(w(e,t).isNone()){N(T(t.childNodes),t=>{"BR"===t.nodeName&&e.dom.getAttrib(t,"data-mce-bogus")&&e.dom.remove(t)});const n=e.getDoc().createTextNode("\xa0");t.insertBefore(n,t.firstChild),t.insertBefore((e=>e.dom.create("span",{class:a,...c},"\u2610"))(e),n),((e,t,n)=>{const o=e.selection.getRng(),r=e.getDoc().createRange();r.setStart(n,n.length),o.collapsed&&t.contains(o.startContainer)&&o.compareBoundaryPoints(window.Range.START_TO_START,r)<0&&e.selection.setCursorLocation(n,n.length)})(e,t,n)}},D=(e,t)=>{w(e,t).each(t=>{const n=t.nextSibling;o(n)&&n.nodeType===Node.TEXT_NODE&&/^[ \u00a0]/.test(n.data)&&n.deleteData(0,1),e.dom.remove(t)})},P=e=>{e.addCommand("mceInsertCheckbox",()=>(e=>{const t=(e=>{const t=e.selection.getRng(),n=t.endContainer;return t.collapsed&&n.nodeType===Node.TEXT_NODE&&/^[ \u00a0]/.test(n.data.slice(t.endOffset))})(e)?"":"&nbsp;";e.insertContent(`<span class="${a}">\u2610</span>${t}`)})(e)),e.hasPlugin("lists")&&(e.addCommand("mceToggleChecklist",()=>(e=>{e.undoManager.transact(()=>{if(R(e))N(L(e),t=>D(e,t)),e.execCommand("RemoveList");else{e.execCommand("InsertUnorderedList",!1,A);const t=C(v(L(e),e=>e.parentNode));N(t,t=>{N(b(T(t.children),S),t=>B(e,t))})}})})(e)),e.addQueryStateHandler("mceToggleChecklist",()=>R(e)))},F=e=>e.ctrlKey||e.metaKey||e.shiftKey||e.altKey,_=e=>e.nodeType===Node.TEXT_NODE&&/^\uFEFF*$/.test(e.data),I=Object.keys,M=Object.hasOwnProperty,$=(e,t)=>M.call(e,t);var j=tinymce.util.Tools.resolve("tinymce.html.Node");const K=/([\u2610-\u2612](?!\uFE0F))/,X=/[\u2610-\u2612](?!\uFE0F)/,U=["audio","video","object","pre","code","kbd","samp"],V=e=>{var t,n;return null!==(n=null===(t=e.attr("class"))||void 0===t?void 0:t.split(/\s+/))&&void 0!==n?n:[]},H=e=>"span"===e.name&&f(V(e),a),z=e=>{var t;const n=e.firstChild;return H(e)&&o(n)&&n===e.lastChild&&3===n.type&&i(null!==(t=n.value)&&void 0!==t?t:"")},Q=e=>{e.attr(c)},q=e=>{const t=new j("#text",3);return t.value=e,t},G=e=>{e.on("SetContent",()=>(e=>{N(e.dom.select(`span.${a}:not([contenteditable])`),t=>{d(e,t)&&e.dom.setAttribs(t,c)})})(e)),e.on("PreInit",()=>{const{parser:t,serializer:r,schema:s}=e;(e=>{const t=e.getValidClasses();return e.isValid("span","class")&&(n(t)||y([t["*"],t.span],e=>o(e)&&$(e,a)))})(s)&&t.addNodeFilter("#text",e=>{N(e,e=>((e,t)=>{const n=t.value,o=t.parent;n&&X.test(n)&&o&&!z(o)&&e.isValidChild(o.name,"span")&&!((e,t)=>{const n=e.getSpecialElements();for(let e=t.parent;e;e=e.parent)if($(n,e.name)||f(U,e.name))return!0;return!1})(e,t)&&(N(n.split(K),e=>{e.length>0&&o.insert(i(e)?(e=>{const t=j.create("span",{class:a});return Q(t),t.append(q(e)),t})(e):q(e),t,!0)}),t.remove())})(s,e))}),t.addAttributeFilter("class",e=>{N(e,e=>{z(e)?Q(e):H(e)&&(e=>{const t=b(V(e),e=>e!==a);e.attr("class",t.length>0?t.join(" "):null)})(e)})}),r.addNodeFilter("span",e=>{N(e,e=>{H(e)&&(N(I(c),t=>e.attr(t,null)),e.attr("data-mce-contenteditable",null))})})})},J=e=>t=>{const n=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",n),n(),()=>{e.off("NodeChange",n)}},W=e=>t=>{const n=()=>{t.setActive(R(e)),t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",n),n(),()=>{e.off("NodeChange",n)}};e.add("checkbox",e=>(P(e),(e=>{const t=()=>e.execCommand("mceInsertCheckbox");e.ui.registry.addButton("checkbox",{icon:"checkbox",tooltip:"Insert checkbox",onAction:t,onSetup:J(e)}),e.ui.registry.addMenuItem("checkbox",{text:"Checkbox",icon:"checkbox",onAction:t,onSetup:J(e)}),e.hasPlugin("lists")&&(e=>{const t=()=>e.execCommand("mceToggleChecklist");e.ui.registry.addToggleButton("checklist",{icon:"checklist",tooltip:"Checklist",onAction:t,onSetup:W(e)}),e.ui.registry.addToggleMenuItem("checklist",{text:"Checklist",icon:"checklist",onAction:t,onSetup:W(e)})})(e)})(e),G(e),(e=>{let t=null;e.on("mousedown",n=>{t=0!==n.button||F(n)?null:u(e,n.target).getOrNull()},!0),e.on("keydown",()=>{t=null}),e.on("BeforeObjectSelected",n=>{if(n.target===t){n.preventDefault();const t=e.dom.createRng();t.setStartAfter(n.target),t.collapse(!0),e.selection.setRng(t)}}),e.on("dragstart",e=>{e.target===t&&e.preventDefault()}),e.on("click",n=>{t=null,F(n)||u(e,n.target).each(t=>{n.preventDefault(),((e,t)=>{e.undoManager.transact(()=>{var e,n;t.textContent="\u2612"===(n=null!==(e=t.textContent)&&void 0!==e?e:"")||"\u2611"===n?"\u2610":"\u2612"})})(e,t)}),(e=>{const t=e.selection.getRng(),n=e.dom.getParent(t.startContainer,t=>e.dom.isBlock(t));t.collapsed&&n&&N(e.dom.select(`span.${a}`,n),n=>{(e=>{let t=e.nextSibling;for(;t&&_(t);)t=t.nextSibling;return s.from(t).filter(e=>e.nodeType===Node.TEXT_NODE&&/^[ \u00a0]/.test(e.data))})(n).each(o=>{const r=e.dom.createRng();r.setStartAfter(n);const s=e.dom.createRng();s.setStart(o,1),t.compareBoundaryPoints(t.START_TO_START,r)>=0&&t.compareBoundaryPoints(t.START_TO_START,s)<0&&e.selection.setCursorLocation(o,1)})})})(e)})})(e),(e=>{e.on("ListMutation",t=>{((e,t)=>("UL"===(null==t?void 0:t.nodeName)||"OL"===(null==t?void 0:t.nodeName))&&t.classList.contains(x)&&!("UL"===t.nodeName&&"none"===e.dom.getStyle(t,"list-style-type")))(e,t.element)&&((e,t)=>{N(T(t.children),t=>{"LI"===t.nodeName&&D(e,t)}),t.classList.remove(x),0===t.classList.length&&t.removeAttribute("class")})(e,t.element)}),e.on("NewBlock",t=>{S(t.newBlock)&&B(e,t.newBlock)}),e.on("keydown",t=>{t.keyCode!==k.ENTER||t.shiftKey||t.isDefaultPrevented()||!e.selection.isCollapsed()||s.from(e.dom.getParent(e.selection.getNode(),"li")).filter(t=>S(t)&&((e,t)=>((e,t)=>{for(let n=0,o=e.length;n<o;++n)if(!0!==t(e[n]))return!1;return!0})(T(t.childNodes),t=>O(t)||"BR"===t.nodeName||d(e,t)))(e,t)&&e.dom.isEditable(t)).each(n=>{t.preventDefault();const o=e.undoManager;o.typing&&(o.typing=!1,o.add()),o.transact(()=>{n.innerHTML='<br data-mce-bogus="1">',e.selection.setCursorLocation(n,0),e.execCommand("mceInsertNewLine",!1,t)})})})})(e),{getMetadata:()=>({name:"Checkbox",url:"https://github.com/mild-blue/opentiny/tree/main/modules/tinymce/src/plugins/checkbox"})}))}();
@@ -44,6 +44,30 @@
44
44
  .tox-comments-visible span.tox-comment[data-mce-annotation-active="true"]:not([data-mce-selected="inline-boundary"]) {
45
45
  background-color: #fed635;
46
46
  }
47
+ .mce-checkbox {
48
+ font-family: "Segoe UI Symbol", "Apple Symbols", "DejaVu Sans", "Noto Sans Symbols 2", sans-serif;
49
+ line-height: 1;
50
+ }
51
+ .mce-content-body[contenteditable="true"] .mce-checkbox,
52
+ .mce-content-body [contenteditable="true"] .mce-checkbox {
53
+ cursor: pointer;
54
+ }
55
+ .mce-content-body [contenteditable="false"] .mce-checkbox {
56
+ cursor: default;
57
+ }
58
+ .mce-checklist > li {
59
+ text-indent: -1.25em;
60
+ }
61
+ .mce-checklist > li > ul:not(.mce-checklist),
62
+ .mce-checklist > li > ol {
63
+ text-indent: 0;
64
+ }
65
+ .mce-checklist > li .mce-checkbox {
66
+ display: inline-block;
67
+ text-align: center;
68
+ text-indent: 0;
69
+ width: 1em;
70
+ }
47
71
  .tox-checklist > li:not(.tox-checklist--hidden) {
48
72
  list-style: none;
49
73
  margin: 0.25em 0;