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