Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 * TinyMCE version 6.8.3 (2024-02-08)
3
 */
4
 
5
(function () {
6
    'use strict';
7
 
8
    var global$1 = 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 isString = isType('string');
33
    const isBoolean = isSimpleType('boolean');
34
    const isNullable = a => a === null || a === undefined;
35
    const isNonNullable = a => !isNullable(a);
36
    const isFunction = isSimpleType('function');
37
 
38
    const option = name => editor => editor.options.get(name);
39
    const register = editor => {
40
      const registerOption = editor.options.register;
41
      const toolbarProcessor = defaultValue => value => {
42
        const valid = isBoolean(value) || isString(value);
43
        if (valid) {
44
          if (isBoolean(value)) {
45
            return {
46
              value: value ? defaultValue : '',
47
              valid
48
            };
49
          } else {
50
            return {
51
              value: value.trim(),
52
              valid
53
            };
54
          }
55
        } else {
56
          return {
57
            valid: false,
58
            message: 'Must be a boolean or string.'
59
          };
60
        }
61
      };
62
      const defaultSelectionToolbar = 'bold italic | quicklink h2 h3 blockquote';
63
      registerOption('quickbars_selection_toolbar', {
64
        processor: toolbarProcessor(defaultSelectionToolbar),
65
        default: defaultSelectionToolbar
66
      });
67
      const defaultInsertToolbar = 'quickimage quicktable';
68
      registerOption('quickbars_insert_toolbar', {
69
        processor: toolbarProcessor(defaultInsertToolbar),
70
        default: defaultInsertToolbar
71
      });
72
      const defaultImageToolbar = 'alignleft aligncenter alignright';
73
      registerOption('quickbars_image_toolbar', {
74
        processor: toolbarProcessor(defaultImageToolbar),
75
        default: defaultImageToolbar
76
      });
77
    };
78
    const getTextSelectionToolbarItems = option('quickbars_selection_toolbar');
79
    const getInsertToolbarItems = option('quickbars_insert_toolbar');
80
    const getImageToolbarItems = option('quickbars_image_toolbar');
81
 
82
    let unique = 0;
83
    const generate = prefix => {
84
      const date = new Date();
85
      const time = date.getTime();
86
      const random = Math.floor(Math.random() * 1000000000);
87
      unique++;
88
      return prefix + '_' + random + unique + String(time);
89
    };
90
 
91
    const insertTable = (editor, columns, rows) => {
92
      editor.execCommand('mceInsertTable', false, {
93
        rows,
94
        columns
95
      });
96
    };
97
    const insertBlob = (editor, base64, blob) => {
98
      const blobCache = editor.editorUpload.blobCache;
99
      const blobInfo = blobCache.create(generate('mceu'), blob, base64);
100
      blobCache.add(blobInfo);
101
      editor.insertContent(editor.dom.createHTML('img', { src: blobInfo.blobUri() }));
102
    };
103
 
104
    const blobToBase64 = blob => {
105
      return new Promise(resolve => {
106
        const reader = new FileReader();
107
        reader.onloadend = () => {
108
          resolve(reader.result.split(',')[1]);
109
        };
110
        reader.readAsDataURL(blob);
111
      });
112
    };
113
 
114
    var global = tinymce.util.Tools.resolve('tinymce.util.Delay');
115
 
116
    const pickFile = editor => new Promise(resolve => {
117
      let resolved = false;
118
      const fileInput = document.createElement('input');
119
      fileInput.type = 'file';
120
      fileInput.accept = 'image/*';
121
      fileInput.style.position = 'fixed';
122
      fileInput.style.left = '0';
123
      fileInput.style.top = '0';
124
      fileInput.style.opacity = '0.001';
125
      document.body.appendChild(fileInput);
126
      const resolveFileInput = value => {
127
        var _a;
128
        if (!resolved) {
129
          (_a = fileInput.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(fileInput);
130
          resolved = true;
131
          resolve(value);
132
        }
133
      };
134
      const changeHandler = e => {
135
        resolveFileInput(Array.prototype.slice.call(e.target.files));
136
      };
137
      fileInput.addEventListener('input', changeHandler);
138
      fileInput.addEventListener('change', changeHandler);
139
      const cancelHandler = e => {
140
        const cleanup = () => {
141
          resolveFileInput([]);
142
        };
143
        if (!resolved) {
144
          if (e.type === 'focusin') {
145
            global.setEditorTimeout(editor, cleanup, 1000);
146
          } else {
147
            cleanup();
148
          }
149
        }
150
        editor.off('focusin remove', cancelHandler);
151
      };
152
      editor.on('focusin remove', cancelHandler);
153
      fileInput.click();
154
    });
155
 
156
    const setupButtons = editor => {
157
      editor.ui.registry.addButton('quickimage', {
158
        icon: 'image',
159
        tooltip: 'Insert image',
160
        onAction: () => {
161
          pickFile(editor).then(files => {
162
            if (files.length > 0) {
163
              const blob = files[0];
164
              blobToBase64(blob).then(base64 => {
165
                insertBlob(editor, base64, blob);
166
              });
167
            }
168
          });
169
        }
170
      });
171
      editor.ui.registry.addButton('quicktable', {
172
        icon: 'table',
173
        tooltip: 'Insert table',
174
        onAction: () => {
175
          insertTable(editor, 2, 2);
176
        }
177
      });
178
    };
179
 
180
    const constant = value => {
181
      return () => {
182
        return value;
183
      };
184
    };
185
    const never = constant(false);
186
 
187
    class Optional {
188
      constructor(tag, value) {
189
        this.tag = tag;
190
        this.value = value;
191
      }
192
      static some(value) {
193
        return new Optional(true, value);
194
      }
195
      static none() {
196
        return Optional.singletonNone;
197
      }
198
      fold(onNone, onSome) {
199
        if (this.tag) {
200
          return onSome(this.value);
201
        } else {
202
          return onNone();
203
        }
204
      }
205
      isSome() {
206
        return this.tag;
207
      }
208
      isNone() {
209
        return !this.tag;
210
      }
211
      map(mapper) {
212
        if (this.tag) {
213
          return Optional.some(mapper(this.value));
214
        } else {
215
          return Optional.none();
216
        }
217
      }
218
      bind(binder) {
219
        if (this.tag) {
220
          return binder(this.value);
221
        } else {
222
          return Optional.none();
223
        }
224
      }
225
      exists(predicate) {
226
        return this.tag && predicate(this.value);
227
      }
228
      forall(predicate) {
229
        return !this.tag || predicate(this.value);
230
      }
231
      filter(predicate) {
232
        if (!this.tag || predicate(this.value)) {
233
          return this;
234
        } else {
235
          return Optional.none();
236
        }
237
      }
238
      getOr(replacement) {
239
        return this.tag ? this.value : replacement;
240
      }
241
      or(replacement) {
242
        return this.tag ? this : replacement;
243
      }
244
      getOrThunk(thunk) {
245
        return this.tag ? this.value : thunk();
246
      }
247
      orThunk(thunk) {
248
        return this.tag ? this : thunk();
249
      }
250
      getOrDie(message) {
251
        if (!this.tag) {
252
          throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
253
        } else {
254
          return this.value;
255
        }
256
      }
257
      static from(value) {
258
        return isNonNullable(value) ? Optional.some(value) : Optional.none();
259
      }
260
      getOrNull() {
261
        return this.tag ? this.value : null;
262
      }
263
      getOrUndefined() {
264
        return this.value;
265
      }
266
      each(worker) {
267
        if (this.tag) {
268
          worker(this.value);
269
        }
270
      }
271
      toArray() {
272
        return this.tag ? [this.value] : [];
273
      }
274
      toString() {
275
        return this.tag ? `some(${ this.value })` : 'none()';
276
      }
277
    }
278
    Optional.singletonNone = new Optional(false);
279
 
280
    typeof window !== 'undefined' ? window : Function('return this;')();
281
 
282
    const ELEMENT = 1;
283
 
284
    const name = element => {
285
      const r = element.dom.nodeName;
286
      return r.toLowerCase();
287
    };
288
 
289
    const has$1 = (element, key) => {
290
      const dom = element.dom;
291
      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;
292
    };
293
 
294
    var ClosestOrAncestor = (is, ancestor, scope, a, isRoot) => {
295
      if (is(scope, a)) {
296
        return Optional.some(scope);
297
      } else if (isFunction(isRoot) && isRoot(scope)) {
298
        return Optional.none();
299
      } else {
300
        return ancestor(scope, a, isRoot);
301
      }
302
    };
303
 
304
    const fromHtml = (html, scope) => {
305
      const doc = scope || document;
306
      const div = doc.createElement('div');
307
      div.innerHTML = html;
308
      if (!div.hasChildNodes() || div.childNodes.length > 1) {
309
        const message = 'HTML does not have a single root node';
310
        console.error(message, html);
311
        throw new Error(message);
312
      }
313
      return fromDom(div.childNodes[0]);
314
    };
315
    const fromTag = (tag, scope) => {
316
      const doc = scope || document;
317
      const node = doc.createElement(tag);
318
      return fromDom(node);
319
    };
320
    const fromText = (text, scope) => {
321
      const doc = scope || document;
322
      const node = doc.createTextNode(text);
323
      return fromDom(node);
324
    };
325
    const fromDom = node => {
326
      if (node === null || node === undefined) {
327
        throw new Error('Node cannot be null or undefined');
328
      }
329
      return { dom: node };
330
    };
331
    const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
332
    const SugarElement = {
333
      fromHtml,
334
      fromTag,
335
      fromText,
336
      fromDom,
337
      fromPoint
338
    };
339
 
340
    const is = (element, selector) => {
341
      const dom = element.dom;
342
      if (dom.nodeType !== ELEMENT) {
343
        return false;
344
      } else {
345
        const elem = dom;
346
        if (elem.matches !== undefined) {
347
          return elem.matches(selector);
348
        } else if (elem.msMatchesSelector !== undefined) {
349
          return elem.msMatchesSelector(selector);
350
        } else if (elem.webkitMatchesSelector !== undefined) {
351
          return elem.webkitMatchesSelector(selector);
352
        } else if (elem.mozMatchesSelector !== undefined) {
353
          return elem.mozMatchesSelector(selector);
354
        } else {
355
          throw new Error('Browser lacks native selectors');
356
        }
357
      }
358
    };
359
 
360
    const ancestor$1 = (scope, predicate, isRoot) => {
361
      let element = scope.dom;
362
      const stop = isFunction(isRoot) ? isRoot : never;
363
      while (element.parentNode) {
364
        element = element.parentNode;
365
        const el = SugarElement.fromDom(element);
366
        if (predicate(el)) {
367
          return Optional.some(el);
368
        } else if (stop(el)) {
369
          break;
370
        }
371
      }
372
      return Optional.none();
373
    };
374
    const closest$2 = (scope, predicate, isRoot) => {
375
      const is = (s, test) => test(s);
376
      return ClosestOrAncestor(is, ancestor$1, scope, predicate, isRoot);
377
    };
378
 
379
    const closest$1 = (scope, predicate, isRoot) => closest$2(scope, predicate, isRoot).isSome();
380
 
381
    const ancestor = (scope, selector, isRoot) => ancestor$1(scope, e => is(e, selector), isRoot);
382
    const closest = (scope, selector, isRoot) => {
383
      const is$1 = (element, selector) => is(element, selector);
384
      return ClosestOrAncestor(is$1, ancestor, scope, selector, isRoot);
385
    };
386
 
387
    const addToEditor$1 = editor => {
388
      const insertToolbarItems = getInsertToolbarItems(editor);
389
      if (insertToolbarItems.length > 0) {
390
        editor.ui.registry.addContextToolbar('quickblock', {
391
          predicate: node => {
392
            const sugarNode = SugarElement.fromDom(node);
393
            const textBlockElementsMap = editor.schema.getTextBlockElements();
394
            const isRoot = elem => elem.dom === editor.getBody();
395
            return !has$1(sugarNode, 'data-mce-bogus') && closest(sugarNode, 'table,[data-mce-bogus="all"]', isRoot).fold(() => closest$1(sugarNode, elem => name(elem) in textBlockElementsMap && editor.dom.isEmpty(elem.dom), isRoot), never);
396
          },
397
          items: insertToolbarItems,
398
          position: 'line',
399
          scope: 'editor'
400
        });
401
      }
402
    };
403
 
404
    const supports = element => element.dom.classList !== undefined;
405
 
406
    const has = (element, clazz) => supports(element) && element.dom.classList.contains(clazz);
407
 
408
    const addToEditor = editor => {
409
      const isEditable = node => editor.dom.isEditable(node);
410
      const isInEditableContext = el => isEditable(el.parentElement);
411
      const isImage = node => {
412
        const isImageFigure = node.nodeName === 'FIGURE' && /image/i.test(node.className);
413
        const isImage = node.nodeName === 'IMG' || isImageFigure;
414
        const isPagebreak = has(SugarElement.fromDom(node), 'mce-pagebreak');
415
        return isImage && isInEditableContext(node) && !isPagebreak;
416
      };
417
      const imageToolbarItems = getImageToolbarItems(editor);
418
      if (imageToolbarItems.length > 0) {
419
        editor.ui.registry.addContextToolbar('imageselection', {
420
          predicate: isImage,
421
          items: imageToolbarItems,
422
          position: 'node'
423
        });
424
      }
425
      const textToolbarItems = getTextSelectionToolbarItems(editor);
426
      if (textToolbarItems.length > 0) {
427
        editor.ui.registry.addContextToolbar('textselection', {
428
          predicate: node => !isImage(node) && !editor.selection.isCollapsed() && isEditable(node),
429
          items: textToolbarItems,
430
          position: 'selection',
431
          scope: 'editor'
432
        });
433
      }
434
    };
435
 
436
    var Plugin = () => {
437
      global$1.add('quickbars', editor => {
438
        register(editor);
439
        setupButtons(editor);
440
        addToEditor$1(editor);
441
        addToEditor(editor);
442
      });
443
    };
444
 
445
    Plugin();
446
 
447
})();