Вызов функции (CKEditor) insertElement () удаляет содержимое тега - PullRequest
0 голосов
/ 12 февраля 2020

Я делаю прослушиватель кликов для класса '.sticker'. Вызывает функцию editor.insertElement (eventElement). Но эта функция удаляет событие содержимого тега HTML.

  1. На панели стикеров нажмите стикер и в прослушиватель, затем вызовите insertSticker enter image description here enter image description here

  2. функция вызова команды insertSticker 'insertElement (стикер-тег)'

enter image description here

Он попадает в редактор, и его тег img исчезает с панели стикеров.

enter image description here enter image description here enter image description here

Как сохранить содержимое тега на панели стикеров после insertElement ()?

Ниже приведен полный код. (Настройка плагина CKEditor 'emoji')

/**
 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
(function () {
  'use strict';

  var stylesLoaded = false,
      arrTools = CKEDITOR.tools.array,
      htmlEncode = CKEDITOR.tools.htmlEncode,
      EmojiDropdown = CKEDITOR.tools.createClass({
        $: function (editor, plugin) {
          var lang = this.lang = editor.lang.emoji,
              self = this,
              ICON_SIZE = 21;

          this.listeners = [];
          this.plugin = plugin;
          this.editor = editor;
          this.groups = [
            {
              groupName: '1001',
              position: {
                x: -1 * ICON_SIZE,
                y: 0
              },
              items: []
            },
            {
              groupName: '1002',
              position: {
                x: -3 * ICON_SIZE,
                y: -1 * ICON_SIZE
              },
              items: []
            },
            {
              groupName: '1003',
              position: {
                x: -5 * ICON_SIZE,
                y: -2 * ICON_SIZE
              },
              items: []
            }
          ];

          // Keeps html elements references to not find them again.
          this.elements = {};

          // Name is responsible for icon name also.
          editor.ui.add('EmojiPanel', CKEDITOR.UI_PANELBUTTON, {
            label: 'emoji',
            title: lang.title,
            modes: {wysiwyg: 1},
            editorFocus: 0,
            toolbar: 'insert',
            panel: {
              css: [
                CKEDITOR.skin.getPath('editor'),
                plugin.path + 'skins/default.css'
              ],
              attributes: {
                role: 'listbox',
                'aria-label': lang.title
              },
              markFirst: false
            },

            onBlock: function (panel, block) {
              var keys = block.keys,
                  rtl = editor.lang.dir === 'rtl';

              keys[rtl ? 37 : 39] = 'next'; // ARROW-RIGHT
              keys[40] = 'next'; // ARROW-DOWN
              keys[9] = 'next'; // TAB
              keys[rtl ? 39 : 37] = 'prev'; // ARROW-LEFT
              keys[38] = 'prev'; // ARROW-UP
              keys[CKEDITOR.SHIFT + 9] = 'prev'; // SHIFT + TAB
              keys[32] = 'click'; // SPACE

              self.blockElement = block.element;
              self.emojiList = self.editor._.emoji.list;

              self.addEmojiToGroups();

              block.element.getAscendant('html').addClass('cke_emoji');
              block.element.getDocument().appendStyleSheet(
                  CKEDITOR.getUrl(CKEDITOR.basePath + 'contents.css'));
              block.element.addClass('cke_emoji-panel_block');
              block.element.setHtml(self.createEmojiBlock());
              block.element.removeAttribute('title');
              panel.element.addClass('cke_emoji-panel');

              self.items = block._.getItems();

              self.blockObject = block;
              self.elements.emojiItems = block.element.find(
                  '.cke_emoji-outer_emoji_block li > a');
              self.elements.sectionHeaders = block.element.find(
                  '.cke_emoji-outer_emoji_block h2');
              self.elements.input = block.element.findOne('input');
              self.inputIndex = self.getItemIndex(self.items,
                  self.elements.input);
              self.elements.emojiBlock = block.element.findOne(
                  '.cke_emoji-outer_emoji_block');
              self.elements.navigationItems = block.element.find('nav li');
              self.elements.sections = block.element.find('section');
              self.registerListeners();

            },

            onOpen: self.openReset()
          });
        },
        proto: {
          registerListeners: function () {
            arrTools.forEach(this.listeners, function (item) {
              var root = this.blockElement,
                  selector = item.selector,
                  listener = item.listener,
                  event = item.event,
                  ctx = item.ctx || this;

              arrTools.forEach(root.find(selector).toArray(), function (node) {
                node.on(event, listener, ctx);
              });
            }, this);
          },
          createEmojiBlock: function () {
            var output = [];

            output.push(this.createGroupsNavigation());
            output.push(this.createEmojiListBlock());

            return '<div class="cke_emoji-inner_panel">' + output.join('')
                + '</div>';
          },
          createGroupsNavigation: function () {
            var itemTemplate,
                items,
                imgUrl;

            imgUrl = CKEDITOR.getUrl(this.plugin.path + 'assets/iconsall.png');


            itemTemplate = new CKEDITOR.template(
                '<li class="cke_emoji-navigation_item" data-cke-emoji-group="{group}">'
                +
                '<a href="#" draggable="false" _cke_focus="1" title="{group}">'
                +
                '<span style="background-image:url(' + imgUrl + ');' +
                'background-repeat:no-repeat;background-position:{positionX}px {positionY}px;"></span>'
                +
                '</a></li>'
            );

            items = arrTools.reduce(this.groups, function (acc, item) {
              if (!item.items.length) {
                return acc;
              } else {
                return acc + itemTemplate.output({
                  group: htmlEncode(item.groupName),
                  positionX: item.position.x,
                  positionY: item.position.y
                });
              }
            }, '');
            this.listeners.push({
              selector: 'nav',
              event: 'click',
              listener: function (event) {
                console.log("clickEvent = " + JSON.stringify(event.data));
                var activeElement = event.data.getTarget().getAscendant('li',
                    true);
                console.log("activeElement" + JSON.stringify(activeElement));
                if (!activeElement) {
                  return;
                }
                arrTools.forEach(this.elements.navigationItems.toArray(),
                    function (node) {
                      if (node.equals(activeElement)) {
                        node.addClass('active');
                      } else {
                        node.removeClass('active');
                      }
                    });

                this.clearSearchAndMoveFocus(activeElement);

                event.data.preventDefault();
              }
            });

            return '<nav aria-label="' + htmlEncode(this.lang.navigationLabel)
                + '"><ul>' + items + '</ul></nav>';
          },
          createEmojiListBlock: function () {
            var self = this;
            this.listeners.push({
              selector: '.cke_emoji-outer_emoji_block',
              event: 'scroll',
              listener: (function () {
                var buffer = CKEDITOR.tools.throttle(150,
                    self.refreshNavigationStatus, self);
                return buffer.input;
              })()
            });

            this.listeners.push({
              selector: '.sticker',
              event: 'click',
              listener: function (event) {
                this.editor.execCommand('insertSticker', {
                  sticker: event.data.getTarget()
                });
              }
                        });
            return '<div class="cke_emoji-outer_emoji_block">'
                + this.getEmojiSections() + '</div>';
          },
          getEmojiSections: function () {
            return arrTools.reduce(this.groups, function (acc, item) {
              var length = item.items.length;
              // If group is empty skip it.
              if (length == 0) {
                return acc;
              } else {
                return acc + this.getEmojiSection(item);
              }
            }, '', this);
          },
          getEmojiSection: function (item) {
            var groupName = htmlEncode(item.groupName),
                group = this.getEmojiListGroup(item.items);
            return '<section data-cke-emoji-group="' + groupName + '" ><ul>'
                + group + '</ul></section>';
          },
          getEmojiListGroup: function (items) {
            var emojiTpl = new CKEDITOR.template('<li class="cke_emoji-item">' +
                '<img class="sticker" width="120" height="auto" draggable="false" '
                                + 'data-cke-emoji-group="{groupName}" src="{src}"></li>');

            return arrTools.reduce(
                items,
                function (acc, item) {
                  addEncodedName(item);
                  return acc + emojiTpl.output({
                    src: htmlEncode(item.src),
                    groupName: htmlEncode(item.groupName),
                  });
                },
                '',
                this
            );
          },
          openReset: function () {
            // Resets state of emoji dropdown.
            // Clear filters, reset focus, etc.
            var self = this,
                firstCall;

            return function () {

              if (!firstCall) {
                //self.filter( '' );
                firstCall = true;
              }

              self.elements.emojiBlock.$.scrollTop = 0;
              self.refreshNavigationStatus();

              // Reset focus:
              CKEDITOR.tools.setTimeout(function () {
                //self.elements.input.focus(true);
                self.blockObject._.markItem(self.inputIndex);
              }, 0, self);
            };
          },
          refreshNavigationStatus: function () {
            var containerOffset = this.elements.emojiBlock.getClientRect().top,
                section,
                groupName;

            section = arrTools.filter(this.elements.sections.toArray(),
                function (element) {
                  var rect = element.getClientRect();
                  if (!rect.height) {
                    return false;
                  }
                  return rect.height + rect.top > containerOffset;
                });
            groupName = section.length ? section[0].data('cke-emoji-group')
                : false;

            arrTools.forEach(this.elements.navigationItems.toArray(),
                function (node) {
                  if (node.data('cke-emoji-group') === groupName) {
                    node.addClass('active');
                  } else {
                    node.removeClass('active');
                  }
                });
          },
          clearSearchAndMoveFocus: function (activeElement) {
            this.moveFocus(activeElement.data('cke-emoji-group'));
          },
          moveFocus: function (groupName) {
            var firstSectionItem = this.blockElement.findOne(
                'a[data-cke-emoji-group="' + htmlEncode(groupName) + '"]'),
                itemIndex;

            if (!firstSectionItem) {
              return;
            }

            itemIndex = this.getItemIndex(this.items, firstSectionItem);
            firstSectionItem.focus(true);
            firstSectionItem.getAscendant('section').getFirst().scrollIntoView(
                true);
            this.blockObject._.markItem(itemIndex);
          },
          getItemIndex: function (nodeList, item) {
            return arrTools.indexOf(nodeList.toArray(), function (element) {
              return element.equals(item);
            });
          },
          addEmojiToGroups: function () {
            var groupObj = {};
            arrTools.forEach(this.groups, function (group) {
              groupObj[group.groupName] = group.items;
            }, this);

            arrTools.forEach(this.emojiList, function (emojiObj) {
              groupObj[emojiObj.groupName].push(emojiObj);
            }, this);
          }
        }
      });

  CKEDITOR.plugins.add('emoji', {
    requires: 'ajax,panelbutton,floatpanel',
    lang: 'en', // %REMOVE_LINE_CORE%
    icons: 'emojipanel',
    hidpi: true,

    isSupportedEnvironment: function () {
      return !CKEDITOR.env.ie || CKEDITOR.env.version >= 11;
    },

    beforeInit: function () {
      if (!this.isSupportedEnvironment()) {
        return;
      }
      if (!stylesLoaded) {
        CKEDITOR.document.appendStyleSheet(this.path + 'skins/default.css');
        stylesLoaded = true;
      }
    },

    init: function (editor) {
      if (!this.isSupportedEnvironment()) {
        return;
      }

      var stickerListUrl = '/sticker';

      CKEDITOR.ajax.load(CKEDITOR.getUrl(stickerListUrl), function (data) {
        if (data === null) {
          return;
        }
        if (editor._.emoji === undefined) {
          editor._.emoji = {};
        }

        if (editor._.emoji.list === undefined) {
          editor._.emoji.list = JSON.parse(data);
        }
      });

      editor.addCommand('insertSticker', {
        exec: function (editor, data) {
          console.log("data = " + JSON.stringify(data));
          editor.insertElement(data.sticker);
        }
      });

      if (editor.plugins.toolbar) {
        new EmojiDropdown(editor, this);
      }

    }
  });

  function addEncodedName(item) {
    if (!item.name) {
      item.name = htmlEncode(
          item.id.replace(/::.*$/, ':').replace(/^:|:$/g, ''));
    }
    return item;
  }
})();

1 Ответ

0 голосов
/ 12 февраля 2020

Я исправил эту проблему.

Функция insertElement (HTML Element) - переместить оригинальный элемент.

Итак, сначала я скопирую элемент в другую переменную. и вызвать insertElement (Clone HTML Element).

Итак, оригинальный элемент остается.

...