var link = (function (domGlobals) {
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK');
var assumeExternalTargets = function (editorSettings) {
return typeof editorSettings.link_assume_external_targets === 'boolean' ? editorSettings.link_assume_external_targets : false;
var hasContextToolbar = function (editorSettings) {
return typeof editorSettings.link_context_toolbar === 'boolean' ? editorSettings.link_context_toolbar : false;
var getLinkList = function (editorSettings) {
return editorSettings.link_list;
var hasDefaultLinkTarget = function (editorSettings) {
return typeof editorSettings.default_link_target === 'string';
var getDefaultLinkTarget = function (editorSettings) {
return editorSettings.default_link_target;
var getTargetList = function (editorSettings) {
return editorSettings.target_list;
var setTargetList = function (editor, list) {
editor.settings.target_list = list;
var shouldShowTargetList = function (editorSettings) {
return getTargetList(editorSettings) !== false;
var getRelList = function (editorSettings) {
return editorSettings.rel_list;
var hasRelList = function (editorSettings) {
return getRelList(editorSettings) !== undefined;
var getLinkClassList = function (editorSettings) {
return editorSettings.link_class_list;
var hasLinkClassList = function (editorSettings) {
return getLinkClassList(editorSettings) !== undefined;
var shouldShowLinkTitle = function (editorSettings) {
return editorSettings.link_title !== false;
var allowUnsafeLinkTarget = function (editorSettings) {
return typeof editorSettings.allow_unsafe_link_target === 'boolean' ? editorSettings.allow_unsafe_link_target : false;
assumeExternalTargets: assumeExternalTargets,
hasContextToolbar: hasContextToolbar,
getLinkList: getLinkList,
hasDefaultLinkTarget: hasDefaultLinkTarget,
getDefaultLinkTarget: getDefaultLinkTarget,
getTargetList: getTargetList,
setTargetList: setTargetList,
shouldShowTargetList: shouldShowTargetList,
getLinkClassList: getLinkClassList,
hasLinkClassList: hasLinkClassList,
shouldShowLinkTitle: shouldShowLinkTitle,
allowUnsafeLinkTarget: allowUnsafeLinkTarget
var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
var global$3 = tinymce.util.Tools.resolve('tinymce.Env');
var appendClickRemove = function (link, evt) {
domGlobals.document.body.appendChild(link);
domGlobals.document.body.removeChild(link);
var open = function (url) {
if (!global$3.ie || global$3.ie > 10) {
var link = domGlobals.document.createElement('a');
link.rel = 'noreferrer noopener';
var evt = domGlobals.document.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, domGlobals.window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
appendClickRemove(link, evt);
var win = domGlobals.window.open('', '_blank');
doc.write('<meta http-equiv="refresh" content="0; url=' + global$2.DOM.encode(url) + '">');
var OpenUrl = { open: open };
var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools');
var toggleTargetRules = function (rel, isUnsafe) {
var rules = ['noopener'];
var newRel = rel ? rel.split(/\s+/) : [];
var toString = function (rel) {
return global$4.trim(rel.sort().join(' '));
var addTargetRules = function (rel) {
rel = removeTargetRules(rel);
return rel.length ? rel.concat(rules) : rules;
var removeTargetRules = function (rel) {
return rel.filter(function (val) {
return global$4.inArray(rules, val) === -1;
newRel = isUnsafe ? addTargetRules(newRel) : removeTargetRules(newRel);
return newRel.length ? toString(newRel) : null;
var trimCaretContainers = function (text) {
return text.replace(/\uFEFF/g, '');
var getAnchorElement = function (editor, selectedElm) {
selectedElm = selectedElm || editor.selection.getNode();
if (isImageFigure(selectedElm)) {
return editor.dom.select('a[href]', selectedElm)[0];
return editor.dom.getParent(selectedElm, 'a[href]');
var getAnchorText = function (selection, anchorElm) {
var text = anchorElm ? anchorElm.innerText || anchorElm.textContent : selection.getContent({ format: 'text' });
return trimCaretContainers(text);
var isLink = function (elm) {
return elm && elm.nodeName === 'A' && elm.href;
var hasLinks = function (elements) {
return global$4.grep(elements, isLink).length > 0;
var isOnlyTextSelected = function (html) {
if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') === -1)) {
var isImageFigure = function (node) {
return node && node.nodeName === 'FIGURE' && /\bimage\b/i.test(node.className);
var link = function (editor, attachState) {
editor.undoManager.transact(function () {
var selectedElm = editor.selection.getNode();
var anchorElm = getAnchorElement(editor, selectedElm);
target: data.target ? data.target : null,
rel: data.rel ? data.rel : null,
class: data.class ? data.class : null,
title: data.title ? data.title : null
if (!Settings.hasRelList(editor.settings) && Settings.allowUnsafeLinkTarget(editor.settings) === false) {
linkAttrs.rel = toggleTargetRules(linkAttrs.rel, linkAttrs.target === '_blank');
if (data.href === attachState.href) {
if (data.hasOwnProperty('text')) {
if ('innerText' in anchorElm) {
anchorElm.innerText = data.text;
anchorElm.textContent = data.text;
editor.dom.setAttribs(anchorElm, linkAttrs);
editor.selection.select(anchorElm);
editor.undoManager.add();
if (isImageFigure(selectedElm)) {
linkImageFigure(editor, selectedElm, linkAttrs);
} else if (data.hasOwnProperty('text')) {
editor.insertContent(editor.dom.createHTML('a', linkAttrs, editor.dom.encode(data.text)));
editor.execCommand('mceInsertLink', false, linkAttrs);
var unlink = function (editor) {
editor.undoManager.transact(function () {
var node = editor.selection.getNode();
if (isImageFigure(node)) {
unlinkImageFigure(editor, node);
editor.execCommand('unlink');
var unlinkImageFigure = function (editor, fig) {
img = editor.dom.select('img', fig)[0];
a = editor.dom.getParents(img, 'a[href]', fig)[0];
a.parentNode.insertBefore(img, a);
var linkImageFigure = function (editor, fig, attrs) {
img = editor.dom.select('img', fig)[0];
a = editor.dom.create('a', attrs);
img.parentNode.insertBefore(a, img);
isOnlyTextSelected: isOnlyTextSelected,
getAnchorElement: getAnchorElement,
getAnchorText: getAnchorText,
toggleTargetRules: toggleTargetRules
var global$5 = tinymce.util.Tools.resolve('tinymce.util.Delay');
var global$6 = tinymce.util.Tools.resolve('tinymce.util.XHR');
var createLinkList = function (editor, callback) {
var linkList = Settings.getLinkList(editor.settings);
if (typeof linkList === 'string') {
success: function (text) {
callback(editor, JSON.parse(text));
} else if (typeof linkList === 'function') {
linkList(function (list) {
callback(editor, linkList);
var buildListItems = function (inputList, itemCallback, startItems) {
var appendItems = function (values, output) {
global$4.each(values, function (item) {
var menuItem = { text: item.text || item.title };
menuItem.menu = appendItems(item.menu);
menuItem.value = item.value;
return appendItems(inputList, startItems || []);
var delayedConfirm = function (editor, message, callback) {
var rng = editor.selection.getRng();
global$5.setEditorTimeout(editor, function () {
editor.windowManager.confirm(message, function (state) {
editor.selection.setRng(rng);
var showDialog = function (editor, linkList) {
var selection = editor.selection;
var anchorElm, initialText;
var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value;
var linkListChangeHandler = function (e) {
var textCtrl = win.find('#text');
if (!textCtrl.value() || e.lastControl && textCtrl.value() === e.lastControl.text()) {
textCtrl.value(e.control.text());
win.find('#href').value(e.control.value());
var buildAnchorListControl = function (url) {
global$4.each(editor.dom.select('a:not([href])'), function (anchor) {
var id = anchor.name || anchor.id;
selected: url.indexOf('#' + id) !== -1
onselect: linkListChangeHandler
var updateText = function () {
if (!initialText && onlyText && !data.text) {
this.parent().parent().find('#text')[0].value(this.value());
var urlChange = function (e) {
linkListCtrl.value(editor.convertURL(this.value(), 'href'));
global$4.each(e.meta, function (value, key) {
var inp = win.find('#' + key);
if (initialText.length === 0) {
var onBeforeCall = function (e) {
onlyText = Utils.isOnlyTextSelected(selection.getContent());
anchorElm = Utils.getAnchorElement(editor);
data.text = initialText = Utils.getAnchorText(editor.selection, anchorElm);
data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : '';
data.target = dom.getAttrib(anchorElm, 'target');
} else if (Settings.hasDefaultLinkTarget(editor.settings)) {
data.target = Settings.getDefaultLinkTarget(editor.settings);
if (value = dom.getAttrib(anchorElm, 'rel')) {
if (value = dom.getAttrib(anchorElm, 'class')) {
if (value = dom.getAttrib(anchorElm, 'title')) {
label: 'Text to display',
data.text = this.value();
values: buildListItems(linkList, function (item) {
item.value = editor.convertURL(item.value || item.url, 'href');
onselect: linkListChangeHandler,
value: editor.convertURL(data.href, 'href'),
onPostRender: function () {
if (Settings.shouldShowTargetList(editor.settings)) {
if (Settings.getTargetList(editor.settings) === undefined) {
Settings.setTargetList(editor, [
values: buildListItems(Settings.getTargetList(editor.settings))
if (Settings.hasRelList(editor.settings)) {
values: buildListItems(Settings.getRelList(editor.settings), function (item) {
if (Settings.allowUnsafeLinkTarget(editor.settings) === false) {
item.value = Utils.toggleTargetRules(item.value, data.target === '_blank');
if (Settings.hasLinkClassList(editor.settings)) {
values: buildListItems(Settings.getLinkClassList(editor.settings), function (item) {
item.textStyle = function () {
return editor.formatter.getCssText({
if (Settings.shouldShowLinkTitle(editor.settings)) {
win = editor.windowManager.open({
onbeforecall: onBeforeCall
buildAnchorListControl(data.href),
var assumeExternalTargets = Settings.assumeExternalTargets(editor.settings);
var insertLink = Utils.link(editor, attachState);
var removeLink = Utils.unlink(editor);
var resultData = global$4.extend({}, data, e.data);
var href = resultData.href;
if (!onlyText || resultData.text === initialText) {
if (href.indexOf('@') > 0 && href.indexOf('//') === -1 && href.indexOf('mailto:') === -1) {
delayedConfirm(editor, 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?', function (state) {