[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/vendor/tinymce/plugins/anchor/ -> plugin.js (source)

   1  /**
   2   * Copyright (c) Tiny Technologies, Inc. All rights reserved.
   3   * Licensed under the LGPL or a commercial license.
   4   * For LGPL see License.txt in the project root for license information.
   5   * For commercial licenses see https://www.tiny.cloud/
   6   *
   7   * Version: 5.10.5 (2022-05-25)
   8   */
   9  (function () {
  10      'use strict';
  11  
  12      var global$2 = tinymce.util.Tools.resolve('tinymce.PluginManager');
  13  
  14      var global$1 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
  15  
  16      var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
  17  
  18      var allowHtmlInNamedAnchor = function (editor) {
  19        return editor.getParam('allow_html_in_named_anchor', false, 'boolean');
  20      };
  21  
  22      var namedAnchorSelector = 'a:not([href])';
  23      var isEmptyString = function (str) {
  24        return !str;
  25      };
  26      var getIdFromAnchor = function (elm) {
  27        var id = elm.getAttribute('id') || elm.getAttribute('name');
  28        return id || '';
  29      };
  30      var isAnchor = function (elm) {
  31        return elm && elm.nodeName.toLowerCase() === 'a';
  32      };
  33      var isNamedAnchor = function (elm) {
  34        return isAnchor(elm) && !elm.getAttribute('href') && getIdFromAnchor(elm) !== '';
  35      };
  36      var isEmptyNamedAnchor = function (elm) {
  37        return isNamedAnchor(elm) && !elm.firstChild;
  38      };
  39  
  40      var removeEmptyNamedAnchorsInSelection = function (editor) {
  41        var dom = editor.dom;
  42        global$1(dom).walk(editor.selection.getRng(), function (nodes) {
  43          global.each(nodes, function (node) {
  44            if (isEmptyNamedAnchor(node)) {
  45              dom.remove(node, false);
  46            }
  47          });
  48        });
  49      };
  50      var isValidId = function (id) {
  51        return /^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id);
  52      };
  53      var getNamedAnchor = function (editor) {
  54        return editor.dom.getParent(editor.selection.getStart(), namedAnchorSelector);
  55      };
  56      var getId = function (editor) {
  57        var anchor = getNamedAnchor(editor);
  58        if (anchor) {
  59          return getIdFromAnchor(anchor);
  60        } else {
  61          return '';
  62        }
  63      };
  64      var createAnchor = function (editor, id) {
  65        editor.undoManager.transact(function () {
  66          if (!allowHtmlInNamedAnchor(editor)) {
  67            editor.selection.collapse(true);
  68          }
  69          if (editor.selection.isCollapsed()) {
  70            editor.insertContent(editor.dom.createHTML('a', { id: id }));
  71          } else {
  72            removeEmptyNamedAnchorsInSelection(editor);
  73            editor.formatter.remove('namedAnchor', null, null, true);
  74            editor.formatter.apply('namedAnchor', { value: id });
  75            editor.addVisual();
  76          }
  77        });
  78      };
  79      var updateAnchor = function (editor, id, anchorElement) {
  80        anchorElement.removeAttribute('name');
  81        anchorElement.id = id;
  82        editor.addVisual();
  83        editor.undoManager.add();
  84      };
  85      var insert = function (editor, id) {
  86        var anchor = getNamedAnchor(editor);
  87        if (anchor) {
  88          updateAnchor(editor, id, anchor);
  89        } else {
  90          createAnchor(editor, id);
  91        }
  92        editor.focus();
  93      };
  94  
  95      var insertAnchor = function (editor, newId) {
  96        if (!isValidId(newId)) {
  97          editor.windowManager.alert('Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.');
  98          return false;
  99        } else {
 100          insert(editor, newId);
 101          return true;
 102        }
 103      };
 104      var open = function (editor) {
 105        var currentId = getId(editor);
 106        editor.windowManager.open({
 107          title: 'Anchor',
 108          size: 'normal',
 109          body: {
 110            type: 'panel',
 111            items: [{
 112                name: 'id',
 113                type: 'input',
 114                label: 'ID',
 115                placeholder: 'example'
 116              }]
 117          },
 118          buttons: [
 119            {
 120              type: 'cancel',
 121              name: 'cancel',
 122              text: 'Cancel'
 123            },
 124            {
 125              type: 'submit',
 126              name: 'save',
 127              text: 'Save',
 128              primary: true
 129            }
 130          ],
 131          initialData: { id: currentId },
 132          onSubmit: function (api) {
 133            if (insertAnchor(editor, api.getData().id)) {
 134              api.close();
 135            }
 136          }
 137        });
 138      };
 139  
 140      var register$1 = function (editor) {
 141        editor.addCommand('mceAnchor', function () {
 142          open(editor);
 143        });
 144      };
 145  
 146      var isNamedAnchorNode = function (node) {
 147        return node && isEmptyString(node.attr('href')) && !isEmptyString(node.attr('id') || node.attr('name'));
 148      };
 149      var isEmptyNamedAnchorNode = function (node) {
 150        return isNamedAnchorNode(node) && !node.firstChild;
 151      };
 152      var setContentEditable = function (state) {
 153        return function (nodes) {
 154          for (var i = 0; i < nodes.length; i++) {
 155            var node = nodes[i];
 156            if (isEmptyNamedAnchorNode(node)) {
 157              node.attr('contenteditable', state);
 158            }
 159          }
 160        };
 161      };
 162      var setup = function (editor) {
 163        editor.on('PreInit', function () {
 164          editor.parser.addNodeFilter('a', setContentEditable('false'));
 165          editor.serializer.addNodeFilter('a', setContentEditable(null));
 166        });
 167      };
 168  
 169      var registerFormats = function (editor) {
 170        editor.formatter.register('namedAnchor', {
 171          inline: 'a',
 172          selector: namedAnchorSelector,
 173          remove: 'all',
 174          split: true,
 175          deep: true,
 176          attributes: { id: '%value' },
 177          onmatch: function (node, _fmt, _itemName) {
 178            return isNamedAnchor(node);
 179          }
 180        });
 181      };
 182  
 183      var register = function (editor) {
 184        editor.ui.registry.addToggleButton('anchor', {
 185          icon: 'bookmark',
 186          tooltip: 'Anchor',
 187          onAction: function () {
 188            return editor.execCommand('mceAnchor');
 189          },
 190          onSetup: function (buttonApi) {
 191            return editor.selection.selectorChangedWithUnbind('a:not([href])', buttonApi.setActive).unbind;
 192          }
 193        });
 194        editor.ui.registry.addMenuItem('anchor', {
 195          icon: 'bookmark',
 196          text: 'Anchor...',
 197          onAction: function () {
 198            return editor.execCommand('mceAnchor');
 199          }
 200        });
 201      };
 202  
 203      function Plugin () {
 204        global$2.add('anchor', function (editor) {
 205          setup(editor);
 206          register$1(editor);
 207          register(editor);
 208          editor.on('PreInit', function () {
 209            registerFormats(editor);
 210          });
 211        });
 212      }
 213  
 214      Plugin();
 215  
 216  }());


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer