Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
1441 ariadna 2
 * TinyMCE version 7.7.1 (2025-03-05)
1 efrain 3
 */
4
 
5
(function () {
6
    'use strict';
7
 
8
    var global$4 = tinymce.util.Tools.resolve('tinymce.PluginManager');
9
 
1441 ariadna 10
    const random = () => window.crypto.getRandomValues(new Uint32Array(1))[0] / 4294967295;
11
 
1 efrain 12
    let unique = 0;
13
    const generate = prefix => {
14
      const date = new Date();
15
      const time = date.getTime();
1441 ariadna 16
      const random$1 = Math.floor(random() * 1000000000);
1 efrain 17
      unique++;
1441 ariadna 18
      return prefix + '_' + random$1 + unique + String(time);
1 efrain 19
    };
20
 
21
    const hasProto = (v, constructor, predicate) => {
22
      var _a;
23
      if (predicate(v, constructor.prototype)) {
24
        return true;
25
      } else {
26
        return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
27
      }
28
    };
29
    const typeOf = x => {
30
      const t = typeof x;
31
      if (x === null) {
32
        return 'null';
33
      } else if (t === 'object' && Array.isArray(x)) {
34
        return 'array';
35
      } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
36
        return 'string';
37
      } else {
38
        return t;
39
      }
40
    };
41
    const isType$1 = type => value => typeOf(value) === type;
42
    const isSimpleType = type => value => typeof value === type;
43
    const isString = isType$1('string');
44
    const isBoolean = isSimpleType('boolean');
45
    const isNullable = a => a === null || a === undefined;
46
    const isNonNullable = a => !isNullable(a);
47
    const isFunction = isSimpleType('function');
48
    const isNumber = isSimpleType('number');
49
 
50
    const compose1 = (fbc, fab) => a => fbc(fab(a));
51
    const constant = value => {
52
      return () => {
53
        return value;
54
      };
55
    };
56
    const tripleEquals = (a, b) => {
57
      return a === b;
58
    };
59
    const never = constant(false);
60
 
61
    class Optional {
62
      constructor(tag, value) {
63
        this.tag = tag;
64
        this.value = value;
65
      }
66
      static some(value) {
67
        return new Optional(true, value);
68
      }
69
      static none() {
70
        return Optional.singletonNone;
71
      }
72
      fold(onNone, onSome) {
73
        if (this.tag) {
74
          return onSome(this.value);
75
        } else {
76
          return onNone();
77
        }
78
      }
79
      isSome() {
80
        return this.tag;
81
      }
82
      isNone() {
83
        return !this.tag;
84
      }
85
      map(mapper) {
86
        if (this.tag) {
87
          return Optional.some(mapper(this.value));
88
        } else {
89
          return Optional.none();
90
        }
91
      }
92
      bind(binder) {
93
        if (this.tag) {
94
          return binder(this.value);
95
        } else {
96
          return Optional.none();
97
        }
98
      }
99
      exists(predicate) {
100
        return this.tag && predicate(this.value);
101
      }
102
      forall(predicate) {
103
        return !this.tag || predicate(this.value);
104
      }
105
      filter(predicate) {
106
        if (!this.tag || predicate(this.value)) {
107
          return this;
108
        } else {
109
          return Optional.none();
110
        }
111
      }
112
      getOr(replacement) {
113
        return this.tag ? this.value : replacement;
114
      }
115
      or(replacement) {
116
        return this.tag ? this : replacement;
117
      }
118
      getOrThunk(thunk) {
119
        return this.tag ? this.value : thunk();
120
      }
121
      orThunk(thunk) {
122
        return this.tag ? this : thunk();
123
      }
124
      getOrDie(message) {
125
        if (!this.tag) {
126
          throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
127
        } else {
128
          return this.value;
129
        }
130
      }
131
      static from(value) {
132
        return isNonNullable(value) ? Optional.some(value) : Optional.none();
133
      }
134
      getOrNull() {
135
        return this.tag ? this.value : null;
136
      }
137
      getOrUndefined() {
138
        return this.value;
139
      }
140
      each(worker) {
141
        if (this.tag) {
142
          worker(this.value);
143
        }
144
      }
145
      toArray() {
146
        return this.tag ? [this.value] : [];
147
      }
148
      toString() {
149
        return this.tag ? `some(${ this.value })` : 'none()';
150
      }
151
    }
152
    Optional.singletonNone = new Optional(false);
153
 
154
    const nativeIndexOf = Array.prototype.indexOf;
155
    const rawIndexOf = (ts, t) => nativeIndexOf.call(ts, t);
156
    const contains = (xs, x) => rawIndexOf(xs, x) > -1;
157
    const map = (xs, f) => {
158
      const len = xs.length;
159
      const r = new Array(len);
160
      for (let i = 0; i < len; i++) {
161
        const x = xs[i];
162
        r[i] = f(x, i);
163
      }
164
      return r;
165
    };
166
    const each$1 = (xs, f) => {
167
      for (let i = 0, len = xs.length; i < len; i++) {
168
        const x = xs[i];
169
        f(x, i);
170
      }
171
    };
172
    const filter = (xs, pred) => {
173
      const r = [];
174
      for (let i = 0, len = xs.length; i < len; i++) {
175
        const x = xs[i];
176
        if (pred(x, i)) {
177
          r.push(x);
178
        }
179
      }
180
      return r;
181
    };
182
    const foldl = (xs, f, acc) => {
183
      each$1(xs, (x, i) => {
184
        acc = f(acc, x, i);
185
      });
186
      return acc;
187
    };
188
 
189
    const keys = Object.keys;
190
    const each = (obj, f) => {
191
      const props = keys(obj);
192
      for (let k = 0, len = props.length; k < len; k++) {
193
        const i = props[k];
194
        const x = obj[i];
195
        f(x, i);
196
      }
197
    };
198
 
199
    typeof window !== 'undefined' ? window : Function('return this;')();
200
 
201
    const COMMENT = 8;
202
    const DOCUMENT = 9;
203
    const DOCUMENT_FRAGMENT = 11;
204
    const ELEMENT = 1;
205
    const TEXT = 3;
206
 
207
    const name = element => {
208
      const r = element.dom.nodeName;
209
      return r.toLowerCase();
210
    };
211
    const type = element => element.dom.nodeType;
212
    const isType = t => element => type(element) === t;
213
    const isComment = element => type(element) === COMMENT || name(element) === '#comment';
214
    const isElement = isType(ELEMENT);
215
    const isText = isType(TEXT);
216
    const isDocument = isType(DOCUMENT);
217
    const isDocumentFragment = isType(DOCUMENT_FRAGMENT);
218
 
219
    const rawSet = (dom, key, value) => {
220
      if (isString(value) || isBoolean(value) || isNumber(value)) {
221
        dom.setAttribute(key, value + '');
222
      } else {
223
        console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
224
        throw new Error('Attribute value was not simple');
225
      }
226
    };
227
    const set$2 = (element, key, value) => {
228
      rawSet(element.dom, key, value);
229
    };
230
    const setAll = (element, attrs) => {
231
      const dom = element.dom;
232
      each(attrs, (v, k) => {
233
        rawSet(dom, k, v);
234
      });
235
    };
236
    const get$2 = (element, key) => {
237
      const v = element.dom.getAttribute(key);
238
      return v === null ? undefined : v;
239
    };
240
    const getOpt = (element, key) => Optional.from(get$2(element, key));
241
    const remove$2 = (element, key) => {
242
      element.dom.removeAttribute(key);
243
    };
244
    const clone = element => foldl(element.dom.attributes, (acc, attr) => {
245
      acc[attr.name] = attr.value;
246
      return acc;
247
    }, {});
248
 
249
    const fromHtml = (html, scope) => {
250
      const doc = scope || document;
251
      const div = doc.createElement('div');
252
      div.innerHTML = html;
253
      if (!div.hasChildNodes() || div.childNodes.length > 1) {
254
        const message = 'HTML does not have a single root node';
255
        console.error(message, html);
256
        throw new Error(message);
257
      }
258
      return fromDom(div.childNodes[0]);
259
    };
260
    const fromTag = (tag, scope) => {
261
      const doc = scope || document;
262
      const node = doc.createElement(tag);
263
      return fromDom(node);
264
    };
265
    const fromText = (text, scope) => {
266
      const doc = scope || document;
267
      const node = doc.createTextNode(text);
268
      return fromDom(node);
269
    };
270
    const fromDom = node => {
271
      if (node === null || node === undefined) {
272
        throw new Error('Node cannot be null or undefined');
273
      }
274
      return { dom: node };
275
    };
276
    const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
277
    const SugarElement = {
278
      fromHtml,
279
      fromTag,
280
      fromText,
281
      fromDom,
282
      fromPoint
283
    };
284
 
285
    const is$2 = (element, selector) => {
286
      const dom = element.dom;
287
      if (dom.nodeType !== ELEMENT) {
288
        return false;
289
      } else {
290
        const elem = dom;
291
        if (elem.matches !== undefined) {
292
          return elem.matches(selector);
293
        } else if (elem.msMatchesSelector !== undefined) {
294
          return elem.msMatchesSelector(selector);
295
        } else if (elem.webkitMatchesSelector !== undefined) {
296
          return elem.webkitMatchesSelector(selector);
297
        } else if (elem.mozMatchesSelector !== undefined) {
298
          return elem.mozMatchesSelector(selector);
299
        } else {
300
          throw new Error('Browser lacks native selectors');
301
        }
302
      }
303
    };
304
    const bypassSelector = dom => dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;
305
    const all = (selector, scope) => {
306
      const base = scope === undefined ? document : scope.dom;
307
      return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), SugarElement.fromDom);
308
    };
309
    const one = (selector, scope) => {
310
      const base = scope === undefined ? document : scope.dom;
311
      return bypassSelector(base) ? Optional.none() : Optional.from(base.querySelector(selector)).map(SugarElement.fromDom);
312
    };
313
 
314
    const eq = (e1, e2) => e1.dom === e2.dom;
315
    const is$1 = is$2;
316
 
317
    const is = (lhs, rhs, comparator = tripleEquals) => lhs.exists(left => comparator(left, rhs));
318
 
319
    const blank = r => s => s.replace(r, '');
320
    const trim = blank(/^\s+|\s+$/g);
321
 
322
    const isSupported = dom => dom.style !== undefined && isFunction(dom.style.getPropertyValue);
323
 
324
    const owner = element => SugarElement.fromDom(element.dom.ownerDocument);
325
    const documentOrOwner = dos => isDocument(dos) ? dos : owner(dos);
326
    const parent = element => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
327
    const parents = (element, isRoot) => {
328
      const stop = isFunction(isRoot) ? isRoot : never;
329
      let dom = element.dom;
330
      const ret = [];
331
      while (dom.parentNode !== null && dom.parentNode !== undefined) {
332
        const rawParent = dom.parentNode;
333
        const p = SugarElement.fromDom(rawParent);
334
        ret.push(p);
335
        if (stop(p) === true) {
336
          break;
337
        } else {
338
          dom = rawParent;
339
        }
340
      }
341
      return ret;
342
    };
343
    const prevSibling = element => Optional.from(element.dom.previousSibling).map(SugarElement.fromDom);
344
    const nextSibling = element => Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
345
    const children = element => map(element.dom.childNodes, SugarElement.fromDom);
346
    const child = (element, index) => {
347
      const cs = element.dom.childNodes;
348
      return Optional.from(cs[index]).map(SugarElement.fromDom);
349
    };
350
    const firstChild = element => child(element, 0);
351
 
352
    const isShadowRoot = dos => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
1441 ariadna 353
    const getRootNode = e => SugarElement.fromDom(e.dom.getRootNode());
1 efrain 354
    const getShadowRoot = e => {
355
      const r = getRootNode(e);
356
      return isShadowRoot(r) ? Optional.some(r) : Optional.none();
357
    };
358
    const getShadowHost = e => SugarElement.fromDom(e.dom.host);
359
 
360
    const inBody = element => {
361
      const dom = isText(element) ? element.dom.parentNode : element.dom;
362
      if (dom === undefined || dom === null || dom.ownerDocument === null) {
363
        return false;
364
      }
365
      const doc = dom.ownerDocument;
366
      return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
367
    };
368
 
369
    const internalSet = (dom, property, value) => {
370
      if (!isString(value)) {
371
        console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
372
        throw new Error('CSS value must be a string: ' + value);
373
      }
374
      if (isSupported(dom)) {
375
        dom.style.setProperty(property, value);
376
      }
377
    };
378
    const internalRemove = (dom, property) => {
379
      if (isSupported(dom)) {
380
        dom.style.removeProperty(property);
381
      }
382
    };
383
    const set$1 = (element, property, value) => {
384
      const dom = element.dom;
385
      internalSet(dom, property, value);
386
    };
387
    const get$1 = (element, property) => {
388
      const dom = element.dom;
389
      const styles = window.getComputedStyle(dom);
390
      const r = styles.getPropertyValue(property);
391
      return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
392
    };
393
    const getUnsafeProperty = (dom, property) => isSupported(dom) ? dom.style.getPropertyValue(property) : '';
394
    const getRaw = (element, property) => {
395
      const dom = element.dom;
396
      const raw = getUnsafeProperty(dom, property);
397
      return Optional.from(raw).filter(r => r.length > 0);
398
    };
399
    const remove$1 = (element, property) => {
400
      const dom = element.dom;
401
      internalRemove(dom, property);
402
      if (is(getOpt(element, 'style').map(trim), '')) {
403
        remove$2(element, 'style');
404
      }
405
    };
406
 
407
    const before = (marker, element) => {
408
      const parent$1 = parent(marker);
409
      parent$1.each(v => {
410
        v.dom.insertBefore(element.dom, marker.dom);
411
      });
412
    };
413
    const after$1 = (marker, element) => {
414
      const sibling = nextSibling(marker);
415
      sibling.fold(() => {
416
        const parent$1 = parent(marker);
417
        parent$1.each(v => {
418
          append$1(v, element);
419
        });
420
      }, v => {
421
        before(v, element);
422
      });
423
    };
424
    const prepend = (parent, element) => {
425
      const firstChild$1 = firstChild(parent);
426
      firstChild$1.fold(() => {
427
        append$1(parent, element);
428
      }, v => {
429
        parent.dom.insertBefore(element.dom, v.dom);
430
      });
431
    };
432
    const append$1 = (parent, element) => {
433
      parent.dom.appendChild(element.dom);
434
    };
435
    const wrap = (element, wrapper) => {
436
      before(element, wrapper);
437
      append$1(wrapper, element);
438
    };
439
 
440
    const after = (marker, elements) => {
441
      each$1(elements, (x, i) => {
442
        const e = i === 0 ? marker : elements[i - 1];
443
        after$1(e, x);
444
      });
445
    };
446
    const append = (parent, elements) => {
447
      each$1(elements, x => {
448
        append$1(parent, x);
449
      });
450
    };
451
 
452
    const descendants$1 = (scope, predicate) => {
453
      let result = [];
454
      each$1(children(scope), x => {
455
        if (predicate(x)) {
456
          result = result.concat([x]);
457
        }
458
        result = result.concat(descendants$1(x, predicate));
459
      });
460
      return result;
461
    };
462
 
463
    var ClosestOrAncestor = (is, ancestor, scope, a, isRoot) => {
464
      if (is(scope, a)) {
465
        return Optional.some(scope);
466
      } else if (isFunction(isRoot) && isRoot(scope)) {
467
        return Optional.none();
468
      } else {
469
        return ancestor(scope, a, isRoot);
470
      }
471
    };
472
 
473
    const ancestor$1 = (scope, predicate, isRoot) => {
474
      let element = scope.dom;
475
      const stop = isFunction(isRoot) ? isRoot : never;
476
      while (element.parentNode) {
477
        element = element.parentNode;
478
        const el = SugarElement.fromDom(element);
479
        if (predicate(el)) {
480
          return Optional.some(el);
481
        } else if (stop(el)) {
482
          break;
483
        }
484
      }
485
      return Optional.none();
486
    };
487
 
488
    const remove = element => {
489
      const dom = element.dom;
490
      if (dom.parentNode !== null) {
491
        dom.parentNode.removeChild(dom);
492
      }
493
    };
494
    const unwrap = wrapper => {
495
      const children$1 = children(wrapper);
496
      if (children$1.length > 0) {
497
        after(wrapper, children$1);
498
      }
499
      remove(wrapper);
500
    };
501
 
502
    const descendants = (scope, selector) => all(selector, scope);
503
 
504
    const ancestor = (scope, selector, isRoot) => ancestor$1(scope, e => is$2(e, selector), isRoot);
505
    const descendant = (scope, selector) => one(selector, scope);
506
    const closest = (scope, selector, isRoot) => {
507
      const is = (element, selector) => is$2(element, selector);
508
      return ClosestOrAncestor(is, ancestor, scope, selector, isRoot);
509
    };
510
 
511
    const NodeValue = (is, name) => {
512
      const get = element => {
513
        if (!is(element)) {
514
          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
515
        }
516
        return getOption(element).getOr('');
517
      };
518
      const getOption = element => is(element) ? Optional.from(element.dom.nodeValue) : Optional.none();
519
      const set = (element, value) => {
520
        if (!is(element)) {
521
          throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node');
522
        }
523
        element.dom.nodeValue = value;
524
      };
525
      return {
526
        get,
527
        getOption,
528
        set
529
      };
530
    };
531
 
532
    const api = NodeValue(isText, 'text');
533
    const get = element => api.get(element);
534
    const set = (element, value) => api.set(element, value);
535
 
536
    var TagBoundaries = [
537
      'body',
538
      'p',
539
      'div',
540
      'article',
541
      'aside',
542
      'figcaption',
543
      'figure',
544
      'footer',
545
      'header',
546
      'nav',
547
      'section',
548
      'ol',
549
      'ul',
550
      'li',
551
      'table',
552
      'thead',
553
      'tbody',
554
      'tfoot',
555
      'caption',
556
      'tr',
557
      'td',
558
      'th',
559
      'h1',
560
      'h2',
561
      'h3',
562
      'h4',
563
      'h5',
564
      'h6',
565
      'blockquote',
566
      'pre',
567
      'address'
568
    ];
569
 
570
    var DomUniverse = () => {
571
      const clone$1 = element => {
572
        return SugarElement.fromDom(element.dom.cloneNode(false));
573
      };
574
      const document = element => documentOrOwner(element).dom;
575
      const isBoundary = element => {
576
        if (!isElement(element)) {
577
          return false;
578
        }
579
        if (name(element) === 'body') {
580
          return true;
581
        }
582
        return contains(TagBoundaries, name(element));
583
      };
584
      const isEmptyTag = element => {
585
        if (!isElement(element)) {
586
          return false;
587
        }
588
        return contains([
589
          'br',
590
          'img',
591
          'hr',
592
          'input'
593
        ], name(element));
594
      };
595
      const isNonEditable = element => isElement(element) && get$2(element, 'contenteditable') === 'false';
596
      const comparePosition = (element, other) => {
597
        return element.dom.compareDocumentPosition(other.dom);
598
      };
599
      const copyAttributesTo = (source, destination) => {
600
        const as = clone(source);
601
        setAll(destination, as);
602
      };
603
      const isSpecial = element => {
604
        const tag = name(element);
605
        return contains([
606
          'script',
607
          'noscript',
608
          'iframe',
609
          'noframes',
610
          'noembed',
611
          'title',
612
          'style',
613
          'textarea',
614
          'xmp'
615
        ], tag);
616
      };
617
      const getLanguage = element => isElement(element) ? getOpt(element, 'lang') : Optional.none();
618
      return {
619
        up: constant({
620
          selector: ancestor,
621
          closest: closest,
622
          predicate: ancestor$1,
623
          all: parents
624
        }),
625
        down: constant({
626
          selector: descendants,
627
          predicate: descendants$1
628
        }),
629
        styles: constant({
630
          get: get$1,
631
          getRaw: getRaw,
632
          set: set$1,
633
          remove: remove$1
634
        }),
635
        attrs: constant({
636
          get: get$2,
637
          set: set$2,
638
          remove: remove$2,
639
          copyTo: copyAttributesTo
640
        }),
641
        insert: constant({
642
          before: before,
643
          after: after$1,
644
          afterAll: after,
645
          append: append$1,
646
          appendAll: append,
647
          prepend: prepend,
648
          wrap: wrap
649
        }),
650
        remove: constant({
651
          unwrap: unwrap,
652
          remove: remove
653
        }),
654
        create: constant({
655
          nu: SugarElement.fromTag,
656
          clone: clone$1,
657
          text: SugarElement.fromText
658
        }),
659
        query: constant({
660
          comparePosition,
661
          prevSibling: prevSibling,
662
          nextSibling: nextSibling
663
        }),
664
        property: constant({
665
          children: children,
666
          name: name,
667
          parent: parent,
668
          document,
669
          isText: isText,
670
          isComment: isComment,
671
          isElement: isElement,
672
          isSpecial,
673
          getLanguage,
674
          getText: get,
675
          setText: set,
676
          isBoundary,
677
          isEmptyTag,
678
          isNonEditable
679
        }),
680
        eq: eq,
681
        is: is$1
682
      };
683
    };
684
 
685
    const point = (element, offset) => ({
686
      element,
687
      offset
688
    });
689
 
690
    const scan = (universe, element, direction) => {
691
      if (universe.property().isText(element) && universe.property().getText(element).trim().length === 0 || universe.property().isComment(element)) {
692
        return direction(element).bind(elem => {
693
          return scan(universe, elem, direction).orThunk(() => {
694
            return Optional.some(elem);
695
          });
696
        });
697
      } else {
698
        return Optional.none();
699
      }
700
    };
701
    const toEnd = (universe, element) => {
702
      if (universe.property().isText(element)) {
703
        return universe.property().getText(element).length;
704
      }
705
      const children = universe.property().children(element);
706
      return children.length;
707
    };
708
    const freefallRtl$2 = (universe, element) => {
709
      const candidate = scan(universe, element, universe.query().prevSibling).getOr(element);
710
      if (universe.property().isText(candidate)) {
711
        return point(candidate, toEnd(universe, candidate));
712
      }
713
      const children = universe.property().children(candidate);
714
      return children.length > 0 ? freefallRtl$2(universe, children[children.length - 1]) : point(candidate, toEnd(universe, candidate));
715
    };
716
 
717
    const freefallRtl$1 = freefallRtl$2;
718
 
719
    const universe = DomUniverse();
720
    const freefallRtl = element => {
721
      return freefallRtl$1(universe, element);
722
    };
723
 
724
    const fireToggleAccordionEvent = (editor, element, state) => editor.dispatch('ToggledAccordion', {
725
      element,
726
      state
727
    });
728
    const fireToggleAllAccordionsEvent = (editor, elements, state) => editor.dispatch('ToggledAllAccordions', {
729
      elements,
730
      state
731
    });
732
 
733
    const accordionTag = 'details';
734
    const accordionDetailsClass = 'mce-accordion';
735
    const accordionSummaryClass = 'mce-accordion-summary';
736
    const accordionBodyWrapperClass = 'mce-accordion-body';
737
    const accordionBodyWrapperTag = 'div';
738
 
739
    var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools');
740
 
741
    const isSummary = node => (node === null || node === void 0 ? void 0 : node.nodeName) === 'SUMMARY';
742
    const isDetails = node => (node === null || node === void 0 ? void 0 : node.nodeName) === 'DETAILS';
743
    const isOpen = details => details.hasAttribute('open');
744
    const isInSummary = editor => {
745
      const node = editor.selection.getNode();
746
      return isSummary(node) || Boolean(editor.dom.getParent(node, isSummary));
747
    };
748
    const isAtDetailsStart = editor => {
749
      const rng = editor.selection.getRng();
750
      return isDetails(rng.startContainer) && rng.collapsed && rng.startOffset === 0;
751
    };
1441 ariadna 752
    const isInsertAllowed = editor => !isInSummary(editor) && editor.dom.isEditable(editor.selection.getNode()) && !editor.mode.isReadOnly();
1 efrain 753
    const getSelectedDetails = editor => Optional.from(editor.dom.getParent(editor.selection.getNode(), isDetails));
754
    const isDetailsSelected = editor => getSelectedDetails(editor).isSome();
755
    const insertBogus = element => {
756
      element.innerHTML = '<br data-mce-bogus="1" />';
757
      return element;
758
    };
759
    const createParagraph = editor => insertBogus(editor.dom.create('p'));
760
    const createSummary = editor => insertBogus(editor.dom.create('summary'));
761
    const insertAndSelectParagraphAfter = (editor, target) => {
762
      const paragraph = createParagraph(editor);
763
      target.insertAdjacentElement('afterend', paragraph);
764
      editor.selection.setCursorLocation(paragraph, 0);
765
    };
766
    const normalizeContent = (editor, accordion) => {
767
      if (isSummary(accordion === null || accordion === void 0 ? void 0 : accordion.lastChild)) {
768
        const paragraph = createParagraph(editor);
769
        accordion.appendChild(paragraph);
770
        editor.selection.setCursorLocation(paragraph, 0);
771
      }
772
    };
773
    const normalizeSummary = (editor, accordion) => {
774
      if (!isSummary(accordion === null || accordion === void 0 ? void 0 : accordion.firstChild)) {
775
        const summary = createSummary(editor);
776
        accordion.prepend(summary);
777
        editor.selection.setCursorLocation(summary, 0);
778
      }
779
    };
780
    const normalizeAccordion = editor => accordion => {
781
      normalizeContent(editor, accordion);
782
      normalizeSummary(editor, accordion);
783
    };
784
    const normalizeDetails = editor => {
785
      global$3.each(global$3.grep(editor.dom.select('details', editor.getBody())), normalizeAccordion(editor));
786
    };
787
 
788
    const insertAccordion = editor => {
789
      if (!isInsertAllowed(editor)) {
790
        return;
791
      }
792
      const editorBody = SugarElement.fromDom(editor.getBody());
793
      const uid = generate('acc');
794
      const summaryText = editor.dom.encode(editor.selection.getRng().toString() || editor.translate('Accordion summary...'));
795
      const bodyText = editor.dom.encode(editor.translate('Accordion body...'));
796
      const accordionSummaryHtml = `<summary class="${ accordionSummaryClass }">${ summaryText }</summary>`;
797
      const accordionBodyHtml = `<${ accordionBodyWrapperTag } class="${ accordionBodyWrapperClass }"><p>${ bodyText }</p></${ accordionBodyWrapperTag }>`;
798
      editor.undoManager.transact(() => {
799
        editor.insertContent([
800
          `<details data-mce-id="${ uid }" class="${ accordionDetailsClass }" open="open">`,
801
          accordionSummaryHtml,
802
          accordionBodyHtml,
803
          `</details>`
804
        ].join(''));
805
        descendant(editorBody, `[data-mce-id="${ uid }"]`).each(detailsElm => {
806
          remove$2(detailsElm, 'data-mce-id');
807
          descendant(detailsElm, `summary`).each(summaryElm => {
808
            const rng = editor.dom.createRng();
809
            const des = freefallRtl(summaryElm);
810
            rng.setStart(des.element.dom, des.offset);
811
            rng.setEnd(des.element.dom, des.offset);
812
            editor.selection.setRng(rng);
813
          });
814
        });
815
      });
816
    };
817
    const toggleDetailsElement = (details, state) => {
818
      const shouldOpen = state !== null && state !== void 0 ? state : !isOpen(details);
819
      if (shouldOpen) {
820
        details.setAttribute('open', 'open');
821
      } else {
822
        details.removeAttribute('open');
823
      }
824
      return shouldOpen;
825
    };
826
    const toggleAccordion = (editor, state) => {
827
      getSelectedDetails(editor).each(details => {
828
        fireToggleAccordionEvent(editor, details, toggleDetailsElement(details, state));
829
      });
830
    };
831
    const removeAccordion = editor => {
1441 ariadna 832
      if (!editor.mode.isReadOnly()) {
833
        getSelectedDetails(editor).each(details => {
834
          const {nextSibling} = details;
835
          if (nextSibling) {
836
            editor.selection.select(nextSibling, true);
837
            editor.selection.collapse(true);
838
          } else {
839
            insertAndSelectParagraphAfter(editor, details);
840
          }
841
          details.remove();
842
        });
843
      }
1 efrain 844
    };
845
    const toggleAllAccordions = (editor, state) => {
846
      const accordions = Array.from(editor.getBody().querySelectorAll('details'));
847
      if (accordions.length === 0) {
848
        return;
849
      }
850
      each$1(accordions, accordion => toggleDetailsElement(accordion, state !== null && state !== void 0 ? state : !isOpen(accordion)));
851
      fireToggleAllAccordionsEvent(editor, accordions, state);
852
    };
853
 
854
    const register$1 = editor => {
855
      editor.addCommand('InsertAccordion', () => insertAccordion(editor));
856
      editor.addCommand('ToggleAccordion', (_ui, value) => toggleAccordion(editor, value));
857
      editor.addCommand('ToggleAllAccordions', (_ui, value) => toggleAllAccordions(editor, value));
858
      editor.addCommand('RemoveAccordion', () => removeAccordion(editor));
859
    };
860
 
861
    var global$2 = tinymce.util.Tools.resolve('tinymce.html.Node');
862
 
863
    const getClassList = node => {
864
      var _a, _b;
865
      return (_b = (_a = node.attr('class')) === null || _a === void 0 ? void 0 : _a.split(' ')) !== null && _b !== void 0 ? _b : [];
866
    };
867
    const addClasses = (node, classes) => {
868
      const classListSet = new Set([
869
        ...getClassList(node),
870
        ...classes
871
      ]);
872
      const newClassList = Array.from(classListSet);
873
      if (newClassList.length > 0) {
874
        node.attr('class', newClassList.join(' '));
875
      }
876
    };
877
    const removeClasses = (node, classes) => {
878
      const newClassList = filter(getClassList(node), clazz => !classes.has(clazz));
879
      node.attr('class', newClassList.length > 0 ? newClassList.join(' ') : null);
880
    };
881
    const isAccordionDetailsNode = node => node.name === accordionTag && contains(getClassList(node), accordionDetailsClass);
882
    const isAccordionBodyWrapperNode = node => node.name === accordionBodyWrapperTag && contains(getClassList(node), accordionBodyWrapperClass);
883
    const getAccordionChildren = accordionNode => {
884
      const children = accordionNode.children();
885
      let summaryNode;
886
      let wrapperNode;
887
      const otherNodes = [];
888
      for (let i = 0; i < children.length; i++) {
889
        const child = children[i];
890
        if (child.name === 'summary' && isNullable(summaryNode)) {
891
          summaryNode = child;
892
        } else if (isAccordionBodyWrapperNode(child) && isNullable(wrapperNode)) {
893
          wrapperNode = child;
894
        } else {
895
          otherNodes.push(child);
896
        }
897
      }
898
      return {
899
        summaryNode,
900
        wrapperNode,
901
        otherNodes
902
      };
903
    };
904
    const padInputNode = node => {
905
      const br = new global$2('br', 1);
906
      br.attr('data-mce-bogus', '1');
907
      node.empty();
908
      node.append(br);
909
    };
910
    const setup$2 = editor => {
911
      editor.on('PreInit', () => {
912
        const {serializer, parser} = editor;
913
        parser.addNodeFilter(accordionTag, nodes => {
914
          for (let i = 0; i < nodes.length; i++) {
915
            const node = nodes[i];
916
            if (isAccordionDetailsNode(node)) {
917
              const accordionNode = node;
918
              const {summaryNode, wrapperNode, otherNodes} = getAccordionChildren(accordionNode);
919
              const hasSummaryNode = isNonNullable(summaryNode);
920
              const newSummaryNode = hasSummaryNode ? summaryNode : new global$2('summary', 1);
921
              if (isNullable(newSummaryNode.firstChild)) {
922
                padInputNode(newSummaryNode);
923
              }
924
              addClasses(newSummaryNode, [accordionSummaryClass]);
925
              if (!hasSummaryNode) {
926
                if (isNonNullable(accordionNode.firstChild)) {
927
                  accordionNode.insert(newSummaryNode, accordionNode.firstChild, true);
928
                } else {
929
                  accordionNode.append(newSummaryNode);
930
                }
931
              }
932
              const hasWrapperNode = isNonNullable(wrapperNode);
933
              const newWrapperNode = hasWrapperNode ? wrapperNode : new global$2(accordionBodyWrapperTag, 1);
934
              newWrapperNode.attr('data-mce-bogus', '1');
935
              addClasses(newWrapperNode, [accordionBodyWrapperClass]);
936
              if (otherNodes.length > 0) {
937
                for (let j = 0; j < otherNodes.length; j++) {
938
                  const otherNode = otherNodes[j];
939
                  newWrapperNode.append(otherNode);
940
                }
941
              }
942
              if (isNullable(newWrapperNode.firstChild)) {
943
                const pNode = new global$2('p', 1);
944
                padInputNode(pNode);
945
                newWrapperNode.append(pNode);
946
              }
947
              if (!hasWrapperNode) {
948
                accordionNode.append(newWrapperNode);
949
              }
950
            }
951
          }
952
        });
953
        serializer.addNodeFilter(accordionTag, nodes => {
954
          const summaryClassRemoveSet = new Set([accordionSummaryClass]);
955
          for (let i = 0; i < nodes.length; i++) {
956
            const node = nodes[i];
957
            if (isAccordionDetailsNode(node)) {
958
              const accordionNode = node;
959
              const {summaryNode, wrapperNode} = getAccordionChildren(accordionNode);
960
              if (isNonNullable(summaryNode)) {
961
                removeClasses(summaryNode, summaryClassRemoveSet);
962
              }
963
              if (isNonNullable(wrapperNode)) {
964
                wrapperNode.unwrap();
965
              }
966
            }
967
          }
968
        });
969
      });
970
    };
971
 
972
    var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK');
973
 
974
    const setupEnterKeyInSummary = editor => {
975
      editor.on('keydown', event => {
976
        if (!event.shiftKey && event.keyCode === global$1.ENTER && isInSummary(editor) || isAtDetailsStart(editor)) {
977
          event.preventDefault();
978
          editor.execCommand('ToggleAccordion');
979
        }
980
      });
981
    };
982
    const setup$1 = editor => {
983
      setupEnterKeyInSummary(editor);
984
      editor.on('ExecCommand', e => {
985
        const cmd = e.command.toLowerCase();
986
        if ((cmd === 'delete' || cmd === 'forwarddelete') && isDetailsSelected(editor)) {
987
          normalizeDetails(editor);
988
        }
989
      });
990
    };
991
 
992
    var global = tinymce.util.Tools.resolve('tinymce.Env');
993
 
994
    const setup = editor => {
995
      if (global.browser.isSafari()) {
996
        editor.on('click', e => {
997
          if (isSummary(e.target)) {
998
            const summary = e.target;
999
            const rng = editor.selection.getRng();
1000
            if (rng.collapsed && rng.startContainer === summary.parentNode && rng.startOffset === 0) {
1001
              editor.selection.setCursorLocation(summary, 0);
1002
            }
1003
          }
1004
        });
1005
      }
1006
    };
1007
 
1008
    const onSetup = editor => buttonApi => {
1009
      const onNodeChange = () => buttonApi.setEnabled(isInsertAllowed(editor));
1010
      editor.on('NodeChange', onNodeChange);
1011
      return () => editor.off('NodeChange', onNodeChange);
1012
    };
1013
    const register = editor => {
1014
      const onAction = () => editor.execCommand('InsertAccordion');
1015
      editor.ui.registry.addButton('accordion', {
1016
        icon: 'accordion',
1017
        tooltip: 'Insert accordion',
1018
        onSetup: onSetup(editor),
1019
        onAction
1020
      });
1021
      editor.ui.registry.addMenuItem('accordion', {
1022
        icon: 'accordion',
1023
        text: 'Accordion',
1024
        onSetup: onSetup(editor),
1025
        onAction
1026
      });
1027
      editor.ui.registry.addToggleButton('accordiontoggle', {
1028
        icon: 'accordion-toggle',
1029
        tooltip: 'Toggle accordion',
1030
        onAction: () => editor.execCommand('ToggleAccordion')
1031
      });
1032
      editor.ui.registry.addToggleButton('accordionremove', {
1033
        icon: 'remove',
1034
        tooltip: 'Delete accordion',
1035
        onAction: () => editor.execCommand('RemoveAccordion')
1036
      });
1037
      editor.ui.registry.addContextToolbar('accordion', {
1038
        predicate: accordion => editor.dom.is(accordion, 'details') && editor.getBody().contains(accordion) && editor.dom.isEditable(accordion.parentNode),
1039
        items: 'accordiontoggle accordionremove',
1040
        scope: 'node',
1041
        position: 'node'
1042
      });
1043
    };
1044
 
1045
    var Plugin = () => {
1046
      global$4.add('accordion', editor => {
1047
        register(editor);
1048
        register$1(editor);
1049
        setup$1(editor);
1050
        setup$2(editor);
1051
        setup(editor);
1052
      });
1053
    };
1054
 
1055
    Plugin();
1056
 
1057
})();