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