Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
13602 | obado | 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 | * |
||
7 | * Version: 5.0.0-1 (2019-02-04) |
||
8 | */ |
||
9 | (function () { |
||
10 | var link = (function () { |
||
11 | 'use strict'; |
||
12 | |||
13 | var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); |
||
14 | |||
15 | var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK'); |
||
16 | |||
17 | var assumeExternalTargets = function (editorSettings) { |
||
18 | return typeof editorSettings.link_assume_external_targets === 'boolean' ? editorSettings.link_assume_external_targets : false; |
||
19 | }; |
||
20 | var hasContextToolbar = function (editorSettings) { |
||
21 | return typeof editorSettings.link_context_toolbar === 'boolean' ? editorSettings.link_context_toolbar : false; |
||
22 | }; |
||
23 | var getLinkList = function (editorSettings) { |
||
24 | return editorSettings.link_list; |
||
25 | }; |
||
26 | var hasDefaultLinkTarget = function (editorSettings) { |
||
27 | return typeof editorSettings.default_link_target === 'string'; |
||
28 | }; |
||
29 | var useQuickLink = function (editorSettings) { |
||
30 | return editorSettings.link_quicklink === true; |
||
31 | }; |
||
32 | var getDefaultLinkTarget = function (editorSettings) { |
||
33 | return editorSettings.default_link_target; |
||
34 | }; |
||
35 | var getTargetList = function (editorSettings) { |
||
36 | return editorSettings.target_list; |
||
37 | }; |
||
38 | var setTargetList = function (editor, list) { |
||
39 | editor.settings.target_list = list; |
||
40 | }; |
||
41 | var shouldShowTargetList = function (editorSettings) { |
||
42 | return getTargetList(editorSettings) !== false; |
||
43 | }; |
||
44 | var getRelList = function (editorSettings) { |
||
45 | return editorSettings.rel_list; |
||
46 | }; |
||
47 | var hasRelList = function (editorSettings) { |
||
48 | return getRelList(editorSettings) !== undefined; |
||
49 | }; |
||
50 | var getLinkClassList = function (editorSettings) { |
||
51 | return editorSettings.link_class_list; |
||
52 | }; |
||
53 | var hasLinkClassList = function (editorSettings) { |
||
54 | return getLinkClassList(editorSettings) !== undefined; |
||
55 | }; |
||
56 | var shouldShowLinkTitle = function (editorSettings) { |
||
57 | return editorSettings.link_title !== false; |
||
58 | }; |
||
59 | var allowUnsafeLinkTarget = function (editorSettings) { |
||
60 | return typeof editorSettings.allow_unsafe_link_target === 'boolean' ? editorSettings.allow_unsafe_link_target : false; |
||
61 | }; |
||
62 | var Settings = { |
||
63 | assumeExternalTargets: assumeExternalTargets, |
||
64 | hasContextToolbar: hasContextToolbar, |
||
65 | getLinkList: getLinkList, |
||
66 | hasDefaultLinkTarget: hasDefaultLinkTarget, |
||
67 | getDefaultLinkTarget: getDefaultLinkTarget, |
||
68 | getTargetList: getTargetList, |
||
69 | setTargetList: setTargetList, |
||
70 | shouldShowTargetList: shouldShowTargetList, |
||
71 | getRelList: getRelList, |
||
72 | hasRelList: hasRelList, |
||
73 | getLinkClassList: getLinkClassList, |
||
74 | hasLinkClassList: hasLinkClassList, |
||
75 | shouldShowLinkTitle: shouldShowLinkTitle, |
||
76 | allowUnsafeLinkTarget: allowUnsafeLinkTarget, |
||
77 | useQuickLink: useQuickLink |
||
78 | }; |
||
79 | |||
80 | var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); |
||
81 | |||
82 | var global$3 = tinymce.util.Tools.resolve('tinymce.Env'); |
||
83 | |||
84 | var appendClickRemove = function (link, evt) { |
||
85 | document.body.appendChild(link); |
||
86 | link.dispatchEvent(evt); |
||
87 | document.body.removeChild(link); |
||
88 | }; |
||
89 | var open$$1 = function (url) { |
||
90 | if (!global$3.ie || global$3.ie > 10) { |
||
91 | var link = document.createElement('a'); |
||
92 | link.target = '_blank'; |
||
93 | link.href = url; |
||
94 | link.rel = 'noreferrer noopener'; |
||
95 | var evt = document.createEvent('MouseEvents'); |
||
96 | evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); |
||
97 | appendClickRemove(link, evt); |
||
98 | } else { |
||
99 | var win = window.open('', '_blank'); |
||
100 | if (win) { |
||
101 | win.opener = null; |
||
102 | var doc = win.document; |
||
103 | doc.open(); |
||
104 | doc.write('<meta http-equiv="refresh" content="0; url=' + global$2.DOM.encode(url) + '">'); |
||
105 | doc.close(); |
||
106 | } |
||
107 | } |
||
108 | }; |
||
109 | var OpenUrl = { open: open$$1 }; |
||
110 | |||
111 | var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); |
||
112 | |||
113 | var getHref = function (elm) { |
||
114 | var href = elm.getAttribute('data-mce-href'); |
||
115 | return href ? href : elm.getAttribute('href'); |
||
116 | }; |
||
117 | var toggleTargetRules = function (rel, isUnsafe) { |
||
118 | var rules = ['noopener']; |
||
119 | var newRel = rel ? rel.split(/\s+/) : []; |
||
120 | var toString = function (rel) { |
||
121 | return global$4.trim(rel.sort().join(' ')); |
||
122 | }; |
||
123 | var addTargetRules = function (rel) { |
||
124 | rel = removeTargetRules(rel); |
||
125 | return rel.length ? rel.concat(rules) : rules; |
||
126 | }; |
||
127 | var removeTargetRules = function (rel) { |
||
128 | return rel.filter(function (val) { |
||
129 | return global$4.inArray(rules, val) === -1; |
||
130 | }); |
||
131 | }; |
||
132 | newRel = isUnsafe ? addTargetRules(newRel) : removeTargetRules(newRel); |
||
133 | return newRel.length ? toString(newRel) : ''; |
||
134 | }; |
||
135 | var trimCaretContainers = function (text) { |
||
136 | return text.replace(/\uFEFF/g, ''); |
||
137 | }; |
||
138 | var getAnchorElement = function (editor, selectedElm) { |
||
139 | selectedElm = selectedElm || editor.selection.getNode(); |
||
140 | if (isImageFigure(selectedElm)) { |
||
141 | return editor.dom.select('a[href]', selectedElm)[0]; |
||
142 | } else { |
||
143 | return editor.dom.getParent(selectedElm, 'a[href]'); |
||
144 | } |
||
145 | }; |
||
146 | var getAnchorText = function (selection, anchorElm) { |
||
147 | var text = anchorElm ? anchorElm.innerText || anchorElm.textContent : selection.getContent({ format: 'text' }); |
||
148 | return trimCaretContainers(text); |
||
149 | }; |
||
150 | var isLink = function (elm) { |
||
151 | return elm && elm.nodeName === 'A' && elm.href; |
||
152 | }; |
||
153 | var hasLinks = function (elements) { |
||
154 | return global$4.grep(elements, isLink).length > 0; |
||
155 | }; |
||
156 | var isOnlyTextSelected = function (html) { |
||
157 | if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') === -1)) { |
||
158 | return false; |
||
159 | } |
||
160 | return true; |
||
161 | }; |
||
162 | var isImageFigure = function (node) { |
||
163 | return node && node.nodeName === 'FIGURE' && /\bimage\b/i.test(node.className); |
||
164 | }; |
||
165 | var link = function (editor, attachState) { |
||
166 | return function (data) { |
||
167 | editor.undoManager.transact(function () { |
||
168 | var selectedElm = editor.selection.getNode(); |
||
169 | var anchorElm = getAnchorElement(editor, selectedElm); |
||
170 | var linkAttrs = { |
||
171 | href: data.href, |
||
172 | target: data.target ? data.target : null, |
||
173 | rel: data.rel ? data.rel : null, |
||
174 | class: data.class ? data.class : null, |
||
175 | title: data.title ? data.title : null |
||
176 | }; |
||
177 | if (!Settings.hasRelList(editor.settings) && Settings.allowUnsafeLinkTarget(editor.settings) === false) { |
||
178 | var newRel = toggleTargetRules(linkAttrs.rel, linkAttrs.target === '_blank'); |
||
179 | linkAttrs.rel = newRel ? newRel : null; |
||
180 | } |
||
181 | if (data.href === attachState.href) { |
||
182 | attachState.attach(); |
||
183 | attachState = {}; |
||
184 | } |
||
185 | if (anchorElm) { |
||
186 | editor.focus(); |
||
187 | if (data.hasOwnProperty('text')) { |
||
188 | if ('innerText' in anchorElm) { |
||
189 | anchorElm.innerText = data.text; |
||
190 | } else { |
||
191 | anchorElm.textContent = data.text; |
||
192 | } |
||
193 | } |
||
194 | editor.dom.setAttribs(anchorElm, linkAttrs); |
||
195 | editor.selection.select(anchorElm); |
||
196 | editor.undoManager.add(); |
||
197 | } else { |
||
198 | if (isImageFigure(selectedElm)) { |
||
199 | linkImageFigure(editor, selectedElm, linkAttrs); |
||
200 | } else if (data.hasOwnProperty('text')) { |
||
201 | editor.insertContent(editor.dom.createHTML('a', linkAttrs, editor.dom.encode(data.text))); |
||
202 | } else { |
||
203 | editor.execCommand('mceInsertLink', false, linkAttrs); |
||
204 | } |
||
205 | } |
||
206 | }); |
||
207 | }; |
||
208 | }; |
||
209 | var unlink = function (editor) { |
||
210 | return function () { |
||
211 | editor.undoManager.transact(function () { |
||
212 | var node = editor.selection.getNode(); |
||
213 | if (isImageFigure(node)) { |
||
214 | unlinkImageFigure(editor, node); |
||
215 | } else { |
||
216 | editor.execCommand('unlink'); |
||
217 | } |
||
218 | }); |
||
219 | }; |
||
220 | }; |
||
221 | var unlinkImageFigure = function (editor, fig) { |
||
222 | var a, img; |
||
223 | img = editor.dom.select('img', fig)[0]; |
||
224 | if (img) { |
||
225 | a = editor.dom.getParents(img, 'a[href]', fig)[0]; |
||
226 | if (a) { |
||
227 | a.parentNode.insertBefore(img, a); |
||
228 | editor.dom.remove(a); |
||
229 | } |
||
230 | } |
||
231 | }; |
||
232 | var linkImageFigure = function (editor, fig, attrs) { |
||
233 | var a, img; |
||
234 | img = editor.dom.select('img', fig)[0]; |
||
235 | if (img) { |
||
236 | a = editor.dom.create('a', attrs); |
||
237 | img.parentNode.insertBefore(a, img); |
||
238 | a.appendChild(img); |
||
239 | } |
||
240 | }; |
||
241 | var Utils = { |
||
242 | link: link, |
||
243 | unlink: unlink, |
||
244 | isLink: isLink, |
||
245 | hasLinks: hasLinks, |
||
246 | getHref: getHref, |
||
247 | isOnlyTextSelected: isOnlyTextSelected, |
||
248 | getAnchorElement: getAnchorElement, |
||
249 | getAnchorText: getAnchorText, |
||
250 | toggleTargetRules: toggleTargetRules |
||
251 | }; |
||
252 | |||
253 | var noop = function () { |
||
254 | var args = []; |
||
255 | for (var _i = 0; _i < arguments.length; _i++) { |
||
256 | args[_i] = arguments[_i]; |
||
257 | } |
||
258 | }; |
||
259 | var constant = function (value) { |
||
260 | return function () { |
||
261 | return value; |
||
262 | }; |
||
263 | }; |
||
264 | var never = constant(false); |
||
265 | var always = constant(true); |
||
266 | |||
267 | var never$1 = never; |
||
268 | var always$1 = always; |
||
269 | var none = function () { |
||
270 | return NONE; |
||
271 | }; |
||
272 | var NONE = function () { |
||
273 | var eq = function (o) { |
||
274 | return o.isNone(); |
||
275 | }; |
||
276 | var call$$1 = function (thunk) { |
||
277 | return thunk(); |
||
278 | }; |
||
279 | var id = function (n) { |
||
280 | return n; |
||
281 | }; |
||
282 | var noop$$1 = function () { |
||
283 | }; |
||
284 | var nul = function () { |
||
285 | return null; |
||
286 | }; |
||
287 | var undef = function () { |
||
288 | return undefined; |
||
289 | }; |
||
290 | var me = { |
||
291 | fold: function (n, s) { |
||
292 | return n(); |
||
293 | }, |
||
294 | is: never$1, |
||
295 | isSome: never$1, |
||
296 | isNone: always$1, |
||
297 | getOr: id, |
||
298 | getOrThunk: call$$1, |
||
299 | getOrDie: function (msg) { |
||
300 | throw new Error(msg || 'error: getOrDie called on none.'); |
||
301 | }, |
||
302 | getOrNull: nul, |
||
303 | getOrUndefined: undef, |
||
304 | or: id, |
||
305 | orThunk: call$$1, |
||
306 | map: none, |
||
307 | ap: none, |
||
308 | each: noop$$1, |
||
309 | bind: none, |
||
310 | flatten: none, |
||
311 | exists: never$1, |
||
312 | forall: always$1, |
||
313 | filter: none, |
||
314 | equals: eq, |
||
315 | equals_: eq, |
||
316 | toArray: function () { |
||
317 | return []; |
||
318 | }, |
||
319 | toString: constant('none()') |
||
320 | }; |
||
321 | if (Object.freeze) |
||
322 | Object.freeze(me); |
||
323 | return me; |
||
324 | }(); |
||
325 | var some = function (a) { |
||
326 | var constant_a = function () { |
||
327 | return a; |
||
328 | }; |
||
329 | var self = function () { |
||
330 | return me; |
||
331 | }; |
||
332 | var map = function (f) { |
||
333 | return some(f(a)); |
||
334 | }; |
||
335 | var bind = function (f) { |
||
336 | return f(a); |
||
337 | }; |
||
338 | var me = { |
||
339 | fold: function (n, s) { |
||
340 | return s(a); |
||
341 | }, |
||
342 | is: function (v) { |
||
343 | return a === v; |
||
344 | }, |
||
345 | isSome: always$1, |
||
346 | isNone: never$1, |
||
347 | getOr: constant_a, |
||
348 | getOrThunk: constant_a, |
||
349 | getOrDie: constant_a, |
||
350 | getOrNull: constant_a, |
||
351 | getOrUndefined: constant_a, |
||
352 | or: self, |
||
353 | orThunk: self, |
||
354 | map: map, |
||
355 | ap: function (optfab) { |
||
356 | return optfab.fold(none, function (fab) { |
||
357 | return some(fab(a)); |
||
358 | }); |
||
359 | }, |
||
360 | each: function (f) { |
||
361 | f(a); |
||
362 | }, |
||
363 | bind: bind, |
||
364 | flatten: constant_a, |
||
365 | exists: bind, |
||
366 | forall: bind, |
||
367 | filter: function (f) { |
||
368 | return f(a) ? me : NONE; |
||
369 | }, |
||
370 | equals: function (o) { |
||
371 | return o.is(a); |
||
372 | }, |
||
373 | equals_: function (o, elementEq) { |
||
374 | return o.fold(never$1, function (b) { |
||
375 | return elementEq(a, b); |
||
376 | }); |
||
377 | }, |
||
378 | toArray: function () { |
||
379 | return [a]; |
||
380 | }, |
||
381 | toString: function () { |
||
382 | return 'some(' + a + ')'; |
||
383 | } |
||
384 | }; |
||
385 | return me; |
||
386 | }; |
||
387 | var from = function (value) { |
||
388 | return value === null || value === undefined ? NONE : some(value); |
||
389 | }; |
||
390 | var Option = { |
||
391 | some: some, |
||
392 | none: none, |
||
393 | from: from |
||
394 | }; |
||
395 | |||
396 | var typeOf = function (x) { |
||
397 | if (x === null) |
||
398 | return 'null'; |
||
399 | var t = typeof x; |
||
400 | if (t === 'object' && Array.prototype.isPrototypeOf(x)) |
||
401 | return 'array'; |
||
402 | if (t === 'object' && String.prototype.isPrototypeOf(x)) |
||
403 | return 'string'; |
||
404 | return t; |
||
405 | }; |
||
406 | var isType = function (type) { |
||
407 | return function (value) { |
||
408 | return typeOf(value) === type; |
||
409 | }; |
||
410 | }; |
||
411 | var isString = isType('string'); |
||
412 | var isFunction = isType('function'); |
||
413 | |||
414 | var rawIndexOf = function () { |
||
415 | var pIndexOf = Array.prototype.indexOf; |
||
416 | var fastIndex = function (xs, x) { |
||
417 | return pIndexOf.call(xs, x); |
||
418 | }; |
||
419 | var slowIndex = function (xs, x) { |
||
420 | return slowIndexOf(xs, x); |
||
421 | }; |
||
422 | return pIndexOf === undefined ? slowIndex : fastIndex; |
||
423 | }(); |
||
424 | var contains = function (xs, x) { |
||
425 | return rawIndexOf(xs, x) > -1; |
||
426 | }; |
||
427 | var map = function (xs, f) { |
||
428 | var len = xs.length; |
||
429 | var r = new Array(len); |
||
430 | for (var i = 0; i < len; i++) { |
||
431 | var x = xs[i]; |
||
432 | r[i] = f(x, i, xs); |
||
433 | } |
||
434 | return r; |
||
435 | }; |
||
436 | var each = function (xs, f) { |
||
437 | for (var i = 0, len = xs.length; i < len; i++) { |
||
438 | var x = xs[i]; |
||
439 | f(x, i, xs); |
||
440 | } |
||
441 | }; |
||
442 | var slowIndexOf = function (xs, x) { |
||
443 | for (var i = 0, len = xs.length; i < len; ++i) { |
||
444 | if (xs[i] === x) { |
||
445 | return i; |
||
446 | } |
||
447 | } |
||
448 | return -1; |
||
449 | }; |
||
450 | var push = Array.prototype.push; |
||
451 | var flatten = function (xs) { |
||
452 | var r = []; |
||
453 | for (var i = 0, len = xs.length; i < len; ++i) { |
||
454 | if (!Array.prototype.isPrototypeOf(xs[i])) |
||
455 | throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); |
||
456 | push.apply(r, xs[i]); |
||
457 | } |
||
458 | return r; |
||
459 | }; |
||
460 | var bind = function (xs, f) { |
||
461 | var output = map(xs, f); |
||
462 | return flatten(output); |
||
463 | }; |
||
464 | var slice = Array.prototype.slice; |
||
465 | var from$1 = isFunction(Array.from) ? Array.from : function (x) { |
||
466 | return slice.call(x); |
||
467 | }; |
||
468 | |||
469 | var cat = function (arr) { |
||
470 | var r = []; |
||
471 | var push = function (x) { |
||
472 | r.push(x); |
||
473 | }; |
||
474 | for (var i = 0; i < arr.length; i++) { |
||
475 | arr[i].each(push); |
||
476 | } |
||
477 | return r; |
||
478 | }; |
||
479 | var findMap = function (arr, f) { |
||
480 | for (var i = 0; i < arr.length; i++) { |
||
481 | var r = f(arr[i], i); |
||
482 | if (r.isSome()) { |
||
483 | return r; |
||
484 | } |
||
485 | } |
||
486 | return Option.none(); |
||
487 | }; |
||
488 | |||
489 | var getValue = function (item) { |
||
490 | return isString(item.value) ? item.value : ''; |
||
491 | }; |
||
492 | var sanitizeList = function (list, extractValue) { |
||
493 | var out = []; |
||
494 | global$4.each(list, function (item) { |
||
495 | var text = isString(item.text) ? item.text : isString(item.title) ? item.title : ''; |
||
496 | if (item.menu !== undefined) ; else { |
||
497 | var value = extractValue(item); |
||
498 | out.push({ |
||
499 | text: text, |
||
500 | value: value |
||
501 | }); |
||
502 | } |
||
503 | }); |
||
504 | return out; |
||
505 | }; |
||
506 | var sanitizeWith = function (extracter) { |
||
507 | if (extracter === void 0) { |
||
508 | extracter = getValue; |
||
509 | } |
||
510 | return function (list) { |
||
511 | return Option.from(list).map(function (list) { |
||
512 | return sanitizeList(list, extracter); |
||
513 | }); |
||
514 | }; |
||
515 | }; |
||
516 | var sanitize = function (list) { |
||
517 | return sanitizeWith(getValue)(list); |
||
518 | }; |
||
519 | var createUi = function (name, label) { |
||
520 | return function (items) { |
||
521 | return { |
||
522 | name: name, |
||
523 | type: 'selectbox', |
||
524 | label: label, |
||
525 | items: items |
||
526 | }; |
||
527 | }; |
||
528 | }; |
||
529 | var ListOptions = { |
||
530 | sanitize: sanitize, |
||
531 | sanitizeWith: sanitizeWith, |
||
532 | createUi: createUi, |
||
533 | getValue: getValue |
||
534 | }; |
||
535 | |||
536 | var Cell = function (initial) { |
||
537 | var value = initial; |
||
538 | var get = function () { |
||
539 | return value; |
||
540 | }; |
||
541 | var set = function (v) { |
||
542 | value = v; |
||
543 | }; |
||
544 | var clone = function () { |
||
545 | return Cell(get()); |
||
546 | }; |
||
547 | return { |
||
548 | get: get, |
||
549 | set: set, |
||
550 | clone: clone |
||
551 | }; |
||
552 | }; |
||
553 | |||
554 | var findTextByValue = function (value, catalog) { |
||
555 | return findMap(catalog, function (item) { |
||
556 | return Option.some(item).filter(function (i) { |
||
557 | return i.value === value; |
||
558 | }); |
||
559 | }); |
||
560 | }; |
||
561 | var getDelta = function (persistentText, fieldName, catalog, data) { |
||
562 | var value = data[fieldName]; |
||
563 | var hasPersistentText = persistentText.length > 0; |
||
564 | return value !== undefined ? findTextByValue(value, catalog).map(function (i) { |
||
565 | return { |
||
566 | url: { |
||
567 | value: i.value, |
||
568 | meta: { |
||
569 | text: hasPersistentText ? persistentText : i.text, |
||
570 | attach: noop |
||
571 | } |
||
572 | }, |
||
573 | text: hasPersistentText ? persistentText : i.text |
||
574 | }; |
||
575 | }) : Option.none(); |
||
576 | }; |
||
577 | var findCatalog = function (settings, fieldName) { |
||
578 | if (fieldName === 'link') { |
||
579 | return settings.catalogs.link; |
||
580 | } else if (fieldName === 'anchor') { |
||
581 | return settings.catalogs.anchor; |
||
582 | } else { |
||
583 | return Option.none(); |
||
584 | } |
||
585 | }; |
||
586 | var init = function (initialData, linkSettings) { |
||
587 | var persistentText = Cell(initialData.text); |
||
588 | var onUrlChange = function (data) { |
||
589 | if (persistentText.get().length <= 0) { |
||
590 | var urlText = data.url.meta.text !== undefined ? data.url.meta.text : data.url.value; |
||
591 | return Option.some({ text: urlText }); |
||
592 | } else { |
||
593 | return Option.none(); |
||
594 | } |
||
595 | }; |
||
596 | var onCatalogChange = function (data, change) { |
||
597 | var catalog = findCatalog(linkSettings, change.name).getOr([]); |
||
598 | return getDelta(persistentText.get(), change.name, catalog, data); |
||
599 | }; |
||
600 | var onChange = function (getData, change) { |
||
601 | if (change.name === 'url') { |
||
602 | return onUrlChange(getData()); |
||
603 | } else if (contains([ |
||
604 | 'anchor', |
||
605 | 'link' |
||
606 | ], change.name)) { |
||
607 | return onCatalogChange(getData(), change); |
||
608 | } else if (change.name === 'text') { |
||
609 | persistentText.set(getData().text); |
||
610 | return Option.none(); |
||
611 | } else { |
||
612 | return Option.none(); |
||
613 | } |
||
614 | }; |
||
615 | return { onChange: onChange }; |
||
616 | }; |
||
617 | var DialogChanges = { |
||
618 | init: init, |
||
619 | getDelta: getDelta |
||
620 | }; |
||
621 | |||
622 | var __assign = function () { |
||
623 | __assign = Object.assign || function __assign(t) { |
||
624 | for (var s, i = 1, n = arguments.length; i < n; i++) { |
||
625 | s = arguments[i]; |
||
626 | for (var p in s) |
||
627 | if (Object.prototype.hasOwnProperty.call(s, p)) |
||
628 | t[p] = s[p]; |
||
629 | } |
||
630 | return t; |
||
631 | }; |
||
632 | return __assign.apply(this, arguments); |
||
633 | }; |
||
634 | |||
635 | var nu = function (baseFn) { |
||
636 | var data = Option.none(); |
||
637 | var callbacks = []; |
||
638 | var map$$1 = function (f) { |
||
639 | return nu(function (nCallback) { |
||
640 | get(function (data) { |
||
641 | nCallback(f(data)); |
||
642 | }); |
||
643 | }); |
||
644 | }; |
||
645 | var get = function (nCallback) { |
||
646 | if (isReady()) |
||
647 | call(nCallback); |
||
648 | else |
||
649 | callbacks.push(nCallback); |
||
650 | }; |
||
651 | var set = function (x) { |
||
652 | data = Option.some(x); |
||
653 | run(callbacks); |
||
654 | callbacks = []; |
||
655 | }; |
||
656 | var isReady = function () { |
||
657 | return data.isSome(); |
||
658 | }; |
||
659 | var run = function (cbs) { |
||
660 | each(cbs, call); |
||
661 | }; |
||
662 | var call = function (cb) { |
||
663 | data.each(function (x) { |
||
664 | setTimeout(function () { |
||
665 | cb(x); |
||
666 | }, 0); |
||
667 | }); |
||
668 | }; |
||
669 | baseFn(set); |
||
670 | return { |
||
671 | get: get, |
||
672 | map: map$$1, |
||
673 | isReady: isReady |
||
674 | }; |
||
675 | }; |
||
676 | var pure$1 = function (a) { |
||
677 | return nu(function (callback) { |
||
678 | callback(a); |
||
679 | }); |
||
680 | }; |
||
681 | var LazyValue = { |
||
682 | nu: nu, |
||
683 | pure: pure$1 |
||
684 | }; |
||
685 | |||
686 | var bounce = function (f) { |
||
687 | return function () { |
||
688 | var args = []; |
||
689 | for (var _i = 0; _i < arguments.length; _i++) { |
||
690 | args[_i] = arguments[_i]; |
||
691 | } |
||
692 | var me = this; |
||
693 | setTimeout(function () { |
||
694 | f.apply(me, args); |
||
695 | }, 0); |
||
696 | }; |
||
697 | }; |
||
698 | |||
699 | var nu$1 = function (baseFn) { |
||
700 | var get = function (callback) { |
||
701 | baseFn(bounce(callback)); |
||
702 | }; |
||
703 | var map = function (fab) { |
||
704 | return nu$1(function (callback) { |
||
705 | get(function (a) { |
||
706 | var value = fab(a); |
||
707 | callback(value); |
||
708 | }); |
||
709 | }); |
||
710 | }; |
||
711 | var bind = function (aFutureB) { |
||
712 | return nu$1(function (callback) { |
||
713 | get(function (a) { |
||
714 | aFutureB(a).get(callback); |
||
715 | }); |
||
716 | }); |
||
717 | }; |
||
718 | var anonBind = function (futureB) { |
||
719 | return nu$1(function (callback) { |
||
720 | get(function (a) { |
||
721 | futureB.get(callback); |
||
722 | }); |
||
723 | }); |
||
724 | }; |
||
725 | var toLazy = function () { |
||
726 | return LazyValue.nu(get); |
||
727 | }; |
||
728 | var toCached = function () { |
||
729 | var cache = null; |
||
730 | return nu$1(function (callback) { |
||
731 | if (cache === null) { |
||
732 | cache = toLazy(); |
||
733 | } |
||
734 | cache.get(callback); |
||
735 | }); |
||
736 | }; |
||
737 | return { |
||
738 | map: map, |
||
739 | bind: bind, |
||
740 | anonBind: anonBind, |
||
741 | toLazy: toLazy, |
||
742 | toCached: toCached, |
||
743 | get: get |
||
744 | }; |
||
745 | }; |
||
746 | var pure$2 = function (a) { |
||
747 | return nu$1(function (callback) { |
||
748 | callback(a); |
||
749 | }); |
||
750 | }; |
||
751 | var Future = { |
||
752 | nu: nu$1, |
||
753 | pure: pure$2 |
||
754 | }; |
||
755 | |||
756 | var global$5 = tinymce.util.Tools.resolve('tinymce.util.Delay'); |
||
757 | |||
758 | var delayedConfirm = function (editor, message, callback) { |
||
759 | var rng = editor.selection.getRng(); |
||
760 | global$5.setEditorTimeout(editor, function () { |
||
761 | editor.windowManager.confirm(message, function (state) { |
||
762 | editor.selection.setRng(rng); |
||
763 | callback(state); |
||
764 | }); |
||
765 | }); |
||
766 | }; |
||
767 | var tryEmailTransform = function (data) { |
||
768 | var url = data.href; |
||
769 | var suggestMailTo = url.indexOf('@') > 0 && url.indexOf('//') === -1 && url.indexOf('mailto:') === -1; |
||
770 | return suggestMailTo ? Option.some({ |
||
771 | message: 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?', |
||
772 | preprocess: function (oldData) { |
||
773 | return __assign({}, oldData, { href: 'mailto:' + url }); |
||
774 | } |
||
775 | }) : Option.none(); |
||
776 | }; |
||
777 | var tryProtocolTransform = function (assumeExternalTargets) { |
||
778 | return function (data) { |
||
779 | var url = data.href; |
||
780 | var suggestProtocol = assumeExternalTargets === true && !/^\w+:/i.test(url) || assumeExternalTargets === false && /^\s*www[\.|\d\.]/i.test(url); |
||
781 | return suggestProtocol ? Option.some({ |
||
782 | message: 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', |
||
783 | preprocess: function (oldData) { |
||
784 | return __assign({}, oldData, { href: 'http://' + url }); |
||
785 | } |
||
786 | }) : Option.none(); |
||
787 | }; |
||
788 | }; |
||
789 | var preprocess = function (editor, assumeExternalTargets, data) { |
||
790 | return findMap([ |
||
791 | tryEmailTransform, |
||
792 | tryProtocolTransform(assumeExternalTargets) |
||
793 | ], function (f) { |
||
794 | return f(data); |
||
795 | }).fold(function () { |
||
796 | return Future.pure(data); |
||
797 | }, function (transform) { |
||
798 | return Future.nu(function (callback) { |
||
799 | delayedConfirm(editor, transform.message, function (state) { |
||
800 | console.log('state', state); |
||
801 | callback(state ? transform.preprocess(data) : data); |
||
802 | }); |
||
803 | }); |
||
804 | }); |
||
805 | }; |
||
806 | var DialogConfirms = { preprocess: preprocess }; |
||
807 | |||
808 | var getAnchors = function (editor) { |
||
809 | var anchorNodes = editor.dom.select('a:not([href])'); |
||
810 | var anchors = bind(anchorNodes, function (anchor) { |
||
811 | var id = anchor.name || anchor.id; |
||
812 | return id ? [{ |
||
813 | text: id, |
||
814 | value: '#' + id |
||
815 | }] : []; |
||
816 | }); |
||
817 | return anchors.length > 0 ? Option.some([{ |
||
818 | text: 'None', |
||
819 | value: '' |
||
820 | }].concat(anchors)) : Option.none(); |
||
821 | }; |
||
822 | var AnchorListOptions = { getAnchors: getAnchors }; |
||
823 | |||
824 | var getClasses = function (editor) { |
||
825 | if (Settings.hasLinkClassList(editor.settings)) { |
||
826 | var list = Settings.getLinkClassList(editor.settings); |
||
827 | return ListOptions.sanitize(list); |
||
828 | } |
||
829 | return Option.none(); |
||
830 | }; |
||
831 | var ClassListOptions = { getClasses: getClasses }; |
||
832 | |||
833 | var global$6 = tinymce.util.Tools.resolve('tinymce.util.XHR'); |
||
834 | |||
835 | var parseJson = function (text) { |
||
836 | try { |
||
837 | return Option.some(JSON.parse(text)); |
||
838 | } catch (err) { |
||
839 | return Option.none(); |
||
840 | } |
||
841 | }; |
||
842 | var getLinks = function (editor) { |
||
843 | var extractor = function (item) { |
||
844 | return editor.convertURL(item.value || item.url, 'href'); |
||
845 | }; |
||
846 | var linkList = Settings.getLinkList(editor.settings); |
||
847 | return Future.nu(function (callback) { |
||
848 | if (typeof linkList === 'string') { |
||
849 | global$6.send({ |
||
850 | url: linkList, |
||
851 | success: function (text) { |
||
852 | return callback(parseJson(text)); |
||
853 | }, |
||
854 | error: function (_) { |
||
855 | return callback(Option.none()); |
||
856 | } |
||
857 | }); |
||
858 | } else if (typeof linkList === 'function') { |
||
859 | linkList(function (output) { |
||
860 | return callback(Option.some(output)); |
||
861 | }); |
||
862 | } else { |
||
863 | callback(Option.from(linkList)); |
||
864 | } |
||
865 | }).map(function (opt) { |
||
866 | return opt.bind(ListOptions.sanitizeWith(extractor)); |
||
867 | }); |
||
868 | }; |
||
869 | var LinkListOptions = { getLinks: getLinks }; |
||
870 | |||
871 | var getRels = function (editor, initialTarget) { |
||
872 | if (Settings.hasRelList(editor.settings)) { |
||
873 | var list = Settings.getRelList(editor.settings); |
||
874 | var isTargetBlank_1 = initialTarget.is('_blank'); |
||
875 | var enforceSafe = Settings.allowUnsafeLinkTarget(editor.settings) === false; |
||
876 | var safeRelExtractor = function (item) { |
||
877 | return Utils.toggleTargetRules(ListOptions.getValue(item), isTargetBlank_1); |
||
878 | }; |
||
879 | var sanitizer = enforceSafe ? ListOptions.sanitizeWith(safeRelExtractor) : ListOptions.sanitize; |
||
880 | return sanitizer(list); |
||
881 | } |
||
882 | return Option.none(); |
||
883 | }; |
||
884 | var RelOptions = { getRels: getRels }; |
||
885 | |||
886 | var fallbacks = [ |
||
887 | { |
||
888 | text: 'Current window', |
||
889 | value: '' |
||
890 | }, |
||
891 | { |
||
892 | text: 'New window', |
||
893 | value: '_blank' |
||
894 | } |
||
895 | ]; |
||
896 | var getTargets = function (editor) { |
||
897 | if (Settings.shouldShowTargetList(editor.settings)) { |
||
898 | var list = Settings.getTargetList(editor.settings); |
||
899 | return ListOptions.sanitize(list).orThunk(function () { |
||
900 | return Option.some(fallbacks); |
||
901 | }); |
||
902 | } |
||
903 | return Option.none(); |
||
904 | }; |
||
905 | var TargetOptions = { getTargets: getTargets }; |
||
906 | |||
907 | var nonEmptyAttr = function (dom, elem, name) { |
||
908 | var val = dom.getAttrib(elem, name); |
||
909 | return val !== null && val.length > 0 ? Option.some(val) : Option.none(); |
||
910 | }; |
||
911 | var extractFromAnchor = function (editor, settings, anchor, selection) { |
||
912 | var dom = editor.dom; |
||
913 | var onlyText = Utils.isOnlyTextSelected(selection.getContent()); |
||
914 | var text = onlyText ? Option.some(Utils.getAnchorText(selection, anchor)) : Option.none(); |
||
915 | var url = anchor ? Option.some(dom.getAttrib(anchor, 'href')) : Option.none(); |
||
916 | var defaultTarget = Settings.hasDefaultLinkTarget(settings) ? Option.some(Settings.getDefaultLinkTarget(settings)) : Option.none(); |
||
917 | var target = anchor ? Option.from(dom.getAttrib(anchor, 'target')) : defaultTarget; |
||
918 | var rel = nonEmptyAttr(dom, anchor, 'rel'); |
||
919 | var linkClass = nonEmptyAttr(dom, anchor, 'class'); |
||
920 | var title = nonEmptyAttr(dom, anchor, 'title'); |
||
921 | return { |
||
922 | url: url, |
||
923 | text: text, |
||
924 | title: title, |
||
925 | target: target, |
||
926 | rel: rel, |
||
927 | linkClass: linkClass |
||
928 | }; |
||
929 | }; |
||
930 | var collect = function (editor, settings, linkNode) { |
||
931 | return LinkListOptions.getLinks(editor).map(function (links) { |
||
932 | var anchor = extractFromAnchor(editor, settings, linkNode, editor.selection); |
||
933 | return { |
||
934 | anchor: anchor, |
||
935 | catalogs: { |
||
936 | targets: TargetOptions.getTargets(editor), |
||
937 | rels: RelOptions.getRels(editor, anchor.target), |
||
938 | classes: ClassListOptions.getClasses(editor), |
||
939 | anchor: AnchorListOptions.getAnchors(editor), |
||
940 | link: links |
||
941 | }, |
||
942 | optNode: Option.from(linkNode), |
||
943 | flags: { titleEnabled: Settings.shouldShowLinkTitle(settings) } |
||
944 | }; |
||
945 | }); |
||
946 | }; |
||
947 | var DialogInfo = { collect: collect }; |
||
948 | |||
949 | var handleSubmit = function (editor, info, text, assumeExternalTargets) { |
||
950 | return function (api) { |
||
951 | var data = api.getData(); |
||
952 | var resultData = { |
||
953 | href: data.url.value, |
||
954 | text: Option.from(data.text).or(text).getOr(undefined), |
||
955 | target: Option.from(data.target).or(info.anchor.target).getOr(undefined), |
||
956 | rel: Option.from(data.rel).or(info.anchor.rel).getOr(undefined), |
||
957 | class: Option.from(data.classz).or(info.anchor.linkClass).getOr(undefined), |
||
958 | title: Option.from(data.title).or(info.anchor.title).getOr(undefined) |
||
959 | }; |
||
960 | var attachState = { |
||
961 | href: data.url.value, |
||
962 | attach: data.url.meta !== undefined && data.url.meta.attach ? data.url.meta.attach : function () { |
||
963 | } |
||
964 | }; |
||
965 | var insertLink = Utils.link(editor, attachState); |
||
966 | var removeLink = Utils.unlink(editor); |
||
967 | var url = data.url.value; |
||
968 | if (!url) { |
||
969 | removeLink(); |
||
970 | api.close(); |
||
971 | return; |
||
972 | } |
||
973 | if (text.is(data.text) || info.optNode.isNone() && !data.text) { |
||
974 | delete resultData.text; |
||
975 | } |
||
976 | DialogConfirms.preprocess(editor, assumeExternalTargets, resultData).get(function (pData) { |
||
977 | insertLink(pData); |
||
978 | }); |
||
979 | api.close(); |
||
980 | }; |
||
981 | }; |
||
982 | var collectData = function (editor) { |
||
983 | var settings = editor.settings; |
||
984 | var anchorNode = Utils.getAnchorElement(editor); |
||
985 | return DialogInfo.collect(editor, settings, anchorNode); |
||
986 | }; |
||
987 | var getInitialData = function (info) { |
||
988 | return { |
||
989 | url: { |
||
990 | value: info.anchor.url.getOr(''), |
||
991 | meta: { |
||
992 | attach: function () { |
||
993 | }, |
||
994 | text: info.anchor.url.fold(function () { |
||
995 | return ''; |
||
996 | }, function () { |
||
997 | return info.anchor.text.getOr(''); |
||
998 | }), |
||
999 | original: { value: info.anchor.url.getOr('') } |
||
1000 | } |
||
1001 | }, |
||
1002 | text: info.anchor.text.getOr(''), |
||
1003 | title: info.anchor.title.getOr(''), |
||
1004 | anchor: info.anchor.url.getOr(''), |
||
1005 | link: info.anchor.url.getOr(''), |
||
1006 | rel: info.anchor.rel.getOr(''), |
||
1007 | target: info.anchor.target.getOr(''), |
||
1008 | classz: info.anchor.linkClass.getOr('') |
||
1009 | }; |
||
1010 | }; |
||
1011 | var makeDialog = function (settings, onSubmit) { |
||
1012 | var urlInput = [{ |
||
1013 | name: 'url', |
||
1014 | type: 'urlinput', |
||
1015 | filetype: 'file', |
||
1016 | label: 'URL' |
||
1017 | }]; |
||
1018 | var displayText = settings.anchor.text.map(function () { |
||
1019 | return { |
||
1020 | name: 'text', |
||
1021 | type: 'input', |
||
1022 | label: 'Text to display' |
||
1023 | }; |
||
1024 | }).toArray(); |
||
1025 | var titleText = settings.flags.titleEnabled ? [{ |
||
1026 | name: 'title', |
||
1027 | type: 'input', |
||
1028 | label: 'Title' |
||
1029 | }] : []; |
||
1030 | var initialData = getInitialData(settings); |
||
1031 | var dialogDelta = DialogChanges.init(initialData, settings); |
||
1032 | var catalogs = settings.catalogs; |
||
1033 | var body = { |
||
1034 | type: 'panel', |
||
1035 | items: flatten([ |
||
1036 | urlInput, |
||
1037 | displayText, |
||
1038 | titleText, |
||
1039 | cat([ |
||
1040 | catalogs.anchor.map(ListOptions.createUi('anchor', 'Anchors')), |
||
1041 | catalogs.rels.map(ListOptions.createUi('rel', 'Rel')), |
||
1042 | catalogs.targets.map(ListOptions.createUi('target', 'Open link in...')), |
||
1043 | catalogs.link.map(ListOptions.createUi('link', 'Link list')), |
||
1044 | catalogs.classes.map(ListOptions.createUi('classz', 'Class')) |
||
1045 | ]) |
||
1046 | ]) |
||
1047 | }; |
||
1048 | return { |
||
1049 | title: 'Insert/Edit Link', |
||
1050 | size: 'normal', |
||
1051 | body: body, |
||
1052 | buttons: [ |
||
1053 | { |
||
1054 | type: 'cancel', |
||
1055 | name: 'cancel', |
||
1056 | text: 'Cancel' |
||
1057 | }, |
||
1058 | { |
||
1059 | type: 'submit', |
||
1060 | name: 'save', |
||
1061 | text: 'Save', |
||
1062 | primary: true |
||
1063 | } |
||
1064 | ], |
||
1065 | initialData: initialData, |
||
1066 | onChange: function (api, _a) { |
||
1067 | var name = _a.name; |
||
1068 | dialogDelta.onChange(api.getData, { name: name }).each(function (newData) { |
||
1069 | api.setData(newData); |
||
1070 | }); |
||
1071 | }, |
||
1072 | onSubmit: onSubmit |
||
1073 | }; |
||
1074 | }; |
||
1075 | var open$1 = function (editor) { |
||
1076 | var data = collectData(editor); |
||
1077 | data.map(function (info) { |
||
1078 | var onSubmit = handleSubmit(editor, info, info.anchor.text, Settings.assumeExternalTargets(editor.settings)); |
||
1079 | return makeDialog(info, onSubmit); |
||
1080 | }).get(function (spec) { |
||
1081 | editor.windowManager.open(spec); |
||
1082 | }); |
||
1083 | }; |
||
1084 | var Dialog = { open: open$1 }; |
||
1085 | |||
1086 | var getLink = function (editor, elm) { |
||
1087 | return editor.dom.getParent(elm, 'a[href]'); |
||
1088 | }; |
||
1089 | var getSelectedLink = function (editor) { |
||
1090 | return getLink(editor, editor.selection.getStart()); |
||
1091 | }; |
||
1092 | var hasOnlyAltModifier = function (e) { |
||
1093 | return e.altKey === true && e.shiftKey === false && e.ctrlKey === false && e.metaKey === false; |
||
1094 | }; |
||
1095 | var gotoLink = function (editor, a) { |
||
1096 | if (a) { |
||
1097 | var href = Utils.getHref(a); |
||
1098 | if (/^#/.test(href)) { |
||
1099 | var targetEl = editor.$(href); |
||
1100 | if (targetEl.length) { |
||
1101 | editor.selection.scrollIntoView(targetEl[0], true); |
||
1102 | } |
||
1103 | } else { |
||
1104 | OpenUrl.open(a.href); |
||
1105 | } |
||
1106 | } |
||
1107 | }; |
||
1108 | var openDialog = function (editor) { |
||
1109 | return function () { |
||
1110 | Dialog.open(editor); |
||
1111 | }; |
||
1112 | }; |
||
1113 | var gotoSelectedLink = function (editor) { |
||
1114 | return function () { |
||
1115 | gotoLink(editor, getSelectedLink(editor)); |
||
1116 | }; |
||
1117 | }; |
||
1118 | var leftClickedOnAHref = function (editor) { |
||
1119 | return function (elm) { |
||
1120 | var sel, rng, node; |
||
1121 | if (Settings.hasContextToolbar(editor.settings) && Utils.isLink(elm)) { |
||
1122 | sel = editor.selection; |
||
1123 | rng = sel.getRng(); |
||
1124 | node = rng.startContainer; |
||
1125 | if (node.nodeType === 3 && sel.isCollapsed() && rng.startOffset > 0 && rng.startOffset < node.data.length) { |
||
1126 | return true; |
||
1127 | } |
||
1128 | } |
||
1129 | return false; |
||
1130 | }; |
||
1131 | }; |
||
1132 | var setupGotoLinks = function (editor) { |
||
1133 | editor.on('click', function (e) { |
||
1134 | var link = getLink(editor, e.target); |
||
1135 | if (link && global$1.metaKeyPressed(e)) { |
||
1136 | e.preventDefault(); |
||
1137 | gotoLink(editor, link); |
||
1138 | } |
||
1139 | }); |
||
1140 | editor.on('keydown', function (e) { |
||
1141 | var link = getSelectedLink(editor); |
||
1142 | if (link && e.keyCode === 13 && hasOnlyAltModifier(e)) { |
||
1143 | e.preventDefault(); |
||
1144 | gotoLink(editor, link); |
||
1145 | } |
||
1146 | }); |
||
1147 | }; |
||
1148 | var toggleActiveState = function (editor) { |
||
1149 | return function (api) { |
||
1150 | var nodeChangeHandler = function (e) { |
||
1151 | return api.setActive(!editor.readonly && !!Utils.getAnchorElement(editor, e.element)); |
||
1152 | }; |
||
1153 | editor.on('nodechange', nodeChangeHandler); |
||
1154 | return function () { |
||
1155 | return editor.off('nodechange', nodeChangeHandler); |
||
1156 | }; |
||
1157 | }; |
||
1158 | }; |
||
1159 | var toggleEnabledState = function (editor) { |
||
1160 | return function (api) { |
||
1161 | api.setDisabled(!Utils.hasLinks(editor.dom.getParents(editor.selection.getStart()))); |
||
1162 | var nodeChangeHandler = function (e) { |
||
1163 | return api.setDisabled(!Utils.hasLinks(e.parents)); |
||
1164 | }; |
||
1165 | editor.on('nodechange', nodeChangeHandler); |
||
1166 | return function () { |
||
1167 | return editor.off('nodechange', nodeChangeHandler); |
||
1168 | }; |
||
1169 | }; |
||
1170 | }; |
||
1171 | var Actions = { |
||
1172 | openDialog: openDialog, |
||
1173 | gotoSelectedLink: gotoSelectedLink, |
||
1174 | leftClickedOnAHref: leftClickedOnAHref, |
||
1175 | setupGotoLinks: setupGotoLinks, |
||
1176 | toggleActiveState: toggleActiveState, |
||
1177 | toggleEnabledState: toggleEnabledState |
||
1178 | }; |
||
1179 | |||
1180 | var register = function (editor) { |
||
1181 | editor.addCommand('mceLink', function () { |
||
1182 | if (Settings.useQuickLink(editor.settings)) { |
||
1183 | editor.fire('contexttoolbar-show', { toolbarKey: 'link-form' }); |
||
1184 | } else { |
||
1185 | Actions.openDialog(editor)(); |
||
1186 | } |
||
1187 | }); |
||
1188 | }; |
||
1189 | var Commands = { register: register }; |
||
1190 | |||
1191 | var setup = function (editor) { |
||
1192 | editor.addShortcut('Meta+K', '', function () { |
||
1193 | editor.execCommand('mceLink'); |
||
1194 | }); |
||
1195 | }; |
||
1196 | var Keyboard = { setup: setup }; |
||
1197 | |||
1198 | var setupButtons = function (editor) { |
||
1199 | editor.ui.registry.addToggleButton('link', { |
||
1200 | icon: 'link', |
||
1201 | tooltip: 'Insert/edit link', |
||
1202 | onAction: Actions.openDialog(editor), |
||
1203 | onSetup: Actions.toggleActiveState(editor) |
||
1204 | }); |
||
1205 | editor.ui.registry.addButton('unlink', { |
||
1206 | icon: 'unlink', |
||
1207 | tooltip: 'Remove link', |
||
1208 | onAction: Utils.unlink(editor), |
||
1209 | onSetup: Actions.toggleEnabledState(editor) |
||
1210 | }); |
||
1211 | }; |
||
1212 | var setupMenuItems = function (editor) { |
||
1213 | editor.ui.registry.addMenuItem('openlink', { |
||
1214 | text: 'Open link', |
||
1215 | icon: 'new-tab', |
||
1216 | onAction: Actions.gotoSelectedLink(editor), |
||
1217 | onSetup: Actions.toggleEnabledState(editor) |
||
1218 | }); |
||
1219 | editor.ui.registry.addMenuItem('link', { |
||
1220 | icon: 'link', |
||
1221 | text: 'Link...', |
||
1222 | shortcut: 'Meta+K', |
||
1223 | onAction: Actions.openDialog(editor) |
||
1224 | }); |
||
1225 | editor.ui.registry.addMenuItem('unlink', { |
||
1226 | icon: 'unlink', |
||
1227 | text: 'Remove link', |
||
1228 | onAction: Utils.unlink(editor), |
||
1229 | onSetup: Actions.toggleEnabledState(editor) |
||
1230 | }); |
||
1231 | }; |
||
1232 | var setupContextMenu = function (editor) { |
||
1233 | var noLink = 'link'; |
||
1234 | var inLink = 'link unlink openlink'; |
||
1235 | editor.ui.registry.addContextMenu('link', { |
||
1236 | update: function (element) { |
||
1237 | return Utils.hasLinks(editor.dom.getParents(element, 'a')) ? inLink : noLink; |
||
1238 | } |
||
1239 | }); |
||
1240 | }; |
||
1241 | var setupContextToolbars = function (editor) { |
||
1242 | var collapseSelectionToEnd = function (editor) { |
||
1243 | editor.selection.collapse(false); |
||
1244 | }; |
||
1245 | editor.ui.registry.addContextForm('link-form', { |
||
1246 | launch: { |
||
1247 | type: 'contextformtogglebutton', |
||
1248 | icon: 'link', |
||
1249 | onSetup: Actions.toggleActiveState(editor) |
||
1250 | }, |
||
1251 | label: 'Link', |
||
1252 | predicate: function (node) { |
||
1253 | return !!Utils.getAnchorElement(editor, node) && Settings.hasContextToolbar(editor.settings); |
||
1254 | }, |
||
1255 | initValue: function () { |
||
1256 | var elm = Utils.getAnchorElement(editor); |
||
1257 | return !!elm ? Utils.getHref(elm) : ''; |
||
1258 | }, |
||
1259 | commands: [ |
||
1260 | { |
||
1261 | type: 'contextformtogglebutton', |
||
1262 | icon: 'link', |
||
1263 | tooltip: 'Link', |
||
1264 | primary: true, |
||
1265 | onSetup: function (buttonApi) { |
||
1266 | var node = editor.selection.getNode(); |
||
1267 | buttonApi.setActive(!!Utils.getAnchorElement(editor, node)); |
||
1268 | return Actions.toggleActiveState(editor)(buttonApi); |
||
1269 | }, |
||
1270 | onAction: function (formApi) { |
||
1271 | var anchor = Utils.getAnchorElement(editor); |
||
1272 | var value = formApi.getValue(); |
||
1273 | if (!anchor) { |
||
1274 | var attachState = { |
||
1275 | href: value, |
||
1276 | attach: function () { |
||
1277 | } |
||
1278 | }; |
||
1279 | var onlyText = Utils.isOnlyTextSelected(editor.selection.getContent()); |
||
1280 | var text = onlyText ? Option.some(Utils.getAnchorText(editor.selection, anchor)).filter(function (t) { |
||
1281 | return t.length > 0; |
||
1282 | }) : Option.none(); |
||
1283 | Utils.link(editor, attachState)({ |
||
1284 | href: value, |
||
1285 | text: text.getOr(value) |
||
1286 | }); |
||
1287 | formApi.hide(); |
||
1288 | } else { |
||
1289 | editor.dom.setAttrib(anchor, 'href', value); |
||
1290 | collapseSelectionToEnd(editor); |
||
1291 | formApi.hide(); |
||
1292 | } |
||
1293 | } |
||
1294 | }, |
||
1295 | { |
||
1296 | type: 'contextformtogglebutton', |
||
1297 | icon: 'unlink', |
||
1298 | tooltip: 'Remove link', |
||
1299 | active: false, |
||
1300 | onSetup: function () { |
||
1301 | return function () { |
||
1302 | }; |
||
1303 | }, |
||
1304 | onAction: function (formApi) { |
||
1305 | Utils.unlink(editor)(); |
||
1306 | formApi.hide(); |
||
1307 | } |
||
1308 | } |
||
1309 | ] |
||
1310 | }); |
||
1311 | }; |
||
1312 | var Controls = { |
||
1313 | setupButtons: setupButtons, |
||
1314 | setupMenuItems: setupMenuItems, |
||
1315 | setupContextMenu: setupContextMenu, |
||
1316 | setupContextToolbars: setupContextToolbars |
||
1317 | }; |
||
1318 | |||
1319 | global.add('link', function (editor) { |
||
1320 | Controls.setupButtons(editor); |
||
1321 | Controls.setupMenuItems(editor); |
||
1322 | Controls.setupContextMenu(editor); |
||
1323 | Controls.setupContextToolbars(editor); |
||
1324 | Actions.setupGotoLinks(editor); |
||
1325 | Commands.register(editor); |
||
1326 | Keyboard.setup(editor); |
||
1327 | }); |
||
1328 | function Plugin () { |
||
1329 | } |
||
1330 | |||
1331 | return Plugin; |
||
1332 | |||
1333 | }()); |
||
1334 | })(); |