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
 
637 daniel-mar 12
    var global$1 = tinymce.util.Tools.resolve('tinymce.PluginManager');
597 daniel-mar 13
 
637 daniel-mar 14
    var checkRange = function (str, substr, start) {
15
      return substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
16
    };
17
    var contains = function (str, substr) {
18
      return str.indexOf(substr) !== -1;
19
    };
20
    var startsWith = function (str, prefix) {
21
      return checkRange(str, prefix, 0);
22
    };
597 daniel-mar 23
 
637 daniel-mar 24
    var global = tinymce.util.Tools.resolve('tinymce.Env');
25
 
26
    var link = function () {
1021 daniel-mar 27
      return /(?:[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;
637 daniel-mar 28
    };
29
 
30
    var defaultLinkPattern = new RegExp('^' + link().source + '$', 'i');
597 daniel-mar 31
    var getAutoLinkPattern = function (editor) {
637 daniel-mar 32
      return editor.getParam('autolink_pattern', defaultLinkPattern);
597 daniel-mar 33
    };
34
    var getDefaultLinkTarget = function (editor) {
35
      return editor.getParam('default_link_target', false);
36
    };
37
    var getDefaultLinkProtocol = function (editor) {
38
      return editor.getParam('link_default_protocol', 'http', 'string');
39
    };
40
 
679 daniel-mar 41
    var rangeEqualsBracketOrSpace = function (rangeString) {
42
      return /^[(\[{ \u00a0]$/.test(rangeString);
597 daniel-mar 43
    };
679 daniel-mar 44
    var isTextNode = function (node) {
45
      return node.nodeType === 3;
597 daniel-mar 46
    };
679 daniel-mar 47
    var isElement = function (node) {
48
      return node.nodeType === 1;
49
    };
50
    var handleBracket = function (editor) {
51
      return parseCurrentLine(editor, -1);
52
    };
597 daniel-mar 53
    var handleSpacebar = function (editor) {
679 daniel-mar 54
      return parseCurrentLine(editor, 0);
597 daniel-mar 55
    };
56
    var handleEnter = function (editor) {
679 daniel-mar 57
      return parseCurrentLine(editor, -1);
597 daniel-mar 58
    };
59
    var scopeIndex = function (container, index) {
60
      if (index < 0) {
61
        index = 0;
62
      }
679 daniel-mar 63
      if (isTextNode(container)) {
597 daniel-mar 64
        var len = container.data.length;
65
        if (index > len) {
66
          index = len;
67
        }
68
      }
69
      return index;
70
    };
71
    var setStart = function (rng, container, offset) {
679 daniel-mar 72
      if (!isElement(container) || container.hasChildNodes()) {
597 daniel-mar 73
        rng.setStart(container, scopeIndex(container, offset));
74
      } else {
75
        rng.setStartBefore(container);
76
      }
77
    };
78
    var setEnd = function (rng, container, offset) {
679 daniel-mar 79
      if (!isElement(container) || container.hasChildNodes()) {
597 daniel-mar 80
        rng.setEnd(container, scopeIndex(container, offset));
81
      } else {
82
        rng.setEndAfter(container);
83
      }
84
    };
637 daniel-mar 85
    var hasProtocol = function (url) {
86
      return /^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(url);
87
    };
88
    var isPunctuation = function (char) {
89
      return /[?!,.;:]/.test(char);
90
    };
679 daniel-mar 91
    var parseCurrentLine = function (editor, endOffset) {
597 daniel-mar 92
      var end, endContainer, bookmark, text, prev, len, rngText;
93
      var autoLinkPattern = getAutoLinkPattern(editor);
94
      var defaultLinkTarget = getDefaultLinkTarget(editor);
679 daniel-mar 95
      if (editor.dom.getParent(editor.selection.getNode(), 'a[href]') !== null) {
597 daniel-mar 96
        return;
97
      }
98
      var rng = editor.selection.getRng().cloneRange();
99
      if (rng.startOffset < 5) {
100
        prev = rng.endContainer.previousSibling;
101
        if (!prev) {
102
          if (!rng.endContainer.firstChild || !rng.endContainer.firstChild.nextSibling) {
103
            return;
104
          }
105
          prev = rng.endContainer.firstChild.nextSibling;
106
        }
107
        len = prev.length;
108
        setStart(rng, prev, len);
109
        setEnd(rng, prev, len);
110
        if (rng.endOffset < 5) {
111
          return;
112
        }
113
        end = rng.endOffset;
114
        endContainer = prev;
115
      } else {
116
        endContainer = rng.endContainer;
679 daniel-mar 117
        if (!isTextNode(endContainer) && endContainer.firstChild) {
118
          while (!isTextNode(endContainer) && endContainer.firstChild) {
597 daniel-mar 119
            endContainer = endContainer.firstChild;
120
          }
679 daniel-mar 121
          if (isTextNode(endContainer)) {
597 daniel-mar 122
            setStart(rng, endContainer, 0);
123
            setEnd(rng, endContainer, endContainer.nodeValue.length);
124
          }
125
        }
126
        if (rng.endOffset === 1) {
127
          end = 2;
128
        } else {
129
          end = rng.endOffset - 1 - endOffset;
130
        }
131
      }
132
      var start = end;
133
      do {
134
        setStart(rng, endContainer, end >= 2 ? end - 2 : 0);
135
        setEnd(rng, endContainer, end >= 1 ? end - 1 : 0);
136
        end -= 1;
137
        rngText = rng.toString();
679 daniel-mar 138
      } while (!rangeEqualsBracketOrSpace(rngText) && end - 2 >= 0);
139
      if (rangeEqualsBracketOrSpace(rng.toString())) {
597 daniel-mar 140
        setStart(rng, endContainer, end);
141
        setEnd(rng, endContainer, start);
142
        end += 1;
143
      } else if (rng.startOffset === 0) {
144
        setStart(rng, endContainer, 0);
145
        setEnd(rng, endContainer, start);
146
      } else {
147
        setStart(rng, endContainer, end);
148
        setEnd(rng, endContainer, start);
149
      }
150
      text = rng.toString();
637 daniel-mar 151
      if (isPunctuation(text.charAt(text.length - 1))) {
597 daniel-mar 152
        setEnd(rng, endContainer, start - 1);
153
      }
154
      text = rng.toString().trim();
155
      var matches = text.match(autoLinkPattern);
156
      var protocol = getDefaultLinkProtocol(editor);
157
      if (matches) {
637 daniel-mar 158
        var url = matches[0];
159
        if (startsWith(url, 'www.')) {
160
          url = protocol + '://' + url;
161
        } else if (contains(url, '@') && !hasProtocol(url)) {
162
          url = 'mailto:' + url;
597 daniel-mar 163
        }
164
        bookmark = editor.selection.getBookmark();
165
        editor.selection.setRng(rng);
637 daniel-mar 166
        editor.execCommand('createlink', false, url);
597 daniel-mar 167
        if (defaultLinkTarget !== false) {
168
          editor.dom.setAttrib(editor.selection.getNode(), 'target', defaultLinkTarget);
169
        }
170
        editor.selection.moveToBookmark(bookmark);
171
        editor.nodeChanged();
172
      }
173
    };
174
    var setup = function (editor) {
175
      var autoUrlDetectState;
176
      editor.on('keydown', function (e) {
177
        if (e.keyCode === 13) {
178
          return handleEnter(editor);
179
        }
180
      });
637 daniel-mar 181
      if (global.browser.isIE()) {
597 daniel-mar 182
        editor.on('focus', function () {
183
          if (!autoUrlDetectState) {
184
            autoUrlDetectState = true;
185
            try {
186
              editor.execCommand('AutoUrlDetect', false, true);
187
            } catch (ex) {
188
            }
189
          }
190
        });
191
        return;
192
      }
193
      editor.on('keypress', function (e) {
679 daniel-mar 194
        if (e.keyCode === 41 || e.keyCode === 93 || e.keyCode === 125) {
195
          return handleBracket(editor);
597 daniel-mar 196
        }
197
      });
198
      editor.on('keyup', function (e) {
199
        if (e.keyCode === 32) {
200
          return handleSpacebar(editor);
201
        }
202
      });
203
    };
204
 
205
    function Plugin () {
637 daniel-mar 206
      global$1.add('autolink', function (editor) {
597 daniel-mar 207
        setup(editor);
208
      });
209
    }
210
 
211
    Plugin();
212
 
213
}());