Subversion Repositories oidplus

Rev

Rev 1042 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
597 daniel-mar 1
/**
2
 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3
 * Licensed under the LGPL or a commercial license.
4
 * For LGPL see License.txt in the project root for license information.
5
 * For commercial licenses see https://www.tiny.cloud/
6
 *
1422 daniel-mar 7
 * Version: 5.10.8 (2023-10-19)
597 daniel-mar 8
 */
9
(function () {
10
    'use strict';
11
 
12
    var Cell = function (initial) {
13
      var value = initial;
14
      var get = function () {
15
        return value;
16
      };
17
      var set = function (v) {
18
        value = v;
19
      };
20
      return {
21
        get: get,
22
        set: set
23
      };
24
    };
25
 
637 daniel-mar 26
    var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
597 daniel-mar 27
 
637 daniel-mar 28
    var get$2 = function (toggleState) {
597 daniel-mar 29
      var isEnabled = function () {
30
        return toggleState.get();
31
      };
32
      return { isEnabled: isEnabled };
33
    };
34
 
35
    var fireVisualChars = function (editor, state) {
36
      return editor.fire('VisualChars', { state: state });
37
    };
38
 
39
    var typeOf = function (x) {
40
      var t = typeof x;
41
      if (x === null) {
42
        return 'null';
43
      } else if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
44
        return 'array';
45
      } else if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
46
        return 'string';
47
      } else {
48
        return t;
49
      }
50
    };
637 daniel-mar 51
    var isType$1 = function (type) {
597 daniel-mar 52
      return function (value) {
53
        return typeOf(value) === type;
54
      };
55
    };
56
    var isSimpleType = function (type) {
57
      return function (value) {
58
        return typeof value === type;
59
      };
60
    };
637 daniel-mar 61
    var isString = isType$1('string');
597 daniel-mar 62
    var isBoolean = isSimpleType('boolean');
63
    var isNumber = isSimpleType('number');
64
 
65
    var noop = function () {
66
    };
67
    var constant = function (value) {
68
      return function () {
69
        return value;
70
      };
71
    };
637 daniel-mar 72
    var identity = function (x) {
73
      return x;
74
    };
597 daniel-mar 75
    var never = constant(false);
76
    var always = constant(true);
77
 
78
    var none = function () {
79
      return NONE;
80
    };
81
    var NONE = function () {
82
      var call = function (thunk) {
83
        return thunk();
84
      };
637 daniel-mar 85
      var id = identity;
597 daniel-mar 86
      var me = {
87
        fold: function (n, _s) {
88
          return n();
89
        },
90
        isSome: never,
91
        isNone: always,
92
        getOr: id,
93
        getOrThunk: call,
94
        getOrDie: function (msg) {
95
          throw new Error(msg || 'error: getOrDie called on none.');
96
        },
97
        getOrNull: constant(null),
98
        getOrUndefined: constant(undefined),
99
        or: id,
100
        orThunk: call,
101
        map: none,
102
        each: noop,
103
        bind: none,
104
        exists: never,
105
        forall: always,
637 daniel-mar 106
        filter: function () {
107
          return none();
108
        },
597 daniel-mar 109
        toArray: function () {
110
          return [];
111
        },
112
        toString: constant('none()')
113
      };
114
      return me;
115
    }();
116
    var some = function (a) {
117
      var constant_a = constant(a);
118
      var self = function () {
119
        return me;
120
      };
121
      var bind = function (f) {
122
        return f(a);
123
      };
124
      var me = {
125
        fold: function (n, s) {
126
          return s(a);
127
        },
128
        isSome: always,
129
        isNone: never,
130
        getOr: constant_a,
131
        getOrThunk: constant_a,
132
        getOrDie: constant_a,
133
        getOrNull: constant_a,
134
        getOrUndefined: constant_a,
135
        or: self,
136
        orThunk: self,
137
        map: function (f) {
138
          return some(f(a));
139
        },
140
        each: function (f) {
141
          f(a);
142
        },
143
        bind: bind,
144
        exists: bind,
145
        forall: bind,
146
        filter: function (f) {
147
          return f(a) ? me : NONE;
148
        },
149
        toArray: function () {
150
          return [a];
151
        },
152
        toString: function () {
153
          return 'some(' + a + ')';
154
        }
155
      };
156
      return me;
157
    };
158
    var from = function (value) {
159
      return value === null || value === undefined ? NONE : some(value);
160
    };
161
    var Optional = {
162
      some: some,
163
      none: none,
164
      from: from
165
    };
166
 
167
    var map = function (xs, f) {
168
      var len = xs.length;
169
      var r = new Array(len);
170
      for (var i = 0; i < len; i++) {
171
        var x = xs[i];
172
        r[i] = f(x, i);
173
      }
174
      return r;
175
    };
637 daniel-mar 176
    var each$1 = function (xs, f) {
597 daniel-mar 177
      for (var i = 0, len = xs.length; i < len; i++) {
178
        var x = xs[i];
179
        f(x, i);
180
      }
181
    };
182
    var filter = function (xs, pred) {
183
      var r = [];
184
      for (var i = 0, len = xs.length; i < len; i++) {
185
        var x = xs[i];
186
        if (pred(x, i)) {
187
          r.push(x);
188
        }
189
      }
190
      return r;
191
    };
192
 
193
    var keys = Object.keys;
637 daniel-mar 194
    var each = function (obj, f) {
597 daniel-mar 195
      var props = keys(obj);
196
      for (var k = 0, len = props.length; k < len; k++) {
197
        var i = props[k];
198
        var x = obj[i];
199
        f(x, i);
200
      }
201
    };
202
 
637 daniel-mar 203
    typeof window !== 'undefined' ? window : Function('return this;')();
597 daniel-mar 204
 
205
    var TEXT = 3;
206
 
207
    var type = function (element) {
208
      return element.dom.nodeType;
209
    };
210
    var value = function (element) {
211
      return element.dom.nodeValue;
212
    };
637 daniel-mar 213
    var isType = function (t) {
597 daniel-mar 214
      return function (element) {
215
        return type(element) === t;
216
      };
217
    };
637 daniel-mar 218
    var isText = isType(TEXT);
597 daniel-mar 219
 
220
    var rawSet = function (dom, key, value) {
221
      if (isString(value) || isBoolean(value) || isNumber(value)) {
222
        dom.setAttribute(key, value + '');
223
      } else {
224
        console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
225
        throw new Error('Attribute value was not simple');
226
      }
227
    };
228
    var set = function (element, key, value) {
229
      rawSet(element.dom, key, value);
230
    };
231
    var get$1 = function (element, key) {
232
      var v = element.dom.getAttribute(key);
233
      return v === null ? undefined : v;
234
    };
637 daniel-mar 235
    var remove$3 = function (element, key) {
597 daniel-mar 236
      element.dom.removeAttribute(key);
237
    };
238
 
239
    var read = function (element, attr) {
240
      var value = get$1(element, attr);
241
      return value === undefined || value === '' ? [] : value.split(' ');
242
    };
637 daniel-mar 243
    var add$2 = function (element, attr, id) {
597 daniel-mar 244
      var old = read(element, attr);
245
      var nu = old.concat([id]);
246
      set(element, attr, nu.join(' '));
247
      return true;
248
    };
637 daniel-mar 249
    var remove$2 = function (element, attr, id) {
597 daniel-mar 250
      var nu = filter(read(element, attr), function (v) {
251
        return v !== id;
252
      });
253
      if (nu.length > 0) {
254
        set(element, attr, nu.join(' '));
255
      } else {
637 daniel-mar 256
        remove$3(element, attr);
597 daniel-mar 257
      }
258
      return false;
259
    };
260
 
261
    var supports = function (element) {
262
      return element.dom.classList !== undefined;
263
    };
637 daniel-mar 264
    var get = function (element) {
597 daniel-mar 265
      return read(element, 'class');
266
    };
267
    var add$1 = function (element, clazz) {
637 daniel-mar 268
      return add$2(element, 'class', clazz);
597 daniel-mar 269
    };
637 daniel-mar 270
    var remove$1 = function (element, clazz) {
271
      return remove$2(element, 'class', clazz);
597 daniel-mar 272
    };
273
 
637 daniel-mar 274
    var add = function (element, clazz) {
597 daniel-mar 275
      if (supports(element)) {
276
        element.dom.classList.add(clazz);
277
      } else {
278
        add$1(element, clazz);
279
      }
280
    };
281
    var cleanClass = function (element) {
637 daniel-mar 282
      var classList = supports(element) ? element.dom.classList : get(element);
597 daniel-mar 283
      if (classList.length === 0) {
637 daniel-mar 284
        remove$3(element, 'class');
597 daniel-mar 285
      }
286
    };
637 daniel-mar 287
    var remove = function (element, clazz) {
597 daniel-mar 288
      if (supports(element)) {
289
        var classList = element.dom.classList;
290
        classList.remove(clazz);
291
      } else {
637 daniel-mar 292
        remove$1(element, clazz);
597 daniel-mar 293
      }
294
      cleanClass(element);
295
    };
296
 
297
    var fromHtml = function (html, scope) {
298
      var doc = scope || document;
299
      var div = doc.createElement('div');
300
      div.innerHTML = html;
301
      if (!div.hasChildNodes() || div.childNodes.length > 1) {
302
        console.error('HTML does not have a single root node', html);
303
        throw new Error('HTML must have a single root node');
304
      }
305
      return fromDom(div.childNodes[0]);
306
    };
307
    var fromTag = function (tag, scope) {
308
      var doc = scope || document;
309
      var node = doc.createElement(tag);
310
      return fromDom(node);
311
    };
312
    var fromText = function (text, scope) {
313
      var doc = scope || document;
314
      var node = doc.createTextNode(text);
315
      return fromDom(node);
316
    };
317
    var fromDom = function (node) {
318
      if (node === null || node === undefined) {
319
        throw new Error('Node cannot be null or undefined');
320
      }
321
      return { dom: node };
322
    };
323
    var fromPoint = function (docElm, x, y) {
324
      return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
325
    };
326
    var SugarElement = {
327
      fromHtml: fromHtml,
328
      fromTag: fromTag,
329
      fromText: fromText,
330
      fromDom: fromDom,
331
      fromPoint: fromPoint
332
    };
333
 
334
    var charMap = {
335
      '\xA0': 'nbsp',
336
      '\xAD': 'shy'
337
    };
338
    var charMapToRegExp = function (charMap, global) {
339
      var regExp = '';
637 daniel-mar 340
      each(charMap, function (_value, key) {
597 daniel-mar 341
        regExp += key;
342
      });
343
      return new RegExp('[' + regExp + ']', global ? 'g' : '');
344
    };
345
    var charMapToSelector = function (charMap) {
346
      var selector = '';
637 daniel-mar 347
      each(charMap, function (value) {
597 daniel-mar 348
        if (selector) {
349
          selector += ',';
350
        }
351
        selector += 'span.mce-' + value;
352
      });
353
      return selector;
354
    };
355
    var regExp = charMapToRegExp(charMap);
356
    var regExpGlobal = charMapToRegExp(charMap, true);
357
    var selector = charMapToSelector(charMap);
358
    var nbspClass = 'mce-nbsp';
359
 
360
    var wrapCharWithSpan = function (value) {
361
      return '<span data-mce-bogus="1" class="mce-' + charMap[value] + '">' + value + '</span>';
362
    };
363
 
364
    var isMatch = function (n) {
365
      var value$1 = value(n);
366
      return isText(n) && value$1 !== undefined && regExp.test(value$1);
367
    };
368
    var filterDescendants = function (scope, predicate) {
369
      var result = [];
370
      var dom = scope.dom;
371
      var children = map(dom.childNodes, SugarElement.fromDom);
637 daniel-mar 372
      each$1(children, function (x) {
597 daniel-mar 373
        if (predicate(x)) {
374
          result = result.concat([x]);
375
        }
376
        result = result.concat(filterDescendants(x, predicate));
377
      });
378
      return result;
379
    };
380
    var findParentElm = function (elm, rootElm) {
381
      while (elm.parentNode) {
382
        if (elm.parentNode === rootElm) {
383
          return elm;
384
        }
385
        elm = elm.parentNode;
386
      }
387
    };
388
    var replaceWithSpans = function (text) {
389
      return text.replace(regExpGlobal, wrapCharWithSpan);
390
    };
391
 
392
    var isWrappedNbsp = function (node) {
393
      return node.nodeName.toLowerCase() === 'span' && node.classList.contains('mce-nbsp-wrap');
394
    };
395
    var show = function (editor, rootElm) {
396
      var nodeList = filterDescendants(SugarElement.fromDom(rootElm), isMatch);
637 daniel-mar 397
      each$1(nodeList, function (n) {
597 daniel-mar 398
        var parent = n.dom.parentNode;
399
        if (isWrappedNbsp(parent)) {
637 daniel-mar 400
          add(SugarElement.fromDom(parent), nbspClass);
597 daniel-mar 401
        } else {
402
          var withSpans = replaceWithSpans(editor.dom.encode(value(n)));
403
          var div = editor.dom.create('div', null, withSpans);
404
          var node = void 0;
405
          while (node = div.lastChild) {
406
            editor.dom.insertAfter(node, n.dom);
407
          }
408
          editor.dom.remove(n.dom);
409
        }
410
      });
411
    };
412
    var hide = function (editor, rootElm) {
413
      var nodeList = editor.dom.select(selector, rootElm);
637 daniel-mar 414
      each$1(nodeList, function (node) {
597 daniel-mar 415
        if (isWrappedNbsp(node)) {
637 daniel-mar 416
          remove(SugarElement.fromDom(node), nbspClass);
597 daniel-mar 417
        } else {
418
          editor.dom.remove(node, true);
419
        }
420
      });
421
    };
422
    var toggle = function (editor) {
423
      var body = editor.getBody();
424
      var bookmark = editor.selection.getBookmark();
425
      var parentNode = findParentElm(editor.selection.getNode(), body);
426
      parentNode = parentNode !== undefined ? parentNode : body;
427
      hide(editor, parentNode);
428
      show(editor, parentNode);
429
      editor.selection.moveToBookmark(bookmark);
430
    };
431
 
432
    var applyVisualChars = function (editor, toggleState) {
433
      fireVisualChars(editor, toggleState.get());
434
      var body = editor.getBody();
435
      if (toggleState.get() === true) {
436
        show(editor, body);
437
      } else {
438
        hide(editor, body);
439
      }
440
    };
441
    var toggleVisualChars = function (editor, toggleState) {
442
      toggleState.set(!toggleState.get());
443
      var bookmark = editor.selection.getBookmark();
444
      applyVisualChars(editor, toggleState);
445
      editor.selection.moveToBookmark(bookmark);
446
    };
447
 
637 daniel-mar 448
    var register$1 = function (editor, toggleState) {
597 daniel-mar 449
      editor.addCommand('mceVisualChars', function () {
450
        toggleVisualChars(editor, toggleState);
451
      });
452
    };
453
 
454
    var isEnabledByDefault = function (editor) {
455
      return editor.getParam('visualchars_default_state', false);
456
    };
457
    var hasForcedRootBlock = function (editor) {
458
      return editor.getParam('forced_root_block') !== false;
459
    };
460
 
637 daniel-mar 461
    var setup$1 = function (editor, toggleState) {
597 daniel-mar 462
      editor.on('init', function () {
463
        applyVisualChars(editor, toggleState);
464
      });
465
    };
466
 
637 daniel-mar 467
    var global = tinymce.util.Tools.resolve('tinymce.util.Delay');
597 daniel-mar 468
 
637 daniel-mar 469
    var setup = function (editor, toggleState) {
470
      var debouncedToggle = global.debounce(function () {
597 daniel-mar 471
        toggle(editor);
472
      }, 300);
473
      if (hasForcedRootBlock(editor)) {
474
        editor.on('keydown', function (e) {
475
          if (toggleState.get() === true) {
476
            e.keyCode === 13 ? toggle(editor) : debouncedToggle();
477
          }
478
        });
479
      }
480
      editor.on('remove', debouncedToggle.stop);
481
    };
482
 
483
    var toggleActiveState = function (editor, enabledStated) {
484
      return function (api) {
485
        api.setActive(enabledStated.get());
486
        var editorEventCallback = function (e) {
487
          return api.setActive(e.state);
488
        };
489
        editor.on('VisualChars', editorEventCallback);
490
        return function () {
491
          return editor.off('VisualChars', editorEventCallback);
492
        };
493
      };
494
    };
637 daniel-mar 495
    var register = function (editor, toggleState) {
496
      var onAction = function () {
497
        return editor.execCommand('mceVisualChars');
498
      };
597 daniel-mar 499
      editor.ui.registry.addToggleButton('visualchars', {
500
        tooltip: 'Show invisible characters',
501
        icon: 'visualchars',
637 daniel-mar 502
        onAction: onAction,
597 daniel-mar 503
        onSetup: toggleActiveState(editor, toggleState)
504
      });
505
      editor.ui.registry.addToggleMenuItem('visualchars', {
506
        text: 'Show invisible characters',
507
        icon: 'visualchars',
637 daniel-mar 508
        onAction: onAction,
597 daniel-mar 509
        onSetup: toggleActiveState(editor, toggleState)
510
      });
511
    };
512
 
513
    function Plugin () {
637 daniel-mar 514
      global$1.add('visualchars', function (editor) {
597 daniel-mar 515
        var toggleState = Cell(isEnabledByDefault(editor));
637 daniel-mar 516
        register$1(editor, toggleState);
597 daniel-mar 517
        register(editor, toggleState);
637 daniel-mar 518
        setup(editor, toggleState);
597 daniel-mar 519
        setup$1(editor, toggleState);
637 daniel-mar 520
        return get$2(toggleState);
597 daniel-mar 521
      });
522
    }
523
 
524
    Plugin();
525
 
526
}());