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 link = () => /(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-.~*+=!;:'%@$(),\/\w]*[-~*+=%@$()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g;
11
 
12
  const option = name => editor => editor.options.get(name);
13
  const register = editor => {
14
    const registerOption = editor.options.register;
15
    registerOption('autolink_pattern', {
16
      processor: 'regexp',
17
      default: new RegExp('^' + link().source + '$', 'i')
18
    });
19
    registerOption('link_default_target', { processor: 'string' });
20
    registerOption('link_default_protocol', {
21
      processor: 'string',
22
      default: 'https'
23
    });
24
  };
25
  const getAutoLinkPattern = option('autolink_pattern');
26
  const getDefaultLinkTarget = option('link_default_target');
27
  const getDefaultLinkProtocol = option('link_default_protocol');
28
  const allowUnsafeLinkTarget = option('allow_unsafe_link_target');
29
 
30
  const hasProto = (v, constructor, predicate) => {
31
    var _a;
32
    if (predicate(v, constructor.prototype)) {
33
      return true;
34
    } else {
35
      return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
36
    }
37
  };
38
  const typeOf = x => {
39
    const t = typeof x;
40
    if (x === null) {
41
      return 'null';
42
    } else if (t === 'object' && Array.isArray(x)) {
43
      return 'array';
44
    } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
45
      return 'string';
46
    } else {
47
      return t;
48
    }
49
  };
50
  const isType = type => value => typeOf(value) === type;
51
  const eq = t => a => t === a;
52
  const isString = isType('string');
53
  const isUndefined = eq(undefined);
54
  const isNullable = a => a === null || a === undefined;
55
  const isNonNullable = a => !isNullable(a);
56
 
57
  const not = f => t => !f(t);
58
 
59
  const hasOwnProperty = Object.hasOwnProperty;
60
  const has = (obj, key) => hasOwnProperty.call(obj, key);
61
 
62
  const checkRange = (str, substr, start) => substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
63
  const contains = (str, substr, start = 0, end) => {
64
    const idx = str.indexOf(substr, start);
65
    if (idx !== -1) {
66
      return isUndefined(end) ? true : idx + substr.length <= end;
67
    } else {
68
      return false;
69
    }
70
  };
71
  const startsWith = (str, prefix) => {
72
    return checkRange(str, prefix, 0);
73
  };
74
 
75
  const zeroWidth = '\uFEFF';
76
  const isZwsp = char => char === zeroWidth;
77
  const removeZwsp = s => s.replace(/\uFEFF/g, '');
78
 
79
  var global = tinymce.util.Tools.resolve('tinymce.dom.TextSeeker');
80
 
81
  const isTextNode = node => node.nodeType === 3;
82
  const isElement = node => node.nodeType === 1;
83
  const isBracketOrSpace = char => /^[(\[{ \u00a0]$/.test(char);
84
  const hasProtocol = url => /^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(url);
85
  const isPunctuation = char => /[?!,.;:]/.test(char);
86
  const findChar = (text, index, predicate) => {
87
    for (let i = index - 1; i >= 0; i--) {
88
      const char = text.charAt(i);
89
      if (!isZwsp(char) && predicate(char)) {
90
        return i;
91
      }
92
    }
93
    return -1;
94
  };
95
  const freefallRtl = (container, offset) => {
96
    let tempNode = container;
97
    let tempOffset = offset;
98
    while (isElement(tempNode) && tempNode.childNodes[tempOffset]) {
99
      tempNode = tempNode.childNodes[tempOffset];
100
      tempOffset = isTextNode(tempNode) ? tempNode.data.length : tempNode.childNodes.length;
101
    }
102
    return {
103
      container: tempNode,
104
      offset: tempOffset
105
    };
106
  };
107
 
108
  const parseCurrentLine = (editor, offset) => {
109
    var _a;
110
    const voidElements = editor.schema.getVoidElements();
111
    const autoLinkPattern = getAutoLinkPattern(editor);
112
    const {dom, selection} = editor;
113
    if (dom.getParent(selection.getNode(), 'a[href]') !== null) {
114
      return null;
115
    }
116
    const rng = selection.getRng();
117
    const textSeeker = global(dom, node => {
118
      return dom.isBlock(node) || has(voidElements, node.nodeName.toLowerCase()) || dom.getContentEditable(node) === 'false';
119
    });
120
    const {
121
      container: endContainer,
122
      offset: endOffset
123
    } = freefallRtl(rng.endContainer, rng.endOffset);
124
    const root = (_a = dom.getParent(endContainer, dom.isBlock)) !== null && _a !== void 0 ? _a : dom.getRoot();
125
    const endSpot = textSeeker.backwards(endContainer, endOffset + offset, (node, offset) => {
126
      const text = node.data;
127
      const idx = findChar(text, offset, not(isBracketOrSpace));
128
      return idx === -1 || isPunctuation(text[idx]) ? idx : idx + 1;
129
    }, root);
130
    if (!endSpot) {
131
      return null;
132
    }
133
    let lastTextNode = endSpot.container;
134
    const startSpot = textSeeker.backwards(endSpot.container, endSpot.offset, (node, offset) => {
135
      lastTextNode = node;
136
      const idx = findChar(node.data, offset, isBracketOrSpace);
137
      return idx === -1 ? idx : idx + 1;
138
    }, root);
139
    const newRng = dom.createRng();
140
    if (!startSpot) {
141
      newRng.setStart(lastTextNode, 0);
142
    } else {
143
      newRng.setStart(startSpot.container, startSpot.offset);
144
    }
145
    newRng.setEnd(endSpot.container, endSpot.offset);
146
    const rngText = removeZwsp(newRng.toString());
147
    const matches = rngText.match(autoLinkPattern);
148
    if (matches) {
149
      let url = matches[0];
150
      if (startsWith(url, 'www.')) {
151
        const protocol = getDefaultLinkProtocol(editor);
152
        url = protocol + '://' + url;
153
      } else if (contains(url, '@') && !hasProtocol(url)) {
154
        url = 'mailto:' + url;
155
      }
156
      return {
157
        rng: newRng,
158
        url
159
      };
160
    } else {
161
      return null;
162
    }
163
  };
164
  const convertToLink = (editor, result) => {
165
    const {dom, selection} = editor;
166
    const {rng, url} = result;
167
    const bookmark = selection.getBookmark();
168
    selection.setRng(rng);
169
    const command = 'createlink';
170
    const args = {
171
      command,
172
      ui: false,
173
      value: url
174
    };
175
    const beforeExecEvent = editor.dispatch('BeforeExecCommand', args);
176
    if (!beforeExecEvent.isDefaultPrevented()) {
177
      editor.getDoc().execCommand(command, false, url);
178
      editor.dispatch('ExecCommand', args);
179
      const defaultLinkTarget = getDefaultLinkTarget(editor);
180
      if (isString(defaultLinkTarget)) {
181
        const anchor = selection.getNode();
182
        dom.setAttrib(anchor, 'target', defaultLinkTarget);
183
        if (defaultLinkTarget === '_blank' && !allowUnsafeLinkTarget(editor)) {
184
          dom.setAttrib(anchor, 'rel', 'noopener');
185
        }
186
      }
187
    }
188
    selection.moveToBookmark(bookmark);
189
    editor.nodeChanged();
190
  };
191
  const handleSpacebar = editor => {
192
    const result = parseCurrentLine(editor, -1);
193
    if (isNonNullable(result)) {
194
      convertToLink(editor, result);
195
    }
196
  };
197
  const handleBracket = handleSpacebar;
198
  const handleEnter = editor => {
199
    const result = parseCurrentLine(editor, 0);
200
    if (isNonNullable(result)) {
201
      convertToLink(editor, result);
202
    }
203
  };
204
  const setup = editor => {
205
    editor.on('keydown', e => {
206
      if (e.keyCode === 13 && !e.isDefaultPrevented()) {
207
        handleEnter(editor);
208
      }
209
    });
210
    editor.on('keyup', e => {
211
      if (e.keyCode === 32) {
212
        handleSpacebar(editor);
213
      } else if (e.keyCode === 48 && e.shiftKey || e.keyCode === 221) {
214
        handleBracket(editor);
215
      }
216
    });
217
  };
218
 
219
  var Plugin = () => {
220
    global$1.add('autolink', editor => {
221
      register(editor);
222
      setup(editor);
223
    });
224
  };
225
 
226
  Plugin();
227
 
228
})();