Subversion Repositories oidplus

Rev

Rev 1422 | View as "text/javascript" | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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.9 (2023-11-15)
  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. }());
  1294.