WordPress.org

Make WordPress Core

Ticket #41590: 41590.patch

File 41590.patch, 88.2 KB (added by turtlepod, 3 years ago)

TinyMCE Link Plugin

  • wp-includes/js/tinymce/plugins/link/plugin.js

     
     1(function () {
     2
     3var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)}
     4
     5// Used when there is no 'main' module.
     6// The name is probably (hopefully) unique so minification removes for releases.
     7var register_3795 = function (id) {
     8  var module = dem(id);
     9  var fragments = id.split('.');
     10  var target = Function('return this;')();
     11  for (var i = 0; i < fragments.length - 1; ++i) {
     12    if (target[fragments[i]] === undefined)
     13      target[fragments[i]] = {};
     14    target = target[fragments[i]];
     15  }
     16  target[fragments[fragments.length - 1]] = module;
     17};
     18
     19var instantiate = function (id) {
     20  var actual = defs[id];
     21  var dependencies = actual.deps;
     22  var definition = actual.defn;
     23  var len = dependencies.length;
     24  var instances = new Array(len);
     25  for (var i = 0; i < len; ++i)
     26    instances[i] = dem(dependencies[i]);
     27  var defResult = definition.apply(null, instances);
     28  if (defResult === undefined)
     29     throw 'module [' + id + '] returned undefined';
     30  actual.instance = defResult;
     31};
     32
     33var def = function (id, dependencies, definition) {
     34  if (typeof id !== 'string')
     35    throw 'module id must be a string';
     36  else if (dependencies === undefined)
     37    throw 'no dependencies for ' + id;
     38  else if (definition === undefined)
     39    throw 'no definition function for ' + id;
     40  defs[id] = {
     41    deps: dependencies,
     42    defn: definition,
     43    instance: undefined
     44  };
     45};
     46
     47var dem = function (id) {
     48  var actual = defs[id];
     49  if (actual === undefined)
     50    throw 'module [' + id + '] was undefined';
     51  else if (actual.instance === undefined)
     52    instantiate(id);
     53  return actual.instance;
     54};
     55
     56var req = function (ids, callback) {
     57  var len = ids.length;
     58  var instances = new Array(len);
     59  for (var i = 0; i < len; ++i)
     60    instances.push(dem(ids[i]));
     61  callback.apply(null, callback);
     62};
     63
     64var ephox = {};
     65
     66ephox.bolt = {
     67  module: {
     68    api: {
     69      define: def,
     70      require: req,
     71      demand: dem
     72    }
     73  }
     74};
     75
     76var define = def;
     77var require = req;
     78var demand = dem;
     79// this helps with minificiation when using a lot of global references
     80var defineGlobal = function (id, ref) {
     81  define(id, [], function () { return ref; });
     82};
     83/*jsc
     84["tinymce.plugins.link.Plugin","tinymce.core.PluginManager","tinymce.plugins.link.core.Actions","tinymce.plugins.link.ui.Controls","global!tinymce.util.Tools.resolve","tinymce.core.util.VK","tinymce.plugins.link.ui.Dialog","tinymce.plugins.link.core.OpenUrl","tinymce.plugins.link.core.Utils","tinymce.plugins.link.core.Settings","tinymce.core.util.Delay","tinymce.core.util.Tools","tinymce.core.util.XHR","global!RegExp","tinymce.core.dom.DOMUtils","tinymce.core.Env"]
     85jsc*/
     86defineGlobal("global!tinymce.util.Tools.resolve", tinymce.util.Tools.resolve);
     87/**
     88 * ResolveGlobal.js
     89 *
     90 * Released under LGPL License.
     91 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     92 *
     93 * License: http://www.tinymce.com/license
     94 * Contributing: http://www.tinymce.com/contributing
     95 */
     96
     97define(
     98  'tinymce.core.PluginManager',
     99  [
     100    'global!tinymce.util.Tools.resolve'
     101  ],
     102  function (resolve) {
     103    return resolve('tinymce.PluginManager');
     104  }
     105);
     106
     107/**
     108 * ResolveGlobal.js
     109 *
     110 * Released under LGPL License.
     111 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     112 *
     113 * License: http://www.tinymce.com/license
     114 * Contributing: http://www.tinymce.com/contributing
     115 */
     116
     117define(
     118  'tinymce.core.util.VK',
     119  [
     120    'global!tinymce.util.Tools.resolve'
     121  ],
     122  function (resolve) {
     123    return resolve('tinymce.util.VK');
     124  }
     125);
     126
     127/**
     128 * ResolveGlobal.js
     129 *
     130 * Released under LGPL License.
     131 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     132 *
     133 * License: http://www.tinymce.com/license
     134 * Contributing: http://www.tinymce.com/contributing
     135 */
     136
     137define(
     138  'tinymce.core.util.Delay',
     139  [
     140    'global!tinymce.util.Tools.resolve'
     141  ],
     142  function (resolve) {
     143    return resolve('tinymce.util.Delay');
     144  }
     145);
     146
     147/**
     148 * ResolveGlobal.js
     149 *
     150 * Released under LGPL License.
     151 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     152 *
     153 * License: http://www.tinymce.com/license
     154 * Contributing: http://www.tinymce.com/contributing
     155 */
     156
     157define(
     158  'tinymce.core.util.Tools',
     159  [
     160    'global!tinymce.util.Tools.resolve'
     161  ],
     162  function (resolve) {
     163    return resolve('tinymce.util.Tools');
     164  }
     165);
     166
     167/**
     168 * ResolveGlobal.js
     169 *
     170 * Released under LGPL License.
     171 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     172 *
     173 * License: http://www.tinymce.com/license
     174 * Contributing: http://www.tinymce.com/contributing
     175 */
     176
     177define(
     178  'tinymce.core.util.XHR',
     179  [
     180    'global!tinymce.util.Tools.resolve'
     181  ],
     182  function (resolve) {
     183    return resolve('tinymce.util.XHR');
     184  }
     185);
     186
     187define(
     188  'tinymce.plugins.link.core.Settings',
     189  [
     190
     191  ],
     192  function () {
     193    var assumeExternalTargets = function (editorSettings) {
     194      return typeof editorSettings.link_assume_external_targets === 'boolean' ? editorSettings.link_assume_external_targets : false;
     195    };
     196
     197    var hasContextToolbar = function (editorSettings) {
     198      return typeof editorSettings.link_context_toolbar === 'boolean' ? editorSettings.link_context_toolbar : false;
     199    };
     200
     201    var getLinkList = function (editorSettings) {
     202      return editorSettings.link_list;
     203    };
     204
     205    var hasDefaultLinkTarget = function (editorSettings) {
     206      return typeof editorSettings.default_link_target === 'string';
     207    };
     208
     209    var getDefaultLinkTarget = function (editorSettings) {
     210      return editorSettings.default_link_target;
     211    };
     212
     213    var getTargetList = function (editorSettings) {
     214      return editorSettings.target_list;
     215    };
     216
     217    var setTargetList = function (editor, list) {
     218      editor.settings.target_list = list;
     219    };
     220
     221    var shouldShowTargetList = function (editorSettings) {
     222      return getTargetList(editorSettings) !== false;
     223    };
     224
     225    var getRelList = function (editorSettings) {
     226      return editorSettings.rel_list;
     227    };
     228
     229    var hasRelList = function (editorSettings) {
     230      return getRelList(editorSettings) !== undefined;
     231    };
     232
     233    var getLinkClassList = function (editorSettings) {
     234      return editorSettings.link_class_list;
     235    };
     236
     237    var hasLinkClassList = function (editorSettings) {
     238      return getLinkClassList(editorSettings) !== undefined;
     239    };
     240
     241    var shouldShowLinkTitle = function (editorSettings) {
     242      return editorSettings.link_title !== false;
     243    };
     244
     245    var allowUnsafeLinkTarget = function (editorSettings) {
     246      return typeof editorSettings.allow_unsafe_link_target === 'boolean' ? editorSettings.allow_unsafe_link_target : false;
     247    };
     248
     249    return {
     250      assumeExternalTargets: assumeExternalTargets,
     251      hasContextToolbar: hasContextToolbar,
     252      getLinkList: getLinkList,
     253      hasDefaultLinkTarget: hasDefaultLinkTarget,
     254      getDefaultLinkTarget: getDefaultLinkTarget,
     255      getTargetList: getTargetList,
     256      setTargetList: setTargetList,
     257      shouldShowTargetList: shouldShowTargetList,
     258      getRelList: getRelList,
     259      hasRelList: hasRelList,
     260      getLinkClassList: getLinkClassList,
     261      hasLinkClassList: hasLinkClassList,
     262      shouldShowLinkTitle: shouldShowLinkTitle,
     263      allowUnsafeLinkTarget: allowUnsafeLinkTarget
     264    };
     265  }
     266);
     267
     268defineGlobal("global!RegExp", RegExp);
     269/**
     270 * Utils.js
     271 *
     272 * Released under LGPL License.
     273 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     274 *
     275 * License: http://www.tinymce.com/license
     276 * Contributing: http://www.tinymce.com/contributing
     277 */
     278
     279define(
     280  'tinymce.plugins.link.core.Utils',
     281  [
     282    'tinymce.core.util.Tools',
     283    'tinymce.plugins.link.core.Settings',
     284    'global!RegExp'
     285  ],
     286  function (Tools, Settings, RegExp) {
     287
     288    var toggleTargetRules = function (rel, isUnsafe) {
     289      var rules = ['noopener'];
     290      var newRel = rel ? rel.split(/\s+/) : [];
     291
     292      var toString = function (rel) {
     293        return Tools.trim(rel.sort().join(' '));
     294      };
     295
     296      var addTargetRules = function (rel) {
     297        rel = removeTargetRules(rel);
     298        return rel.length ? rel.concat(rules) : rules;
     299      };
     300
     301      var removeTargetRules = function (rel) {
     302        return rel.filter(function (val) {
     303          return Tools.inArray(rules, val) === -1;
     304        });
     305      };
     306
     307      newRel = isUnsafe ? addTargetRules(newRel) : removeTargetRules(newRel);
     308      return newRel.length ? toString(newRel) : null;
     309    };
     310
     311
     312    var trimCaretContainers = function (text) {
     313      return text.replace(/\uFEFF/g, '');
     314    };
     315
     316
     317    var getAnchorElement = function (editor, selectedElm) {
     318      selectedElm = selectedElm || editor.selection.getStart();
     319      if (isImageFigure(selectedElm)) {
     320        // for an image conained in a figure we look for a link inside the selected element
     321        return editor.dom.select('a[href]', selectedElm)[0];
     322      } else {
     323        return editor.dom.getParent(selectedElm, 'a[href]');
     324      }
     325    };
     326
     327
     328    var getAnchorText = function (selection, anchorElm) {
     329      var text = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({ format: 'text' });
     330      return trimCaretContainers(text);
     331    };
     332
     333
     334    var isLink = function (elm) {
     335      return elm && elm.nodeName === 'A' && elm.href;
     336    };
     337
     338    var hasLinks = function (elements) {
     339      return Tools.grep(elements, isLink).length > 0;
     340    };
     341
     342
     343    var isOnlyTextSelected = function (html) {
     344      // Partial html and not a fully selected anchor element
     345      if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') == -1)) {
     346        return false;
     347      }
     348
     349      return true;
     350    };
     351
     352
     353    var isImageFigure = function (node) {
     354      return node && node.nodeName === 'FIGURE' && /\bimage\b/i.test(node.className);
     355    };
     356
     357
     358    var link = function (editor, attachState) {
     359      return function (data) {
     360        editor.undoManager.transact(function () {
     361          var selectedElm = editor.selection.getNode();
     362          var anchorElm = getAnchorElement(editor, selectedElm);
     363
     364          var linkAttrs = {
     365            href: data.href,
     366            target: data.target ? data.target : null,
     367            rel: data.rel ? data.rel : null,
     368            "class": data["class"] ? data["class"] : null,
     369            title: data.title ? data.title : null
     370          };
     371
     372          if (!Settings.hasRelList(editor.settings) && Settings.allowUnsafeLinkTarget(editor.settings) === false) {
     373            linkAttrs.rel = toggleTargetRules(linkAttrs.rel, linkAttrs.target == '_blank');
     374          }
     375
     376          if (data.href === attachState.href) {
     377            attachState.attach();
     378            attachState = {};
     379          }
     380
     381          if (anchorElm) {
     382            editor.focus();
     383
     384            if (data.hasOwnProperty('text')) {
     385              if ("innerText" in anchorElm) {
     386                anchorElm.innerText = data.text;
     387              } else {
     388                anchorElm.textContent = data.text;
     389              }
     390            }
     391
     392            editor.dom.setAttribs(anchorElm, linkAttrs);
     393
     394            editor.selection.select(anchorElm);
     395            editor.undoManager.add();
     396          } else {
     397            if (isImageFigure(selectedElm)) {
     398              linkImageFigure(editor, selectedElm, linkAttrs);
     399            } else if (data.hasOwnProperty('text')) {
     400              editor.insertContent(editor.dom.createHTML('a', linkAttrs, editor.dom.encode(data.text)));
     401            } else {
     402              editor.execCommand('mceInsertLink', false, linkAttrs);
     403            }
     404          }
     405        });
     406      };
     407    };
     408
     409
     410    var unlink = function (editor) {
     411      return function () {
     412        editor.undoManager.transact(function () {
     413          var node = editor.selection.getNode();
     414          if (isImageFigure(node)) {
     415            unlinkImageFigure(editor, node);
     416          } else {
     417            editor.execCommand('unlink');
     418          }
     419        });
     420      };
     421    };
     422
     423
     424    var unlinkImageFigure = function (editor, fig) {
     425      var a, img;
     426      img = editor.dom.select('img', fig)[0];
     427      if (img) {
     428        a = editor.dom.getParents(img, 'a[href]', fig)[0];
     429        if (a) {
     430          a.parentNode.insertBefore(img, a);
     431          editor.dom.remove(a);
     432        }
     433      }
     434    };
     435
     436
     437    var linkImageFigure = function (editor, fig, attrs) {
     438      var a, img;
     439      img = editor.dom.select('img', fig)[0];
     440      if (img) {
     441        a = editor.dom.create('a', attrs);
     442        img.parentNode.insertBefore(a, img);
     443        a.appendChild(img);
     444      }
     445    };
     446
     447    return {
     448      link: link,
     449      unlink: unlink,
     450      isLink: isLink,
     451      hasLinks: hasLinks,
     452      isOnlyTextSelected: isOnlyTextSelected,
     453      getAnchorElement: getAnchorElement,
     454      getAnchorText: getAnchorText,
     455      toggleTargetRules: toggleTargetRules
     456    };
     457  }
     458);
     459/**
     460 * Dialog.js
     461 *
     462 * Released under LGPL License.
     463 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     464 *
     465 * License: http://www.tinymce.com/license
     466 * Contributing: http://www.tinymce.com/contributing
     467 */
     468
     469define(
     470  'tinymce.plugins.link.ui.Dialog',
     471  [
     472    'tinymce.core.util.Delay',
     473    'tinymce.core.util.Tools',
     474    'tinymce.core.util.XHR',
     475    'tinymce.plugins.link.core.Utils',
     476    'tinymce.plugins.link.core.Settings'
     477  ],
     478  function (Delay, Tools, XHR, Utils, Settings) {
     479    var attachState = {};
     480
     481    var createLinkList = function (editor, callback) {
     482      var linkList = Settings.getLinkList(editor.settings);
     483
     484      if (typeof linkList == "string") {
     485        XHR.send({
     486          url: linkList,
     487          success: function (text) {
     488            callback(editor, JSON.parse(text));
     489          }
     490        });
     491      } else if (typeof linkList == "function") {
     492        linkList(function (list) {
     493          callback(editor, list);
     494        });
     495      } else {
     496        callback(editor, linkList);
     497      }
     498    };
     499
     500    var buildListItems = function (inputList, itemCallback, startItems) {
     501      var appendItems = function (values, output) {
     502        output = output || [];
     503
     504        Tools.each(values, function (item) {
     505          var menuItem = { text: item.text || item.title };
     506
     507          if (item.menu) {
     508            menuItem.menu = appendItems(item.menu);
     509          } else {
     510            menuItem.value = item.value;
     511
     512            if (itemCallback) {
     513              itemCallback(menuItem);
     514            }
     515          }
     516
     517          output.push(menuItem);
     518        });
     519
     520        return output;
     521      };
     522
     523      return appendItems(inputList, startItems || []);
     524    };
     525
     526    // Delay confirm since onSubmit will move focus
     527    var delayedConfirm = function (editor, message, callback) {
     528      var rng = editor.selection.getRng();
     529
     530      Delay.setEditorTimeout(editor, function () {
     531        editor.windowManager.confirm(message, function (state) {
     532          editor.selection.setRng(rng);
     533          callback(state);
     534        });
     535      });
     536    };
     537
     538    var showDialog = function (editor, linkList) {
     539      var data = {}, selection = editor.selection, dom = editor.dom, anchorElm, initialText;
     540      var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value;
     541
     542      var linkListChangeHandler = function (e) {
     543        var textCtrl = win.find('#text');
     544
     545        if (!textCtrl.value() || (e.lastControl && textCtrl.value() == e.lastControl.text())) {
     546          textCtrl.value(e.control.text());
     547        }
     548
     549        win.find('#href').value(e.control.value());
     550      };
     551
     552      var buildAnchorListControl = function (url) {
     553        var anchorList = [];
     554
     555        Tools.each(editor.dom.select('a:not([href])'), function (anchor) {
     556          var id = anchor.name || anchor.id;
     557
     558          if (id) {
     559            anchorList.push({
     560              text: id,
     561              value: '#' + id,
     562              selected: url.indexOf('#' + id) != -1
     563            });
     564          }
     565        });
     566
     567        if (anchorList.length) {
     568          anchorList.unshift({ text: 'None', value: '' });
     569
     570          return {
     571            name: 'anchor',
     572            type: 'listbox',
     573            label: 'Anchors',
     574            values: anchorList,
     575            onselect: linkListChangeHandler
     576          };
     577        }
     578      };
     579
     580      var updateText = function () {
     581        if (!initialText && onlyText && !data.text) {
     582          this.parent().parent().find('#text')[0].value(this.value());
     583        }
     584      };
     585
     586      var urlChange = function (e) {
     587        var meta = e.meta || {};
     588
     589        if (linkListCtrl) {
     590          linkListCtrl.value(editor.convertURL(this.value(), 'href'));
     591        }
     592
     593        Tools.each(e.meta, function (value, key) {
     594          var inp = win.find('#' + key);
     595
     596          if (key === 'text') {
     597            if (initialText.length === 0) {
     598              inp.value(value);
     599              data.text = value;
     600            }
     601          } else {
     602            inp.value(value);
     603          }
     604        });
     605
     606        if (meta.attach) {
     607          attachState = {
     608            href: this.value(),
     609            attach: meta.attach
     610          };
     611        }
     612
     613        if (!meta.text) {
     614          updateText.call(this);
     615        }
     616      };
     617
     618      var onBeforeCall = function (e) {
     619        e.meta = win.toJSON();
     620      };
     621
     622      onlyText = Utils.isOnlyTextSelected(selection.getContent());
     623      anchorElm = Utils.getAnchorElement(editor);
     624
     625      data.text = initialText = Utils.getAnchorText(editor.selection, anchorElm);
     626      data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : '';
     627
     628      if (anchorElm) {
     629        data.target = dom.getAttrib(anchorElm, 'target');
     630      } else if (Settings.hasDefaultLinkTarget(editor.settings)) {
     631        data.target = Settings.getDefaultLinkTarget(editor.settings);
     632      }
     633
     634      if ((value = dom.getAttrib(anchorElm, 'rel'))) {
     635        data.rel = value;
     636      }
     637
     638      if ((value = dom.getAttrib(anchorElm, 'class'))) {
     639        data['class'] = value;
     640      }
     641
     642      if ((value = dom.getAttrib(anchorElm, 'title'))) {
     643        data.title = value;
     644      }
     645
     646      if (onlyText) {
     647        textListCtrl = {
     648          name: 'text',
     649          type: 'textbox',
     650          size: 40,
     651          label: 'Text to display',
     652          onchange: function () {
     653            data.text = this.value();
     654          }
     655        };
     656      }
     657
     658      if (linkList) {
     659        linkListCtrl = {
     660          type: 'listbox',
     661          label: 'Link list',
     662          values: buildListItems(
     663            linkList,
     664            function (item) {
     665              item.value = editor.convertURL(item.value || item.url, 'href');
     666            },
     667            [{ text: 'None', value: '' }]
     668          ),
     669          onselect: linkListChangeHandler,
     670          value: editor.convertURL(data.href, 'href'),
     671          onPostRender: function () {
     672            /*eslint consistent-this:0*/
     673            linkListCtrl = this;
     674          }
     675        };
     676      }
     677
     678      if (Settings.shouldShowTargetList(editor.settings)) {
     679        if (Settings.getTargetList(editor.settings) === undefined) {
     680          Settings.setTargetList(editor, [
     681            { text: 'None', value: '' },
     682            { text: 'New window', value: '_blank' }
     683          ]);
     684        }
     685
     686        targetListCtrl = {
     687          name: 'target',
     688          type: 'listbox',
     689          label: 'Target',
     690          values: buildListItems(Settings.getTargetList(editor.settings))
     691        };
     692      }
     693
     694      if (Settings.hasRelList(editor.settings)) {
     695        relListCtrl = {
     696          name: 'rel',
     697          type: 'listbox',
     698          label: 'Rel',
     699          values: buildListItems(
     700            Settings.getRelList(editor.settings),
     701            function (item) {
     702              if (Settings.allowUnsafeLinkTarget(editor.settings) === false) {
     703                item.value = Utils.toggleTargetRules(item.value, data.target === '_blank');
     704              }
     705            }
     706          )
     707        };
     708      }
     709
     710      if (Settings.hasLinkClassList(editor.settings)) {
     711        classListCtrl = {
     712          name: 'class',
     713          type: 'listbox',
     714          label: 'Class',
     715          values: buildListItems(
     716            Settings.getLinkClassList(editor.settings),
     717            function (item) {
     718              if (item.value) {
     719                item.textStyle = function () {
     720                  return editor.formatter.getCssText({ inline: 'a', classes: [item.value] });
     721                };
     722              }
     723            }
     724          )
     725        };
     726      }
     727
     728      if (Settings.shouldShowLinkTitle(editor.settings)) {
     729        linkTitleCtrl = {
     730          name: 'title',
     731          type: 'textbox',
     732          label: 'Title',
     733          value: data.title
     734        };
     735      }
     736
     737      win = editor.windowManager.open({
     738        title: 'Insert link',
     739        data: data,
     740        body: [
     741          {
     742            name: 'href',
     743            type: 'filepicker',
     744            filetype: 'file',
     745            size: 40,
     746            autofocus: true,
     747            label: 'Url',
     748            onchange: urlChange,
     749            onkeyup: updateText,
     750            onbeforecall: onBeforeCall
     751          },
     752          textListCtrl,
     753          linkTitleCtrl,
     754          buildAnchorListControl(data.href),
     755          linkListCtrl,
     756          relListCtrl,
     757          targetListCtrl,
     758          classListCtrl
     759        ],
     760        onSubmit: function (e) {
     761          var assumeExternalTargets = Settings.assumeExternalTargets(editor.settings);
     762          var insertLink = Utils.link(editor, attachState);
     763          var removeLink = Utils.unlink(editor);
     764
     765          var resultData = Tools.extend({}, data, e.data);
     766          /*eslint dot-notation: 0*/
     767          var href = resultData.href;
     768
     769          if (!href) {
     770            removeLink();
     771            return;
     772          }
     773
     774          if (!onlyText || resultData.text === initialText) {
     775            delete resultData.text;
     776          }
     777
     778          // Is email and not //user@domain.com
     779          if (href.indexOf('@') > 0 && href.indexOf('//') == -1 && href.indexOf('mailto:') == -1) {
     780            delayedConfirm(
     781              editor,
     782              'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?',
     783              function (state) {
     784                if (state) {
     785                  resultData.href = 'mailto:' + href;
     786                }
     787                insertLink(resultData);
     788              }
     789            );
     790            return;
     791          }
     792
     793          // Is not protocol prefixed
     794          if ((assumeExternalTargets === true && !/^\w+:/i.test(href)) ||
     795            (assumeExternalTargets === false && /^\s*www[\.|\d\.]/i.test(href))) {
     796            delayedConfirm(
     797              editor,
     798              'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
     799              function (state) {
     800                if (state) {
     801                  resultData.href = 'http://' + href;
     802                }
     803                insertLink(resultData);
     804              }
     805            );
     806            return;
     807          }
     808
     809          insertLink(resultData);
     810        }
     811      });
     812    };
     813
     814    var open = function (editor) {
     815      createLinkList(editor, showDialog);
     816    };
     817
     818    return {
     819      open: open
     820    };
     821  }
     822);
     823/**
     824 * ResolveGlobal.js
     825 *
     826 * Released under LGPL License.
     827 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     828 *
     829 * License: http://www.tinymce.com/license
     830 * Contributing: http://www.tinymce.com/contributing
     831 */
     832
     833define(
     834  'tinymce.core.dom.DOMUtils',
     835  [
     836    'global!tinymce.util.Tools.resolve'
     837  ],
     838  function (resolve) {
     839    return resolve('tinymce.dom.DOMUtils');
     840  }
     841);
     842
     843/**
     844 * ResolveGlobal.js
     845 *
     846 * Released under LGPL License.
     847 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     848 *
     849 * License: http://www.tinymce.com/license
     850 * Contributing: http://www.tinymce.com/contributing
     851 */
     852
     853define(
     854  'tinymce.core.Env',
     855  [
     856    'global!tinymce.util.Tools.resolve'
     857  ],
     858  function (resolve) {
     859    return resolve('tinymce.Env');
     860  }
     861);
     862
     863/**
     864 * OpenUrl.js
     865 *
     866 * Released under LGPL License.
     867 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     868 *
     869 * License: http://www.tinymce.com/license
     870 * Contributing: http://www.tinymce.com/contributing
     871 */
     872
     873define(
     874  'tinymce.plugins.link.core.OpenUrl',
     875  [
     876    'tinymce.core.dom.DOMUtils',
     877    'tinymce.core.Env'
     878  ],
     879  function (DOMUtils, Env) {
     880    var appendClickRemove = function (link, evt) {
     881      document.body.appendChild(link);
     882      link.dispatchEvent(evt);
     883      document.body.removeChild(link);
     884    };
     885
     886    var open = function (url) {
     887      // Chrome and Webkit has implemented noopener and works correctly with/without popup blocker
     888      // Firefox has it implemented noopener but when the popup blocker is activated it doesn't work
     889      // Edge has only implemented noreferrer and it seems to remove opener as well
     890      // Older IE versions pre IE 11 falls back to a window.open approach
     891      if (!Env.ie || Env.ie > 10) {
     892        var link = document.createElement('a');
     893        link.target = '_blank';
     894        link.href = url;
     895        link.rel = 'noreferrer noopener';
     896
     897        var evt = document.createEvent('MouseEvents');
     898        evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
     899
     900        appendClickRemove(link, evt);
     901      } else {
     902        var win = window.open('', '_blank');
     903        if (win) {
     904          win.opener = null;
     905          var doc = win.document;
     906          doc.open();
     907          doc.write('<meta http-equiv="refresh" content="0; url=' + DOMUtils.DOM.encode(url) + '">');
     908          doc.close();
     909        }
     910      }
     911    };
     912
     913    return {
     914      open: open
     915    };
     916  }
     917);
     918/**
     919 * Actions.js
     920 *
     921 * Released under LGPL License.
     922 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     923 *
     924 * License: http://www.tinymce.com/license
     925 * Contributing: http://www.tinymce.com/contributing
     926 */
     927
     928define(
     929  'tinymce.plugins.link.core.Actions',
     930  [
     931    'tinymce.core.util.VK',
     932    'tinymce.plugins.link.ui.Dialog',
     933    'tinymce.plugins.link.core.OpenUrl',
     934    'tinymce.plugins.link.core.Utils',
     935    'tinymce.plugins.link.core.Settings'
     936  ],
     937  function (VK, Dialog, OpenUrl, Utils, Settings) {
     938    var getLink = function (editor, elm) {
     939      return editor.dom.getParent(elm, 'a[href]');
     940    };
     941
     942    var getSelectedLink = function (editor) {
     943      return getLink(editor, editor.selection.getStart());
     944    };
     945
     946    var getHref = function (elm) {
     947      // Returns the real href value not the resolved a.href value
     948      var href = elm.getAttribute('data-mce-href');
     949      return href ? href : elm.getAttribute('href');
     950    };
     951
     952    var isContextMenuVisible = function (editor) {
     953      var contextmenu = editor.plugins.contextmenu;
     954      return contextmenu ? contextmenu.isContextMenuVisible() : false;
     955    };
     956
     957    var hasOnlyAltModifier = function (e) {
     958      return e.altKey === true && e.shiftKey === false && e.ctrlKey === false && e.metaKey === false;
     959    };
     960
     961    var gotoLink = function (editor, a) {
     962      if (a) {
     963        var href = getHref(a);
     964        if (/^#/.test(href)) {
     965          var targetEl = editor.$(href);
     966          if (targetEl.length) {
     967            editor.selection.scrollIntoView(targetEl[0], true);
     968          }
     969        } else {
     970          OpenUrl.open(a.href);
     971        }
     972      }
     973    };
     974
     975    var openDialog = function (editor) {
     976      return function () {
     977        Dialog.open(editor);
     978      };
     979    };
     980
     981    var gotoSelectedLink = function (editor) {
     982      return function () {
     983        gotoLink(editor, getSelectedLink(editor));
     984      };
     985    };
     986
     987    var leftClickedOnAHref = function (editor) {
     988      return function (elm) {
     989        var sel, rng, node;
     990        if (Settings.hasContextToolbar(editor.settings) && !isContextMenuVisible(editor) && Utils.isLink(elm)) {
     991          sel = editor.selection;
     992          rng = sel.getRng();
     993          node = rng.startContainer;
     994          // ignore cursor positions at the beginning/end (to make context toolbar less noisy)
     995          if (node.nodeType == 3 && sel.isCollapsed() && rng.startOffset > 0 && rng.startOffset < node.data.length) {
     996            return true;
     997          }
     998        }
     999        return false;
     1000      };
     1001    };
     1002
     1003    var setupGotoLinks = function (editor) {
     1004      editor.on('click', function (e) {
     1005        var link = getLink(editor, e.target);
     1006        if (link && VK.metaKeyPressed(e)) {
     1007          e.preventDefault();
     1008          gotoLink(editor, link);
     1009        }
     1010      });
     1011
     1012      editor.on('keydown', function (e) {
     1013        var link = getSelectedLink(editor);
     1014        if (link && e.keyCode === 13 && hasOnlyAltModifier(e)) {
     1015          e.preventDefault();
     1016          gotoLink(editor, link);
     1017        }
     1018      });
     1019    };
     1020
     1021    var toggleActiveState = function (editor) {
     1022      return function () {
     1023        var self = this;
     1024        editor.on('nodechange', function (e) {
     1025          self.active(!editor.readonly && !!Utils.getAnchorElement(editor, e.element));
     1026        });
     1027      };
     1028    };
     1029
     1030    var toggleViewLinkState = function (editor) {
     1031      return function () {
     1032        var self = this;
     1033
     1034        var toggleVisibility = function (e) {
     1035          if (Utils.hasLinks(e.parents)) {
     1036            self.show();
     1037          } else {
     1038            self.hide();
     1039          }
     1040        };
     1041
     1042        if (!Utils.hasLinks(editor.dom.getParents(editor.selection.getStart()))) {
     1043          self.hide();
     1044        }
     1045
     1046        editor.on('nodechange', toggleVisibility);
     1047
     1048        self.on('remove', function () {
     1049          editor.off('nodechange', toggleVisibility);
     1050        });
     1051      };
     1052    };
     1053
     1054    return {
     1055      openDialog: openDialog,
     1056      gotoSelectedLink: gotoSelectedLink,
     1057      leftClickedOnAHref: leftClickedOnAHref,
     1058      setupGotoLinks: setupGotoLinks,
     1059      toggleActiveState: toggleActiveState,
     1060      toggleViewLinkState: toggleViewLinkState
     1061    };
     1062  }
     1063);
     1064/**
     1065 * Controls.js
     1066 *
     1067 * Released under LGPL License.
     1068 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     1069 *
     1070 * License: http://www.tinymce.com/license
     1071 * Contributing: http://www.tinymce.com/contributing
     1072 */
     1073
     1074define(
     1075  'tinymce.plugins.link.ui.Controls',
     1076  [
     1077    'tinymce.plugins.link.core.Actions',
     1078    'tinymce.plugins.link.core.Utils'
     1079  ],
     1080  function (Actions, Utils) {
     1081
     1082    var setupButtons = function (editor) {
     1083      editor.addButton('link', {
     1084        icon: 'link',
     1085        tooltip: 'Insert/edit link',
     1086        shortcut: 'Meta+K',
     1087        onclick: Actions.openDialog(editor),
     1088        onpostrender: Actions.toggleActiveState(editor)
     1089      });
     1090
     1091      editor.addButton('unlink', {
     1092        icon: 'unlink',
     1093        tooltip: 'Remove link',
     1094        onclick: Utils.unlink(editor),
     1095        onpostrender: Actions.toggleActiveState(editor)
     1096      });
     1097
     1098      if (editor.addContextToolbar) {
     1099        editor.addButton('openlink', {
     1100          icon: 'newtab',
     1101          tooltip: 'Open link',
     1102          onclick: Actions.gotoSelectedLink(editor)
     1103        });
     1104      }
     1105    };
     1106
     1107    var setupMenuItems = function (editor) {
     1108      editor.addMenuItem('openlink', {
     1109        text: 'Open link',
     1110        icon: 'newtab',
     1111        onclick: Actions.gotoSelectedLink(editor),
     1112        onPostRender: Actions.toggleViewLinkState(editor),
     1113        prependToContext: true
     1114      });
     1115
     1116      editor.addMenuItem('link', {
     1117        icon: 'link',
     1118        text: 'Link',
     1119        shortcut: 'Meta+K',
     1120        onclick: Actions.openDialog(editor),
     1121        stateSelector: 'a[href]',
     1122        context: 'insert',
     1123        prependToContext: true
     1124      });
     1125    };
     1126
     1127    var setupContextToolbars = function (editor) {
     1128      if (editor.addContextToolbar) {
     1129        editor.addContextToolbar(
     1130          Actions.leftClickedOnAHref(editor),
     1131          'openlink | link unlink'
     1132        );
     1133      }
     1134    };
     1135
     1136    return {
     1137      setupButtons: setupButtons,
     1138      setupMenuItems: setupMenuItems,
     1139      setupContextToolbars: setupContextToolbars
     1140    };
     1141  }
     1142);
     1143/**
     1144 * Plugin.js
     1145 *
     1146 * Released under LGPL License.
     1147 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     1148 *
     1149 * License: http://www.tinymce.com/license
     1150 * Contributing: http://www.tinymce.com/contributing
     1151 */
     1152
     1153define(
     1154  'tinymce.plugins.link.Plugin',
     1155  [
     1156    'tinymce.core.PluginManager',
     1157    'tinymce.plugins.link.core.Actions',
     1158    'tinymce.plugins.link.ui.Controls'
     1159  ],
     1160  function (PluginManager, Actions, Controls) {
     1161    PluginManager.add('link', function (editor) {
     1162      Controls.setupButtons(editor);
     1163      Controls.setupMenuItems(editor);
     1164      Controls.setupContextToolbars(editor);
     1165      Actions.setupGotoLinks(editor);
     1166      editor.addShortcut('Meta+K', '', Actions.openDialog(editor));
     1167      editor.addCommand('mceLink', Actions.openDialog(editor));
     1168    });
     1169
     1170    return function () { };
     1171  }
     1172);
     1173dem('tinymce.plugins.link.Plugin')();
     1174})();
  • wp-includes/js/tinymce/plugins/link/plugin.min.js

     
     1!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("4",tinymce.util.Tools.resolve),g("1",["4"],function(a){return a("tinymce.PluginManager")}),g("5",["4"],function(a){return a("tinymce.util.VK")}),g("a",["4"],function(a){return a("tinymce.util.Delay")}),g("b",["4"],function(a){return a("tinymce.util.Tools")}),g("c",["4"],function(a){return a("tinymce.util.XHR")}),g("9",[],function(){var a=function(a){return"boolean"==typeof a.link_assume_external_targets&&a.link_assume_external_targets},b=function(a){return"boolean"==typeof a.link_context_toolbar&&a.link_context_toolbar},c=function(a){return a.link_list},d=function(a){return"string"==typeof a.default_link_target},e=function(a){return a.default_link_target},f=function(a){return a.target_list},g=function(a,b){a.settings.target_list=b},h=function(a){return f(a)!==!1},i=function(a){return a.rel_list},j=function(a){return void 0!==i(a)},k=function(a){return a.link_class_list},l=function(a){return void 0!==k(a)},m=function(a){return a.link_title!==!1},n=function(a){return"boolean"==typeof a.allow_unsafe_link_target&&a.allow_unsafe_link_target};return{assumeExternalTargets:a,hasContextToolbar:b,getLinkList:c,hasDefaultLinkTarget:d,getDefaultLinkTarget:e,getTargetList:f,setTargetList:g,shouldShowTargetList:h,getRelList:i,hasRelList:j,getLinkClassList:k,hasLinkClassList:l,shouldShowLinkTitle:m,allowUnsafeLinkTarget:n}}),h("d",RegExp),g("8",["b","9","d"],function(a,b,c){var d=function(b,c){var d=["noopener"],e=b?b.split(/\s+/):[],f=function(b){return a.trim(b.sort().join(" "))},g=function(a){return a=h(a),a.length?a.concat(d):d},h=function(b){return b.filter(function(b){return a.inArray(d,b)===-1})};return e=c?g(e):h(e),e.length?f(e):null},e=function(a){return a.replace(/\uFEFF/g,"")},f=function(a,b){return b=b||a.selection.getStart(),k(b)?a.dom.select("a[href]",b)[0]:a.dom.getParent(b,"a[href]")},g=function(a,b){var c=b?b.innerText||b.textContent:a.getContent({format:"text"});return e(c)},h=function(a){return a&&"A"===a.nodeName&&a.href},i=function(b){return a.grep(b,h).length>0},j=function(a){return!(/</.test(a)&&(!/^<a [^>]+>[^<]+<\/a>$/.test(a)||a.indexOf("href=")==-1))},k=function(a){return a&&"FIGURE"===a.nodeName&&/\bimage\b/i.test(a.className)},l=function(a,c){return function(e){a.undoManager.transact(function(){var g=a.selection.getNode(),h=f(a,g),i={href:e.href,target:e.target?e.target:null,rel:e.rel?e.rel:null,"class":e["class"]?e["class"]:null,title:e.title?e.title:null};b.hasRelList(a.settings)||b.allowUnsafeLinkTarget(a.settings)!==!1||(i.rel=d(i.rel,"_blank"==i.target)),e.href===c.href&&(c.attach(),c={}),h?(a.focus(),e.hasOwnProperty("text")&&("innerText"in h?h.innerText=e.text:h.textContent=e.text),a.dom.setAttribs(h,i),a.selection.select(h),a.undoManager.add()):k(g)?o(a,g,i):e.hasOwnProperty("text")?a.insertContent(a.dom.createHTML("a",i,a.dom.encode(e.text))):a.execCommand("mceInsertLink",!1,i)})}},m=function(a){return function(){a.undoManager.transact(function(){var b=a.selection.getNode();k(b)?n(a,b):a.execCommand("unlink")})}},n=function(a,b){var c,d;d=a.dom.select("img",b)[0],d&&(c=a.dom.getParents(d,"a[href]",b)[0],c&&(c.parentNode.insertBefore(d,c),a.dom.remove(c)))},o=function(a,b,c){var d,e;e=a.dom.select("img",b)[0],e&&(d=a.dom.create("a",c),e.parentNode.insertBefore(d,e),d.appendChild(e))};return{link:l,unlink:m,isLink:h,hasLinks:i,isOnlyTextSelected:j,getAnchorElement:f,getAnchorText:g,toggleTargetRules:d}}),g("6",["a","b","c","8","9"],function(a,b,c,d,e){var f={},g=function(a,b){var d=e.getLinkList(a.settings);"string"==typeof d?c.send({url:d,success:function(c){b(a,JSON.parse(c))}}):"function"==typeof d?d(function(c){b(a,c)}):b(a,d)},h=function(a,c,d){var e=function(a,d){return d=d||[],b.each(a,function(a){var b={text:a.text||a.title};a.menu?b.menu=e(a.menu):(b.value=a.value,c&&c(b)),d.push(b)}),d};return e(a,d||[])},i=function(b,c,d){var e=b.selection.getRng();a.setEditorTimeout(b,function(){b.windowManager.confirm(c,function(a){b.selection.setRng(e),d(a)})})},j=function(a,c){var g,j,k,l,m,n,o,p,q,r,s,t={},u=a.selection,v=a.dom,w=function(a){var b=k.find("#text");(!b.value()||a.lastControl&&b.value()==a.lastControl.text())&&b.value(a.control.text()),k.find("#href").value(a.control.value())},x=function(c){var d=[];if(b.each(a.dom.select("a:not([href])"),function(a){var b=a.name||a.id;b&&d.push({text:b,value:"#"+b,selected:c.indexOf("#"+b)!=-1})}),d.length)return d.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:d,onselect:w}},y=function(){j||!l||t.text||this.parent().parent().find("#text")[0].value(this.value())},z=function(c){var d=c.meta||{};n&&n.value(a.convertURL(this.value(),"href")),b.each(c.meta,function(a,b){var c=k.find("#"+b);"text"===b?0===j.length&&(c.value(a),t.text=a):c.value(a)}),d.attach&&(f={href:this.value(),attach:d.attach}),d.text||y.call(this)},A=function(a){a.meta=k.toJSON()};l=d.isOnlyTextSelected(u.getContent()),g=d.getAnchorElement(a),t.text=j=d.getAnchorText(a.selection,g),t.href=g?v.getAttrib(g,"href"):"",g?t.target=v.getAttrib(g,"target"):e.hasDefaultLinkTarget(a.settings)&&(t.target=e.getDefaultLinkTarget(a.settings)),(s=v.getAttrib(g,"rel"))&&(t.rel=s),(s=v.getAttrib(g,"class"))&&(t["class"]=s),(s=v.getAttrib(g,"title"))&&(t.title=s),l&&(m={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){t.text=this.value()}}),c&&(n={type:"listbox",label:"Link list",values:h(c,function(b){b.value=a.convertURL(b.value||b.url,"href")},[{text:"None",value:""}]),onselect:w,value:a.convertURL(t.href,"href"),onPostRender:function(){n=this}}),e.shouldShowTargetList(a.settings)&&(void 0===e.getTargetList(a.settings)&&e.setTargetList(a,[{text:"None",value:""},{text:"New window",value:"_blank"}]),p={name:"target",type:"listbox",label:"Target",values:h(e.getTargetList(a.settings))}),e.hasRelList(a.settings)&&(o={name:"rel",type:"listbox",label:"Rel",values:h(e.getRelList(a.settings),function(b){e.allowUnsafeLinkTarget(a.settings)===!1&&(b.value=d.toggleTargetRules(b.value,"_blank"===t.target))})}),e.hasLinkClassList(a.settings)&&(q={name:"class",type:"listbox",label:"Class",values:h(e.getLinkClassList(a.settings),function(b){b.value&&(b.textStyle=function(){return a.formatter.getCssText({inline:"a",classes:[b.value]})})})}),e.shouldShowLinkTitle(a.settings)&&(r={name:"title",type:"textbox",label:"Title",value:t.title}),k=a.windowManager.open({title:"Insert link",data:t,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:z,onkeyup:y,onbeforecall:A},m,r,x(t.href),n,o,p,q],onSubmit:function(c){var g=e.assumeExternalTargets(a.settings),h=d.link(a,f),k=d.unlink(a),m=b.extend({},t,c.data),n=m.href;return n?(l&&m.text!==j||delete m.text,n.indexOf("@")>0&&n.indexOf("//")==-1&&n.indexOf("mailto:")==-1?void i(a,"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(a){a&&(m.href="mailto:"+n),h(m)}):g===!0&&!/^\w+:/i.test(n)||g===!1&&/^\s*www[\.|\d\.]/i.test(n)?void i(a,"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(a){a&&(m.href="http://"+n),h(m)}):void h(m)):void k()}})},k=function(a){g(a,j)};return{open:k}}),g("e",["4"],function(a){return a("tinymce.dom.DOMUtils")}),g("f",["4"],function(a){return a("tinymce.Env")}),g("7",["e","f"],function(a,b){var c=function(a,b){document.body.appendChild(a),a.dispatchEvent(b),document.body.removeChild(a)},d=function(d){if(!b.ie||b.ie>10){var e=document.createElement("a");e.target="_blank",e.href=d,e.rel="noreferrer noopener";var f=document.createEvent("MouseEvents");f.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),c(e,f)}else{var g=window.open("","_blank");if(g){g.opener=null;var h=g.document;h.open(),h.write('<meta http-equiv="refresh" content="0; url='+a.DOM.encode(d)+'">'),h.close()}}};return{open:d}}),g("2",["5","6","7","8","9"],function(a,b,c,d,e){var f=function(a,b){return a.dom.getParent(b,"a[href]")},g=function(a){return f(a,a.selection.getStart())},h=function(a){var b=a.getAttribute("data-mce-href");return b?b:a.getAttribute("href")},i=function(a){var b=a.plugins.contextmenu;return!!b&&b.isContextMenuVisible()},j=function(a){return a.altKey===!0&&a.shiftKey===!1&&a.ctrlKey===!1&&a.metaKey===!1},k=function(a,b){if(b){var d=h(b);if(/^#/.test(d)){var e=a.$(d);e.length&&a.selection.scrollIntoView(e[0],!0)}else c.open(b.href)}},l=function(a){return function(){b.open(a)}},m=function(a){return function(){k(a,g(a))}},n=function(a){return function(b){var c,f,g;return!!(e.hasContextToolbar(a.settings)&&!i(a)&&d.isLink(b)&&(c=a.selection,f=c.getRng(),g=f.startContainer,3==g.nodeType&&c.isCollapsed()&&f.startOffset>0&&f.startOffset<g.data.length))}},o=function(b){b.on("click",function(c){var d=f(b,c.target);d&&a.metaKeyPressed(c)&&(c.preventDefault(),k(b,d))}),b.on("keydown",function(a){var c=g(b);c&&13===a.keyCode&&j(a)&&(a.preventDefault(),k(b,c))})},p=function(a){return function(){var b=this;a.on("nodechange",function(c){b.active(!a.readonly&&!!d.getAnchorElement(a,c.element))})}},q=function(a){return function(){var b=this,c=function(a){d.hasLinks(a.parents)?b.show():b.hide()};d.hasLinks(a.dom.getParents(a.selection.getStart()))||b.hide(),a.on("nodechange",c),b.on("remove",function(){a.off("nodechange",c)})}};return{openDialog:l,gotoSelectedLink:m,leftClickedOnAHref:n,setupGotoLinks:o,toggleActiveState:p,toggleViewLinkState:q}}),g("3",["2","8"],function(a,b){var c=function(c){c.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Meta+K",onclick:a.openDialog(c),onpostrender:a.toggleActiveState(c)}),c.addButton("unlink",{icon:"unlink",tooltip:"Remove link",onclick:b.unlink(c),onpostrender:a.toggleActiveState(c)}),c.addContextToolbar&&c.addButton("openlink",{icon:"newtab",tooltip:"Open link",onclick:a.gotoSelectedLink(c)})},d=function(b){b.addMenuItem("openlink",{text:"Open link",icon:"newtab",onclick:a.gotoSelectedLink(b),onPostRender:a.toggleViewLinkState(b),prependToContext:!0}),b.addMenuItem("link",{icon:"link",text:"Link",shortcut:"Meta+K",onclick:a.openDialog(b),stateSelector:"a[href]",context:"insert",prependToContext:!0})},e=function(b){b.addContextToolbar&&b.addContextToolbar(a.leftClickedOnAHref(b),"openlink | link unlink")};return{setupButtons:c,setupMenuItems:d,setupContextToolbars:e}}),g("0",["1","2","3"],function(a,b,c){return a.add("link",function(a){c.setupButtons(a),c.setupMenuItems(a),c.setupContextToolbars(a),b.setupGotoLinks(a),a.addShortcut("Meta+K","",b.openDialog(a)),a.addCommand("mceLink",b.openDialog(a))}),function(){}}),d("0")()}();
     2 No newline at end of file
  • wp-includes/js/tinymce/plugins/link/plugin.js

     
     1(function () {
     2
     3var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)}
     4
     5// Used when there is no 'main' module.
     6// The name is probably (hopefully) unique so minification removes for releases.
     7var register_3795 = function (id) {
     8  var module = dem(id);
     9  var fragments = id.split('.');
     10  var target = Function('return this;')();
     11  for (var i = 0; i < fragments.length - 1; ++i) {
     12    if (target[fragments[i]] === undefined)
     13      target[fragments[i]] = {};
     14    target = target[fragments[i]];
     15  }
     16  target[fragments[fragments.length - 1]] = module;
     17};
     18
     19var instantiate = function (id) {
     20  var actual = defs[id];
     21  var dependencies = actual.deps;
     22  var definition = actual.defn;
     23  var len = dependencies.length;
     24  var instances = new Array(len);
     25  for (var i = 0; i < len; ++i)
     26    instances[i] = dem(dependencies[i]);
     27  var defResult = definition.apply(null, instances);
     28  if (defResult === undefined)
     29     throw 'module [' + id + '] returned undefined';
     30  actual.instance = defResult;
     31};
     32
     33var def = function (id, dependencies, definition) {
     34  if (typeof id !== 'string')
     35    throw 'module id must be a string';
     36  else if (dependencies === undefined)
     37    throw 'no dependencies for ' + id;
     38  else if (definition === undefined)
     39    throw 'no definition function for ' + id;
     40  defs[id] = {
     41    deps: dependencies,
     42    defn: definition,
     43    instance: undefined
     44  };
     45};
     46
     47var dem = function (id) {
     48  var actual = defs[id];
     49  if (actual === undefined)
     50    throw 'module [' + id + '] was undefined';
     51  else if (actual.instance === undefined)
     52    instantiate(id);
     53  return actual.instance;
     54};
     55
     56var req = function (ids, callback) {
     57  var len = ids.length;
     58  var instances = new Array(len);
     59  for (var i = 0; i < len; ++i)
     60    instances.push(dem(ids[i]));
     61  callback.apply(null, callback);
     62};
     63
     64var ephox = {};
     65
     66ephox.bolt = {
     67  module: {
     68    api: {
     69      define: def,
     70      require: req,
     71      demand: dem
     72    }
     73  }
     74};
     75
     76var define = def;
     77var require = req;
     78var demand = dem;
     79// this helps with minificiation when using a lot of global references
     80var defineGlobal = function (id, ref) {
     81  define(id, [], function () { return ref; });
     82};
     83/*jsc
     84["tinymce.plugins.link.Plugin","tinymce.core.PluginManager","tinymce.plugins.link.core.Actions","tinymce.plugins.link.ui.Controls","global!tinymce.util.Tools.resolve","tinymce.core.util.VK","tinymce.plugins.link.ui.Dialog","tinymce.plugins.link.core.OpenUrl","tinymce.plugins.link.core.Utils","tinymce.plugins.link.core.Settings","tinymce.core.util.Delay","tinymce.core.util.Tools","tinymce.core.util.XHR","global!RegExp","tinymce.core.dom.DOMUtils","tinymce.core.Env"]
     85jsc*/
     86defineGlobal("global!tinymce.util.Tools.resolve", tinymce.util.Tools.resolve);
     87/**
     88 * ResolveGlobal.js
     89 *
     90 * Released under LGPL License.
     91 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     92 *
     93 * License: http://www.tinymce.com/license
     94 * Contributing: http://www.tinymce.com/contributing
     95 */
     96
     97define(
     98  'tinymce.core.PluginManager',
     99  [
     100    'global!tinymce.util.Tools.resolve'
     101  ],
     102  function (resolve) {
     103    return resolve('tinymce.PluginManager');
     104  }
     105);
     106
     107/**
     108 * ResolveGlobal.js
     109 *
     110 * Released under LGPL License.
     111 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     112 *
     113 * License: http://www.tinymce.com/license
     114 * Contributing: http://www.tinymce.com/contributing
     115 */
     116
     117define(
     118  'tinymce.core.util.VK',
     119  [
     120    'global!tinymce.util.Tools.resolve'
     121  ],
     122  function (resolve) {
     123    return resolve('tinymce.util.VK');
     124  }
     125);
     126
     127/**
     128 * ResolveGlobal.js
     129 *
     130 * Released under LGPL License.
     131 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     132 *
     133 * License: http://www.tinymce.com/license
     134 * Contributing: http://www.tinymce.com/contributing
     135 */
     136
     137define(
     138  'tinymce.core.util.Delay',
     139  [
     140    'global!tinymce.util.Tools.resolve'
     141  ],
     142  function (resolve) {
     143    return resolve('tinymce.util.Delay');
     144  }
     145);
     146
     147/**
     148 * ResolveGlobal.js
     149 *
     150 * Released under LGPL License.
     151 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     152 *
     153 * License: http://www.tinymce.com/license
     154 * Contributing: http://www.tinymce.com/contributing
     155 */
     156
     157define(
     158  'tinymce.core.util.Tools',
     159  [
     160    'global!tinymce.util.Tools.resolve'
     161  ],
     162  function (resolve) {
     163    return resolve('tinymce.util.Tools');
     164  }
     165);
     166
     167/**
     168 * ResolveGlobal.js
     169 *
     170 * Released under LGPL License.
     171 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     172 *
     173 * License: http://www.tinymce.com/license
     174 * Contributing: http://www.tinymce.com/contributing
     175 */
     176
     177define(
     178  'tinymce.core.util.XHR',
     179  [
     180    'global!tinymce.util.Tools.resolve'
     181  ],
     182  function (resolve) {
     183    return resolve('tinymce.util.XHR');
     184  }
     185);
     186
     187define(
     188  'tinymce.plugins.link.core.Settings',
     189  [
     190
     191  ],
     192  function () {
     193    var assumeExternalTargets = function (editorSettings) {
     194      return typeof editorSettings.link_assume_external_targets === 'boolean' ? editorSettings.link_assume_external_targets : false;
     195    };
     196
     197    var hasContextToolbar = function (editorSettings) {
     198      return typeof editorSettings.link_context_toolbar === 'boolean' ? editorSettings.link_context_toolbar : false;
     199    };
     200
     201    var getLinkList = function (editorSettings) {
     202      return editorSettings.link_list;
     203    };
     204
     205    var hasDefaultLinkTarget = function (editorSettings) {
     206      return typeof editorSettings.default_link_target === 'string';
     207    };
     208
     209    var getDefaultLinkTarget = function (editorSettings) {
     210      return editorSettings.default_link_target;
     211    };
     212
     213    var getTargetList = function (editorSettings) {
     214      return editorSettings.target_list;
     215    };
     216
     217    var setTargetList = function (editor, list) {
     218      editor.settings.target_list = list;
     219    };
     220
     221    var shouldShowTargetList = function (editorSettings) {
     222      return getTargetList(editorSettings) !== false;
     223    };
     224
     225    var getRelList = function (editorSettings) {
     226      return editorSettings.rel_list;
     227    };
     228
     229    var hasRelList = function (editorSettings) {
     230      return getRelList(editorSettings) !== undefined;
     231    };
     232
     233    var getLinkClassList = function (editorSettings) {
     234      return editorSettings.link_class_list;
     235    };
     236
     237    var hasLinkClassList = function (editorSettings) {
     238      return getLinkClassList(editorSettings) !== undefined;
     239    };
     240
     241    var shouldShowLinkTitle = function (editorSettings) {
     242      return editorSettings.link_title !== false;
     243    };
     244
     245    var allowUnsafeLinkTarget = function (editorSettings) {
     246      return typeof editorSettings.allow_unsafe_link_target === 'boolean' ? editorSettings.allow_unsafe_link_target : false;
     247    };
     248
     249    return {
     250      assumeExternalTargets: assumeExternalTargets,
     251      hasContextToolbar: hasContextToolbar,
     252      getLinkList: getLinkList,
     253      hasDefaultLinkTarget: hasDefaultLinkTarget,
     254      getDefaultLinkTarget: getDefaultLinkTarget,
     255      getTargetList: getTargetList,
     256      setTargetList: setTargetList,
     257      shouldShowTargetList: shouldShowTargetList,
     258      getRelList: getRelList,
     259      hasRelList: hasRelList,
     260      getLinkClassList: getLinkClassList,
     261      hasLinkClassList: hasLinkClassList,
     262      shouldShowLinkTitle: shouldShowLinkTitle,
     263      allowUnsafeLinkTarget: allowUnsafeLinkTarget
     264    };
     265  }
     266);
     267
     268defineGlobal("global!RegExp", RegExp);
     269/**
     270 * Utils.js
     271 *
     272 * Released under LGPL License.
     273 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     274 *
     275 * License: http://www.tinymce.com/license
     276 * Contributing: http://www.tinymce.com/contributing
     277 */
     278
     279define(
     280  'tinymce.plugins.link.core.Utils',
     281  [
     282    'tinymce.core.util.Tools',
     283    'tinymce.plugins.link.core.Settings',
     284    'global!RegExp'
     285  ],
     286  function (Tools, Settings, RegExp) {
     287
     288    var toggleTargetRules = function (rel, isUnsafe) {
     289      var rules = ['noopener'];
     290      var newRel = rel ? rel.split(/\s+/) : [];
     291
     292      var toString = function (rel) {
     293        return Tools.trim(rel.sort().join(' '));
     294      };
     295
     296      var addTargetRules = function (rel) {
     297        rel = removeTargetRules(rel);
     298        return rel.length ? rel.concat(rules) : rules;
     299      };
     300
     301      var removeTargetRules = function (rel) {
     302        return rel.filter(function (val) {
     303          return Tools.inArray(rules, val) === -1;
     304        });
     305      };
     306
     307      newRel = isUnsafe ? addTargetRules(newRel) : removeTargetRules(newRel);
     308      return newRel.length ? toString(newRel) : null;
     309    };
     310
     311
     312    var trimCaretContainers = function (text) {
     313      return text.replace(/\uFEFF/g, '');
     314    };
     315
     316
     317    var getAnchorElement = function (editor, selectedElm) {
     318      selectedElm = selectedElm || editor.selection.getStart();
     319      if (isImageFigure(selectedElm)) {
     320        // for an image conained in a figure we look for a link inside the selected element
     321        return editor.dom.select('a[href]', selectedElm)[0];
     322      } else {
     323        return editor.dom.getParent(selectedElm, 'a[href]');
     324      }
     325    };
     326
     327
     328    var getAnchorText = function (selection, anchorElm) {
     329      var text = anchorElm ? (anchorElm.innerText || anchorElm.textContent) : selection.getContent({ format: 'text' });
     330      return trimCaretContainers(text);
     331    };
     332
     333
     334    var isLink = function (elm) {
     335      return elm && elm.nodeName === 'A' && elm.href;
     336    };
     337
     338    var hasLinks = function (elements) {
     339      return Tools.grep(elements, isLink).length > 0;
     340    };
     341
     342
     343    var isOnlyTextSelected = function (html) {
     344      // Partial html and not a fully selected anchor element
     345      if (/</.test(html) && (!/^<a [^>]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') == -1)) {
     346        return false;
     347      }
     348
     349      return true;
     350    };
     351
     352
     353    var isImageFigure = function (node) {
     354      return node && node.nodeName === 'FIGURE' && /\bimage\b/i.test(node.className);
     355    };
     356
     357
     358    var link = function (editor, attachState) {
     359      return function (data) {
     360        editor.undoManager.transact(function () {
     361          var selectedElm = editor.selection.getNode();
     362          var anchorElm = getAnchorElement(editor, selectedElm);
     363
     364          var linkAttrs = {
     365            href: data.href,
     366            target: data.target ? data.target : null,
     367            rel: data.rel ? data.rel : null,
     368            "class": data["class"] ? data["class"] : null,
     369            title: data.title ? data.title : null
     370          };
     371
     372          if (!Settings.hasRelList(editor.settings) && Settings.allowUnsafeLinkTarget(editor.settings) === false) {
     373            linkAttrs.rel = toggleTargetRules(linkAttrs.rel, linkAttrs.target == '_blank');
     374          }
     375
     376          if (data.href === attachState.href) {
     377            attachState.attach();
     378            attachState = {};
     379          }
     380
     381          if (anchorElm) {
     382            editor.focus();
     383
     384            if (data.hasOwnProperty('text')) {
     385              if ("innerText" in anchorElm) {
     386                anchorElm.innerText = data.text;
     387              } else {
     388                anchorElm.textContent = data.text;
     389              }
     390            }
     391
     392            editor.dom.setAttribs(anchorElm, linkAttrs);
     393
     394            editor.selection.select(anchorElm);
     395            editor.undoManager.add();
     396          } else {
     397            if (isImageFigure(selectedElm)) {
     398              linkImageFigure(editor, selectedElm, linkAttrs);
     399            } else if (data.hasOwnProperty('text')) {
     400              editor.insertContent(editor.dom.createHTML('a', linkAttrs, editor.dom.encode(data.text)));
     401            } else {
     402              editor.execCommand('mceInsertLink', false, linkAttrs);
     403            }
     404          }
     405        });
     406      };
     407    };
     408
     409
     410    var unlink = function (editor) {
     411      return function () {
     412        editor.undoManager.transact(function () {
     413          var node = editor.selection.getNode();
     414          if (isImageFigure(node)) {
     415            unlinkImageFigure(editor, node);
     416          } else {
     417            editor.execCommand('unlink');
     418          }
     419        });
     420      };
     421    };
     422
     423
     424    var unlinkImageFigure = function (editor, fig) {
     425      var a, img;
     426      img = editor.dom.select('img', fig)[0];
     427      if (img) {
     428        a = editor.dom.getParents(img, 'a[href]', fig)[0];
     429        if (a) {
     430          a.parentNode.insertBefore(img, a);
     431          editor.dom.remove(a);
     432        }
     433      }
     434    };
     435
     436
     437    var linkImageFigure = function (editor, fig, attrs) {
     438      var a, img;
     439      img = editor.dom.select('img', fig)[0];
     440      if (img) {
     441        a = editor.dom.create('a', attrs);
     442        img.parentNode.insertBefore(a, img);
     443        a.appendChild(img);
     444      }
     445    };
     446
     447    return {
     448      link: link,
     449      unlink: unlink,
     450      isLink: isLink,
     451      hasLinks: hasLinks,
     452      isOnlyTextSelected: isOnlyTextSelected,
     453      getAnchorElement: getAnchorElement,
     454      getAnchorText: getAnchorText,
     455      toggleTargetRules: toggleTargetRules
     456    };
     457  }
     458);
     459/**
     460 * Dialog.js
     461 *
     462 * Released under LGPL License.
     463 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     464 *
     465 * License: http://www.tinymce.com/license
     466 * Contributing: http://www.tinymce.com/contributing
     467 */
     468
     469define(
     470  'tinymce.plugins.link.ui.Dialog',
     471  [
     472    'tinymce.core.util.Delay',
     473    'tinymce.core.util.Tools',
     474    'tinymce.core.util.XHR',
     475    'tinymce.plugins.link.core.Utils',
     476    'tinymce.plugins.link.core.Settings'
     477  ],
     478  function (Delay, Tools, XHR, Utils, Settings) {
     479    var attachState = {};
     480
     481    var createLinkList = function (editor, callback) {
     482      var linkList = Settings.getLinkList(editor.settings);
     483
     484      if (typeof linkList == "string") {
     485        XHR.send({
     486          url: linkList,
     487          success: function (text) {
     488            callback(editor, JSON.parse(text));
     489          }
     490        });
     491      } else if (typeof linkList == "function") {
     492        linkList(function (list) {
     493          callback(editor, list);
     494        });
     495      } else {
     496        callback(editor, linkList);
     497      }
     498    };
     499
     500    var buildListItems = function (inputList, itemCallback, startItems) {
     501      var appendItems = function (values, output) {
     502        output = output || [];
     503
     504        Tools.each(values, function (item) {
     505          var menuItem = { text: item.text || item.title };
     506
     507          if (item.menu) {
     508            menuItem.menu = appendItems(item.menu);
     509          } else {
     510            menuItem.value = item.value;
     511
     512            if (itemCallback) {
     513              itemCallback(menuItem);
     514            }
     515          }
     516
     517          output.push(menuItem);
     518        });
     519
     520        return output;
     521      };
     522
     523      return appendItems(inputList, startItems || []);
     524    };
     525
     526    // Delay confirm since onSubmit will move focus
     527    var delayedConfirm = function (editor, message, callback) {
     528      var rng = editor.selection.getRng();
     529
     530      Delay.setEditorTimeout(editor, function () {
     531        editor.windowManager.confirm(message, function (state) {
     532          editor.selection.setRng(rng);
     533          callback(state);
     534        });
     535      });
     536    };
     537
     538    var showDialog = function (editor, linkList) {
     539      var data = {}, selection = editor.selection, dom = editor.dom, anchorElm, initialText;
     540      var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value;
     541
     542      var linkListChangeHandler = function (e) {
     543        var textCtrl = win.find('#text');
     544
     545        if (!textCtrl.value() || (e.lastControl && textCtrl.value() == e.lastControl.text())) {
     546          textCtrl.value(e.control.text());
     547        }
     548
     549        win.find('#href').value(e.control.value());
     550      };
     551
     552      var buildAnchorListControl = function (url) {
     553        var anchorList = [];
     554
     555        Tools.each(editor.dom.select('a:not([href])'), function (anchor) {
     556          var id = anchor.name || anchor.id;
     557
     558          if (id) {
     559            anchorList.push({
     560              text: id,
     561              value: '#' + id,
     562              selected: url.indexOf('#' + id) != -1
     563            });
     564          }
     565        });
     566
     567        if (anchorList.length) {
     568          anchorList.unshift({ text: 'None', value: '' });
     569
     570          return {
     571            name: 'anchor',
     572            type: 'listbox',
     573            label: 'Anchors',
     574            values: anchorList,
     575            onselect: linkListChangeHandler
     576          };
     577        }
     578      };
     579
     580      var updateText = function () {
     581        if (!initialText && onlyText && !data.text) {
     582          this.parent().parent().find('#text')[0].value(this.value());
     583        }
     584      };
     585
     586      var urlChange = function (e) {
     587        var meta = e.meta || {};
     588
     589        if (linkListCtrl) {
     590          linkListCtrl.value(editor.convertURL(this.value(), 'href'));
     591        }
     592
     593        Tools.each(e.meta, function (value, key) {
     594          var inp = win.find('#' + key);
     595
     596          if (key === 'text') {
     597            if (initialText.length === 0) {
     598              inp.value(value);
     599              data.text = value;
     600            }
     601          } else {
     602            inp.value(value);
     603          }
     604        });
     605
     606        if (meta.attach) {
     607          attachState = {
     608            href: this.value(),
     609            attach: meta.attach
     610          };
     611        }
     612
     613        if (!meta.text) {
     614          updateText.call(this);
     615        }
     616      };
     617
     618      var onBeforeCall = function (e) {
     619        e.meta = win.toJSON();
     620      };
     621
     622      onlyText = Utils.isOnlyTextSelected(selection.getContent());
     623      anchorElm = Utils.getAnchorElement(editor);
     624
     625      data.text = initialText = Utils.getAnchorText(editor.selection, anchorElm);
     626      data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : '';
     627
     628      if (anchorElm) {
     629        data.target = dom.getAttrib(anchorElm, 'target');
     630      } else if (Settings.hasDefaultLinkTarget(editor.settings)) {
     631        data.target = Settings.getDefaultLinkTarget(editor.settings);
     632      }
     633
     634      if ((value = dom.getAttrib(anchorElm, 'rel'))) {
     635        data.rel = value;
     636      }
     637
     638      if ((value = dom.getAttrib(anchorElm, 'class'))) {
     639        data['class'] = value;
     640      }
     641
     642      if ((value = dom.getAttrib(anchorElm, 'title'))) {
     643        data.title = value;
     644      }
     645
     646      if (onlyText) {
     647        textListCtrl = {
     648          name: 'text',
     649          type: 'textbox',
     650          size: 40,
     651          label: 'Text to display',
     652          onchange: function () {
     653            data.text = this.value();
     654          }
     655        };
     656      }
     657
     658      if (linkList) {
     659        linkListCtrl = {
     660          type: 'listbox',
     661          label: 'Link list',
     662          values: buildListItems(
     663            linkList,
     664            function (item) {
     665              item.value = editor.convertURL(item.value || item.url, 'href');
     666            },
     667            [{ text: 'None', value: '' }]
     668          ),
     669          onselect: linkListChangeHandler,
     670          value: editor.convertURL(data.href, 'href'),
     671          onPostRender: function () {
     672            /*eslint consistent-this:0*/
     673            linkListCtrl = this;
     674          }
     675        };
     676      }
     677
     678      if (Settings.shouldShowTargetList(editor.settings)) {
     679        if (Settings.getTargetList(editor.settings) === undefined) {
     680          Settings.setTargetList(editor, [
     681            { text: 'None', value: '' },
     682            { text: 'New window', value: '_blank' }
     683          ]);
     684        }
     685
     686        targetListCtrl = {
     687          name: 'target',
     688          type: 'listbox',
     689          label: 'Target',
     690          values: buildListItems(Settings.getTargetList(editor.settings))
     691        };
     692      }
     693
     694      if (Settings.hasRelList(editor.settings)) {
     695        relListCtrl = {
     696          name: 'rel',
     697          type: 'listbox',
     698          label: 'Rel',
     699          values: buildListItems(
     700            Settings.getRelList(editor.settings),
     701            function (item) {
     702              if (Settings.allowUnsafeLinkTarget(editor.settings) === false) {
     703                item.value = Utils.toggleTargetRules(item.value, data.target === '_blank');
     704              }
     705            }
     706          )
     707        };
     708      }
     709
     710      if (Settings.hasLinkClassList(editor.settings)) {
     711        classListCtrl = {
     712          name: 'class',
     713          type: 'listbox',
     714          label: 'Class',
     715          values: buildListItems(
     716            Settings.getLinkClassList(editor.settings),
     717            function (item) {
     718              if (item.value) {
     719                item.textStyle = function () {
     720                  return editor.formatter.getCssText({ inline: 'a', classes: [item.value] });
     721                };
     722              }
     723            }
     724          )
     725        };
     726      }
     727
     728      if (Settings.shouldShowLinkTitle(editor.settings)) {
     729        linkTitleCtrl = {
     730          name: 'title',
     731          type: 'textbox',
     732          label: 'Title',
     733          value: data.title
     734        };
     735      }
     736
     737      win = editor.windowManager.open({
     738        title: 'Insert link',
     739        data: data,
     740        body: [
     741          {
     742            name: 'href',
     743            type: 'filepicker',
     744            filetype: 'file',
     745            size: 40,
     746            autofocus: true,
     747            label: 'Url',
     748            onchange: urlChange,
     749            onkeyup: updateText,
     750            onbeforecall: onBeforeCall
     751          },
     752          textListCtrl,
     753          linkTitleCtrl,
     754          buildAnchorListControl(data.href),
     755          linkListCtrl,
     756          relListCtrl,
     757          targetListCtrl,
     758          classListCtrl
     759        ],
     760        onSubmit: function (e) {
     761          var assumeExternalTargets = Settings.assumeExternalTargets(editor.settings);
     762          var insertLink = Utils.link(editor, attachState);
     763          var removeLink = Utils.unlink(editor);
     764
     765          var resultData = Tools.extend({}, data, e.data);
     766          /*eslint dot-notation: 0*/
     767          var href = resultData.href;
     768
     769          if (!href) {
     770            removeLink();
     771            return;
     772          }
     773
     774          if (!onlyText || resultData.text === initialText) {
     775            delete resultData.text;
     776          }
     777
     778          // Is email and not //user@domain.com
     779          if (href.indexOf('@') > 0 && href.indexOf('//') == -1 && href.indexOf('mailto:') == -1) {
     780            delayedConfirm(
     781              editor,
     782              'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?',
     783              function (state) {
     784                if (state) {
     785                  resultData.href = 'mailto:' + href;
     786                }
     787                insertLink(resultData);
     788              }
     789            );
     790            return;
     791          }
     792
     793          // Is not protocol prefixed
     794          if ((assumeExternalTargets === true && !/^\w+:/i.test(href)) ||
     795            (assumeExternalTargets === false && /^\s*www[\.|\d\.]/i.test(href))) {
     796            delayedConfirm(
     797              editor,
     798              'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?',
     799              function (state) {
     800                if (state) {
     801                  resultData.href = 'http://' + href;
     802                }
     803                insertLink(resultData);
     804              }
     805            );
     806            return;
     807          }
     808
     809          insertLink(resultData);
     810        }
     811      });
     812    };
     813
     814    var open = function (editor) {
     815      createLinkList(editor, showDialog);
     816    };
     817
     818    return {
     819      open: open
     820    };
     821  }
     822);
     823/**
     824 * ResolveGlobal.js
     825 *
     826 * Released under LGPL License.
     827 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     828 *
     829 * License: http://www.tinymce.com/license
     830 * Contributing: http://www.tinymce.com/contributing
     831 */
     832
     833define(
     834  'tinymce.core.dom.DOMUtils',
     835  [
     836    'global!tinymce.util.Tools.resolve'
     837  ],
     838  function (resolve) {
     839    return resolve('tinymce.dom.DOMUtils');
     840  }
     841);
     842
     843/**
     844 * ResolveGlobal.js
     845 *
     846 * Released under LGPL License.
     847 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     848 *
     849 * License: http://www.tinymce.com/license
     850 * Contributing: http://www.tinymce.com/contributing
     851 */
     852
     853define(
     854  'tinymce.core.Env',
     855  [
     856    'global!tinymce.util.Tools.resolve'
     857  ],
     858  function (resolve) {
     859    return resolve('tinymce.Env');
     860  }
     861);
     862
     863/**
     864 * OpenUrl.js
     865 *
     866 * Released under LGPL License.
     867 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     868 *
     869 * License: http://www.tinymce.com/license
     870 * Contributing: http://www.tinymce.com/contributing
     871 */
     872
     873define(
     874  'tinymce.plugins.link.core.OpenUrl',
     875  [
     876    'tinymce.core.dom.DOMUtils',
     877    'tinymce.core.Env'
     878  ],
     879  function (DOMUtils, Env) {
     880    var appendClickRemove = function (link, evt) {
     881      document.body.appendChild(link);
     882      link.dispatchEvent(evt);
     883      document.body.removeChild(link);
     884    };
     885
     886    var open = function (url) {
     887      // Chrome and Webkit has implemented noopener and works correctly with/without popup blocker
     888      // Firefox has it implemented noopener but when the popup blocker is activated it doesn't work
     889      // Edge has only implemented noreferrer and it seems to remove opener as well
     890      // Older IE versions pre IE 11 falls back to a window.open approach
     891      if (!Env.ie || Env.ie > 10) {
     892        var link = document.createElement('a');
     893        link.target = '_blank';
     894        link.href = url;
     895        link.rel = 'noreferrer noopener';
     896
     897        var evt = document.createEvent('MouseEvents');
     898        evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
     899
     900        appendClickRemove(link, evt);
     901      } else {
     902        var win = window.open('', '_blank');
     903        if (win) {
     904          win.opener = null;
     905          var doc = win.document;
     906          doc.open();
     907          doc.write('<meta http-equiv="refresh" content="0; url=' + DOMUtils.DOM.encode(url) + '">');
     908          doc.close();
     909        }
     910      }
     911    };
     912
     913    return {
     914      open: open
     915    };
     916  }
     917);
     918/**
     919 * Actions.js
     920 *
     921 * Released under LGPL License.
     922 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     923 *
     924 * License: http://www.tinymce.com/license
     925 * Contributing: http://www.tinymce.com/contributing
     926 */
     927
     928define(
     929  'tinymce.plugins.link.core.Actions',
     930  [
     931    'tinymce.core.util.VK',
     932    'tinymce.plugins.link.ui.Dialog',
     933    'tinymce.plugins.link.core.OpenUrl',
     934    'tinymce.plugins.link.core.Utils',
     935    'tinymce.plugins.link.core.Settings'
     936  ],
     937  function (VK, Dialog, OpenUrl, Utils, Settings) {
     938    var getLink = function (editor, elm) {
     939      return editor.dom.getParent(elm, 'a[href]');
     940    };
     941
     942    var getSelectedLink = function (editor) {
     943      return getLink(editor, editor.selection.getStart());
     944    };
     945
     946    var getHref = function (elm) {
     947      // Returns the real href value not the resolved a.href value
     948      var href = elm.getAttribute('data-mce-href');
     949      return href ? href : elm.getAttribute('href');
     950    };
     951
     952    var isContextMenuVisible = function (editor) {
     953      var contextmenu = editor.plugins.contextmenu;
     954      return contextmenu ? contextmenu.isContextMenuVisible() : false;
     955    };
     956
     957    var hasOnlyAltModifier = function (e) {
     958      return e.altKey === true && e.shiftKey === false && e.ctrlKey === false && e.metaKey === false;
     959    };
     960
     961    var gotoLink = function (editor, a) {
     962      if (a) {
     963        var href = getHref(a);
     964        if (/^#/.test(href)) {
     965          var targetEl = editor.$(href);
     966          if (targetEl.length) {
     967            editor.selection.scrollIntoView(targetEl[0], true);
     968          }
     969        } else {
     970          OpenUrl.open(a.href);
     971        }
     972      }
     973    };
     974
     975    var openDialog = function (editor) {
     976      return function () {
     977        Dialog.open(editor);
     978      };
     979    };
     980
     981    var gotoSelectedLink = function (editor) {
     982      return function () {
     983        gotoLink(editor, getSelectedLink(editor));
     984      };
     985    };
     986
     987    var leftClickedOnAHref = function (editor) {
     988      return function (elm) {
     989        var sel, rng, node;
     990        if (Settings.hasContextToolbar(editor.settings) && !isContextMenuVisible(editor) && Utils.isLink(elm)) {
     991          sel = editor.selection;
     992          rng = sel.getRng();
     993          node = rng.startContainer;
     994          // ignore cursor positions at the beginning/end (to make context toolbar less noisy)
     995          if (node.nodeType == 3 && sel.isCollapsed() && rng.startOffset > 0 && rng.startOffset < node.data.length) {
     996            return true;
     997          }
     998        }
     999        return false;
     1000      };
     1001    };
     1002
     1003    var setupGotoLinks = function (editor) {
     1004      editor.on('click', function (e) {
     1005        var link = getLink(editor, e.target);
     1006        if (link && VK.metaKeyPressed(e)) {
     1007          e.preventDefault();
     1008          gotoLink(editor, link);
     1009        }
     1010      });
     1011
     1012      editor.on('keydown', function (e) {
     1013        var link = getSelectedLink(editor);
     1014        if (link && e.keyCode === 13 && hasOnlyAltModifier(e)) {
     1015          e.preventDefault();
     1016          gotoLink(editor, link);
     1017        }
     1018      });
     1019    };
     1020
     1021    var toggleActiveState = function (editor) {
     1022      return function () {
     1023        var self = this;
     1024        editor.on('nodechange', function (e) {
     1025          self.active(!editor.readonly && !!Utils.getAnchorElement(editor, e.element));
     1026        });
     1027      };
     1028    };
     1029
     1030    var toggleViewLinkState = function (editor) {
     1031      return function () {
     1032        var self = this;
     1033
     1034        var toggleVisibility = function (e) {
     1035          if (Utils.hasLinks(e.parents)) {
     1036            self.show();
     1037          } else {
     1038            self.hide();
     1039          }
     1040        };
     1041
     1042        if (!Utils.hasLinks(editor.dom.getParents(editor.selection.getStart()))) {
     1043          self.hide();
     1044        }
     1045
     1046        editor.on('nodechange', toggleVisibility);
     1047
     1048        self.on('remove', function () {
     1049          editor.off('nodechange', toggleVisibility);
     1050        });
     1051      };
     1052    };
     1053
     1054    return {
     1055      openDialog: openDialog,
     1056      gotoSelectedLink: gotoSelectedLink,
     1057      leftClickedOnAHref: leftClickedOnAHref,
     1058      setupGotoLinks: setupGotoLinks,
     1059      toggleActiveState: toggleActiveState,
     1060      toggleViewLinkState: toggleViewLinkState
     1061    };
     1062  }
     1063);
     1064/**
     1065 * Controls.js
     1066 *
     1067 * Released under LGPL License.
     1068 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     1069 *
     1070 * License: http://www.tinymce.com/license
     1071 * Contributing: http://www.tinymce.com/contributing
     1072 */
     1073
     1074define(
     1075  'tinymce.plugins.link.ui.Controls',
     1076  [
     1077    'tinymce.plugins.link.core.Actions',
     1078    'tinymce.plugins.link.core.Utils'
     1079  ],
     1080  function (Actions, Utils) {
     1081
     1082    var setupButtons = function (editor) {
     1083      editor.addButton('link', {
     1084        icon: 'link',
     1085        tooltip: 'Insert/edit link',
     1086        shortcut: 'Meta+K',
     1087        onclick: Actions.openDialog(editor),
     1088        onpostrender: Actions.toggleActiveState(editor)
     1089      });
     1090
     1091      editor.addButton('unlink', {
     1092        icon: 'unlink',
     1093        tooltip: 'Remove link',
     1094        onclick: Utils.unlink(editor),
     1095        onpostrender: Actions.toggleActiveState(editor)
     1096      });
     1097
     1098      if (editor.addContextToolbar) {
     1099        editor.addButton('openlink', {
     1100          icon: 'newtab',
     1101          tooltip: 'Open link',
     1102          onclick: Actions.gotoSelectedLink(editor)
     1103        });
     1104      }
     1105    };
     1106
     1107    var setupMenuItems = function (editor) {
     1108      editor.addMenuItem('openlink', {
     1109        text: 'Open link',
     1110        icon: 'newtab',
     1111        onclick: Actions.gotoSelectedLink(editor),
     1112        onPostRender: Actions.toggleViewLinkState(editor),
     1113        prependToContext: true
     1114      });
     1115
     1116      editor.addMenuItem('link', {
     1117        icon: 'link',
     1118        text: 'Link',
     1119        shortcut: 'Meta+K',
     1120        onclick: Actions.openDialog(editor),
     1121        stateSelector: 'a[href]',
     1122        context: 'insert',
     1123        prependToContext: true
     1124      });
     1125    };
     1126
     1127    var setupContextToolbars = function (editor) {
     1128      if (editor.addContextToolbar) {
     1129        editor.addContextToolbar(
     1130          Actions.leftClickedOnAHref(editor),
     1131          'openlink | link unlink'
     1132        );
     1133      }
     1134    };
     1135
     1136    return {
     1137      setupButtons: setupButtons,
     1138      setupMenuItems: setupMenuItems,
     1139      setupContextToolbars: setupContextToolbars
     1140    };
     1141  }
     1142);
     1143/**
     1144 * Plugin.js
     1145 *
     1146 * Released under LGPL License.
     1147 * Copyright (c) 1999-2017 Ephox Corp. All rights reserved
     1148 *
     1149 * License: http://www.tinymce.com/license
     1150 * Contributing: http://www.tinymce.com/contributing
     1151 */
     1152
     1153define(
     1154  'tinymce.plugins.link.Plugin',
     1155  [
     1156    'tinymce.core.PluginManager',
     1157    'tinymce.plugins.link.core.Actions',
     1158    'tinymce.plugins.link.ui.Controls'
     1159  ],
     1160  function (PluginManager, Actions, Controls) {
     1161    PluginManager.add('link', function (editor) {
     1162      Controls.setupButtons(editor);
     1163      Controls.setupMenuItems(editor);
     1164      Controls.setupContextToolbars(editor);
     1165      Actions.setupGotoLinks(editor);
     1166      editor.addShortcut('Meta+K', '', Actions.openDialog(editor));
     1167      editor.addCommand('mceLink', Actions.openDialog(editor));
     1168    });
     1169
     1170    return function () { };
     1171  }
     1172);
     1173dem('tinymce.plugins.link.Plugin')();
     1174})();
  • wp-includes/js/tinymce/plugins/link/plugin.min.js

     
     1!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("4",tinymce.util.Tools.resolve),g("1",["4"],function(a){return a("tinymce.PluginManager")}),g("5",["4"],function(a){return a("tinymce.util.VK")}),g("a",["4"],function(a){return a("tinymce.util.Delay")}),g("b",["4"],function(a){return a("tinymce.util.Tools")}),g("c",["4"],function(a){return a("tinymce.util.XHR")}),g("9",[],function(){var a=function(a){return"boolean"==typeof a.link_assume_external_targets&&a.link_assume_external_targets},b=function(a){return"boolean"==typeof a.link_context_toolbar&&a.link_context_toolbar},c=function(a){return a.link_list},d=function(a){return"string"==typeof a.default_link_target},e=function(a){return a.default_link_target},f=function(a){return a.target_list},g=function(a,b){a.settings.target_list=b},h=function(a){return f(a)!==!1},i=function(a){return a.rel_list},j=function(a){return void 0!==i(a)},k=function(a){return a.link_class_list},l=function(a){return void 0!==k(a)},m=function(a){return a.link_title!==!1},n=function(a){return"boolean"==typeof a.allow_unsafe_link_target&&a.allow_unsafe_link_target};return{assumeExternalTargets:a,hasContextToolbar:b,getLinkList:c,hasDefaultLinkTarget:d,getDefaultLinkTarget:e,getTargetList:f,setTargetList:g,shouldShowTargetList:h,getRelList:i,hasRelList:j,getLinkClassList:k,hasLinkClassList:l,shouldShowLinkTitle:m,allowUnsafeLinkTarget:n}}),h("d",RegExp),g("8",["b","9","d"],function(a,b,c){var d=function(b,c){var d=["noopener"],e=b?b.split(/\s+/):[],f=function(b){return a.trim(b.sort().join(" "))},g=function(a){return a=h(a),a.length?a.concat(d):d},h=function(b){return b.filter(function(b){return a.inArray(d,b)===-1})};return e=c?g(e):h(e),e.length?f(e):null},e=function(a){return a.replace(/\uFEFF/g,"")},f=function(a,b){return b=b||a.selection.getStart(),k(b)?a.dom.select("a[href]",b)[0]:a.dom.getParent(b,"a[href]")},g=function(a,b){var c=b?b.innerText||b.textContent:a.getContent({format:"text"});return e(c)},h=function(a){return a&&"A"===a.nodeName&&a.href},i=function(b){return a.grep(b,h).length>0},j=function(a){return!(/</.test(a)&&(!/^<a [^>]+>[^<]+<\/a>$/.test(a)||a.indexOf("href=")==-1))},k=function(a){return a&&"FIGURE"===a.nodeName&&/\bimage\b/i.test(a.className)},l=function(a,c){return function(e){a.undoManager.transact(function(){var g=a.selection.getNode(),h=f(a,g),i={href:e.href,target:e.target?e.target:null,rel:e.rel?e.rel:null,"class":e["class"]?e["class"]:null,title:e.title?e.title:null};b.hasRelList(a.settings)||b.allowUnsafeLinkTarget(a.settings)!==!1||(i.rel=d(i.rel,"_blank"==i.target)),e.href===c.href&&(c.attach(),c={}),h?(a.focus(),e.hasOwnProperty("text")&&("innerText"in h?h.innerText=e.text:h.textContent=e.text),a.dom.setAttribs(h,i),a.selection.select(h),a.undoManager.add()):k(g)?o(a,g,i):e.hasOwnProperty("text")?a.insertContent(a.dom.createHTML("a",i,a.dom.encode(e.text))):a.execCommand("mceInsertLink",!1,i)})}},m=function(a){return function(){a.undoManager.transact(function(){var b=a.selection.getNode();k(b)?n(a,b):a.execCommand("unlink")})}},n=function(a,b){var c,d;d=a.dom.select("img",b)[0],d&&(c=a.dom.getParents(d,"a[href]",b)[0],c&&(c.parentNode.insertBefore(d,c),a.dom.remove(c)))},o=function(a,b,c){var d,e;e=a.dom.select("img",b)[0],e&&(d=a.dom.create("a",c),e.parentNode.insertBefore(d,e),d.appendChild(e))};return{link:l,unlink:m,isLink:h,hasLinks:i,isOnlyTextSelected:j,getAnchorElement:f,getAnchorText:g,toggleTargetRules:d}}),g("6",["a","b","c","8","9"],function(a,b,c,d,e){var f={},g=function(a,b){var d=e.getLinkList(a.settings);"string"==typeof d?c.send({url:d,success:function(c){b(a,JSON.parse(c))}}):"function"==typeof d?d(function(c){b(a,c)}):b(a,d)},h=function(a,c,d){var e=function(a,d){return d=d||[],b.each(a,function(a){var b={text:a.text||a.title};a.menu?b.menu=e(a.menu):(b.value=a.value,c&&c(b)),d.push(b)}),d};return e(a,d||[])},i=function(b,c,d){var e=b.selection.getRng();a.setEditorTimeout(b,function(){b.windowManager.confirm(c,function(a){b.selection.setRng(e),d(a)})})},j=function(a,c){var g,j,k,l,m,n,o,p,q,r,s,t={},u=a.selection,v=a.dom,w=function(a){var b=k.find("#text");(!b.value()||a.lastControl&&b.value()==a.lastControl.text())&&b.value(a.control.text()),k.find("#href").value(a.control.value())},x=function(c){var d=[];if(b.each(a.dom.select("a:not([href])"),function(a){var b=a.name||a.id;b&&d.push({text:b,value:"#"+b,selected:c.indexOf("#"+b)!=-1})}),d.length)return d.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:d,onselect:w}},y=function(){j||!l||t.text||this.parent().parent().find("#text")[0].value(this.value())},z=function(c){var d=c.meta||{};n&&n.value(a.convertURL(this.value(),"href")),b.each(c.meta,function(a,b){var c=k.find("#"+b);"text"===b?0===j.length&&(c.value(a),t.text=a):c.value(a)}),d.attach&&(f={href:this.value(),attach:d.attach}),d.text||y.call(this)},A=function(a){a.meta=k.toJSON()};l=d.isOnlyTextSelected(u.getContent()),g=d.getAnchorElement(a),t.text=j=d.getAnchorText(a.selection,g),t.href=g?v.getAttrib(g,"href"):"",g?t.target=v.getAttrib(g,"target"):e.hasDefaultLinkTarget(a.settings)&&(t.target=e.getDefaultLinkTarget(a.settings)),(s=v.getAttrib(g,"rel"))&&(t.rel=s),(s=v.getAttrib(g,"class"))&&(t["class"]=s),(s=v.getAttrib(g,"title"))&&(t.title=s),l&&(m={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){t.text=this.value()}}),c&&(n={type:"listbox",label:"Link list",values:h(c,function(b){b.value=a.convertURL(b.value||b.url,"href")},[{text:"None",value:""}]),onselect:w,value:a.convertURL(t.href,"href"),onPostRender:function(){n=this}}),e.shouldShowTargetList(a.settings)&&(void 0===e.getTargetList(a.settings)&&e.setTargetList(a,[{text:"None",value:""},{text:"New window",value:"_blank"}]),p={name:"target",type:"listbox",label:"Target",values:h(e.getTargetList(a.settings))}),e.hasRelList(a.settings)&&(o={name:"rel",type:"listbox",label:"Rel",values:h(e.getRelList(a.settings),function(b){e.allowUnsafeLinkTarget(a.settings)===!1&&(b.value=d.toggleTargetRules(b.value,"_blank"===t.target))})}),e.hasLinkClassList(a.settings)&&(q={name:"class",type:"listbox",label:"Class",values:h(e.getLinkClassList(a.settings),function(b){b.value&&(b.textStyle=function(){return a.formatter.getCssText({inline:"a",classes:[b.value]})})})}),e.shouldShowLinkTitle(a.settings)&&(r={name:"title",type:"textbox",label:"Title",value:t.title}),k=a.windowManager.open({title:"Insert link",data:t,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:z,onkeyup:y,onbeforecall:A},m,r,x(t.href),n,o,p,q],onSubmit:function(c){var g=e.assumeExternalTargets(a.settings),h=d.link(a,f),k=d.unlink(a),m=b.extend({},t,c.data),n=m.href;return n?(l&&m.text!==j||delete m.text,n.indexOf("@")>0&&n.indexOf("//")==-1&&n.indexOf("mailto:")==-1?void i(a,"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(a){a&&(m.href="mailto:"+n),h(m)}):g===!0&&!/^\w+:/i.test(n)||g===!1&&/^\s*www[\.|\d\.]/i.test(n)?void i(a,"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(a){a&&(m.href="http://"+n),h(m)}):void h(m)):void k()}})},k=function(a){g(a,j)};return{open:k}}),g("e",["4"],function(a){return a("tinymce.dom.DOMUtils")}),g("f",["4"],function(a){return a("tinymce.Env")}),g("7",["e","f"],function(a,b){var c=function(a,b){document.body.appendChild(a),a.dispatchEvent(b),document.body.removeChild(a)},d=function(d){if(!b.ie||b.ie>10){var e=document.createElement("a");e.target="_blank",e.href=d,e.rel="noreferrer noopener";var f=document.createEvent("MouseEvents");f.initMouseEvent("click",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),c(e,f)}else{var g=window.open("","_blank");if(g){g.opener=null;var h=g.document;h.open(),h.write('<meta http-equiv="refresh" content="0; url='+a.DOM.encode(d)+'">'),h.close()}}};return{open:d}}),g("2",["5","6","7","8","9"],function(a,b,c,d,e){var f=function(a,b){return a.dom.getParent(b,"a[href]")},g=function(a){return f(a,a.selection.getStart())},h=function(a){var b=a.getAttribute("data-mce-href");return b?b:a.getAttribute("href")},i=function(a){var b=a.plugins.contextmenu;return!!b&&b.isContextMenuVisible()},j=function(a){return a.altKey===!0&&a.shiftKey===!1&&a.ctrlKey===!1&&a.metaKey===!1},k=function(a,b){if(b){var d=h(b);if(/^#/.test(d)){var e=a.$(d);e.length&&a.selection.scrollIntoView(e[0],!0)}else c.open(b.href)}},l=function(a){return function(){b.open(a)}},m=function(a){return function(){k(a,g(a))}},n=function(a){return function(b){var c,f,g;return!!(e.hasContextToolbar(a.settings)&&!i(a)&&d.isLink(b)&&(c=a.selection,f=c.getRng(),g=f.startContainer,3==g.nodeType&&c.isCollapsed()&&f.startOffset>0&&f.startOffset<g.data.length))}},o=function(b){b.on("click",function(c){var d=f(b,c.target);d&&a.metaKeyPressed(c)&&(c.preventDefault(),k(b,d))}),b.on("keydown",function(a){var c=g(b);c&&13===a.keyCode&&j(a)&&(a.preventDefault(),k(b,c))})},p=function(a){return function(){var b=this;a.on("nodechange",function(c){b.active(!a.readonly&&!!d.getAnchorElement(a,c.element))})}},q=function(a){return function(){var b=this,c=function(a){d.hasLinks(a.parents)?b.show():b.hide()};d.hasLinks(a.dom.getParents(a.selection.getStart()))||b.hide(),a.on("nodechange",c),b.on("remove",function(){a.off("nodechange",c)})}};return{openDialog:l,gotoSelectedLink:m,leftClickedOnAHref:n,setupGotoLinks:o,toggleActiveState:p,toggleViewLinkState:q}}),g("3",["2","8"],function(a,b){var c=function(c){c.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Meta+K",onclick:a.openDialog(c),onpostrender:a.toggleActiveState(c)}),c.addButton("unlink",{icon:"unlink",tooltip:"Remove link",onclick:b.unlink(c),onpostrender:a.toggleActiveState(c)}),c.addContextToolbar&&c.addButton("openlink",{icon:"newtab",tooltip:"Open link",onclick:a.gotoSelectedLink(c)})},d=function(b){b.addMenuItem("openlink",{text:"Open link",icon:"newtab",onclick:a.gotoSelectedLink(b),onPostRender:a.toggleViewLinkState(b),prependToContext:!0}),b.addMenuItem("link",{icon:"link",text:"Link",shortcut:"Meta+K",onclick:a.openDialog(b),stateSelector:"a[href]",context:"insert",prependToContext:!0})},e=function(b){b.addContextToolbar&&b.addContextToolbar(a.leftClickedOnAHref(b),"openlink | link unlink")};return{setupButtons:c,setupMenuItems:d,setupContextToolbars:e}}),g("0",["1","2","3"],function(a,b,c){return a.add("link",function(a){c.setupButtons(a),c.setupMenuItems(a),c.setupContextToolbars(a),b.setupGotoLinks(a),a.addShortcut("Meta+K","",b.openDialog(a)),a.addCommand("mceLink",b.openDialog(a))}),function(){}}),d("0")()}();
     2 No newline at end of file