Янв
13
2022

Как добавить кнопку в визуальный редактор Битрикс

Простая кнопка, оборачивающая выделенный текст в тег

Сделаем кнопку, которая будет оборачивать текст в тег <noindex>.

  1. Создадим папку /local/php_interface/handlers/htmleditor
  2. Создадим в папке файл handler.php с контентом:
<?php
AddEventHandler('fileman', 'OnBeforeHTMLEditorScriptRuns', 'addHtmlGalleryEditor');

function addHtmlGalleryEditor() {
    static $init = false;

    if ($init) return;
    $init = true;

    echo '<script>(function(){'.file_get_contents(__DIR__ . '/assets/script.js').'})();</script>';
}

3. Там же создаем папку assets, внутри создаем файл script.js. В файле контент:

function applyForEditor(editor) {
    editor.AddButton(
        {
            id: 'noindex_btn',
            src: '/local/php_interface/handlers/htmleditor/assets/img/noindex.png',
            name: 'Не индексировать выделенное',
            title: 'Не индексировать выделенное',
            show_name: false,
            handler: function (e) {
                this.editor.action.actions.formatInline.exec("noindex", null, "noindex")
            },
            toolbarSort: 300
        }
    );
}

if (window.BXHtmlEditor && window.BXHtmlEditor.editors) {
    for (var id in window.BXHtmlEditor.editors) {
        if (window.BXHtmlEditor.editors.hasOwnProperty(id)) {
            applyForEditor(window.BXHtmlEditor.Get(id))
        }
    }
}

BX.addCustomEvent("OnEditorInitedBefore", applyForEditor);

Главную работу тут делает this.editor.action.actions.formatInline.exec("noindex", null, "noindex"). У метода такие параметры: function(command, value, tagName, arStyle, cssClass, params). command и value не используются, можно указывать что угодно туда. tagName - имя тега, которым обрамлять, arStyle - стили на теге, cssClass - классы на теге.

Если выделенный текст уже обрамлен тегом, то обрамление снимется.

На адрес /local/php_interface/handlers/htmleditor/assets/img/noindex.png загрузите иконку кнопки 20x20 пикселей.

Такая получилась у меня кнопка:

Кнопка с попапом

Сделаем кнопку вставки HTML кода как текст.

  1. Создадим папку /local/php_interface/handlers/htmleditor
  2. Создадим в папке файл handler.php с контентом:
<?php
AddEventHandler('fileman', 'OnBeforeHTMLEditorScriptRuns', 'addHtmlGalleryEditor');

function addHtmlGalleryEditor() {
    static $init = false;

    if ($init) return;
    $init = true;

    echo '<script>(function(){'.file_get_contents(__DIR__ . '/assets/script.js').'})();</script>';
}

3. Там же создаем папку assets, внутри создаем файл script.js. В файле контент:

// Основной конструктор
function CodeDialog(editor, params) {
    params = {
        id: 'bx_code',
        width: 600,
        className: 'bxhtmled-code-dialog'
    };

    // Call parrent constructor
    CodeDialog.superclass.constructor.apply(this, [editor, params]);
    this.id = 'code_' + this.editor.id;
    this.waitCounter = false;
    this.SetContent(this.Build());

    BX.addCustomEvent(this, "OnDialogSave", BX.proxy(this.Save, this));
}

// Расширяем наш диалог стандартными методами из BXHtmlEditor.Dialog
BX.extend(CodeDialog, window.BXHtmlEditor.Dialog);

// Функция создания тела попапа
CodeDialog.prototype.Build = function () {
    this.textarea = BX.create('textarea', {props: {style: 'width:95%;min-height:100px'}})

    return this.textarea;
};

// Функция после нажатия Сохранить в попапе
CodeDialog.prototype.Save = function () {
    if (this.savedRange) {
        this.editor.selection.SetBookmark(this.savedRange);
    }

    // Создаем ноду из текста textarea
    var code = document.createElement('code')
    code.className = 'editor_insert_code'
    code.innerText = this.textarea.value;

    // Вставляем ноду в редактор
    this.editor.selection.InsertNode(code);

    // Очищаем поле
    this.textarea.value = '';
}

// Функция показа попапа
CodeDialog.prototype.Show = function (bxTag, savedRange) {
    this.savedRange = savedRange;
    if (this.savedRange) {
        this.editor.selection.SetBookmark(this.savedRange);
    }

    this.SetTitle('Вставка кода');
    CodeDialog.superclass.Show.apply(this, arguments);
};

// Добавляем наш попап в список Битрикса
window.BXHtmlEditor.dialogs.Code = CodeDialog;

function applyForEditor(editor) {
    editor.AddButton(
        {
            id: 'code',
            src: '/local/php_interface/handlers/htmleditor/assets/img/code.png',
            name: 'Вставка кода',
            codeEditorMode: true,
            handler: function () {
                // Показать попап
                this.editor.GetDialog('Code').Show(false, this.savedRange);
            },
            toolbarSort: 220
        }
    );
}

if (window.BXHtmlEditor && window.BXHtmlEditor.editors) {
    for (var id in window.BXHtmlEditor.editors) {
        if (window.BXHtmlEditor.editors.hasOwnProperty(id)) {
            applyForEditor(window.BXHtmlEditor.Get(id))
        }
    }
}

BX.addCustomEvent("OnEditorInitedBefore", applyForEditor);

В данном примере код я вставляю с помощью метода this.editor.selection.InsertNode(). Вместо него можно использовать this.editor.selection.InsertHTML(). Эти методы вставляют код вначале выделенного места.

Если надо вставлять взамен выделенного фрагмента, то используйте this.editor.action.Exec('insertHTML', html), где html - ваш код. Но insertHTML не всегда работает как ожидается, поэтому я его не использую.

На адрес /local/php_interface/handlers/htmleditor/assets/img/code.png загрузите иконку кнопки 20x20 пикселей.

Такая получилось так:

Как добавить стили только для визуального редактора

С помощью способа выше добавляем функцию applyForEditor(). В ней добавляем код:

BX.addCustomEvent(editor, 'OnIframeInit', function () {
    var iframeHead = this.dom.iframeCont.querySelector('iframe').contentWindow.document.querySelector('head')

    var style = document.createElement('link')
    style.rel = 'stylesheet';
    style.href = '/local/templates/.default/visual_editor.css';

    iframeHead.appendChild(style)
})

Создаем файл /local/templates/.default/visual_editor.css и добавляем в него стили. Они будут отображаться только в визуальном редакторе.

Например, для кода, вставленного через нашу кнопку, можно добавить рамку. (на скрине у меня она уже есть).

.editor_insert_code {
    border: 1px dotted orange;
    padding: 3px;
    position: relative;
    padding-top: 10px;
    display: block;
    margin: 2px;
}
.editor_insert_code:before {
    content: "HTML";
    position: absolute;
    top: -7px;
    background: #fff;
    margin: 0 3px;
    font-size: 11px;
}
Пожалуйста, оцените на сколько вам понравилась статья!
Голосов: 13 Среднее: 4.7