Конфигурация БТР

Для конфигурации БТР предоставлены следующие опции:

  • Опции полей ввода:
    • tagStyle — цвет рамки поля ввода.
    • tooltip — всплывающая подсказка.
    • selectOnClick — выделять текст в поле ввода по клику.
    • fontSize - используемый размер шрифта. Опция может принимать следующие значения:
      • 'xs' - 12px;
      • 's' - 13px;
      • 'm' - 14px;
      • 'l' - 15px;
      • 'xl' - 16px;
      • '2xl' - 17px;
      • '3xl' - 18px;
      • '4xl' - 20px;
      • '5xl' - 24px;
      • '6xl' - 28px;
      • '7xl' - 32px.
    • lineHeight - используемый межстрочный интервал. Опция может принимать следующие значения:
      • 's' - 129%;
      • 'm' - 150%.
  • Опции форматирования:
    • textFormats — список предустановленных стилей для текста. Текстовые форматы могут применяться посредством метода applyFormats().

Базовые форматы описаны в tinyConstants.styles, который распространяется в классе RichEditor/base:contstants.

Пример задания набора пользовательских форматов:

// TypeScript
import {constants} from 'RichEditor/base';
  
const textFormats = [
    ...constants.tinyConstants.styles,
    accented: {
        inline: 'span',
        classes: 'news_Panel_accentedText',
        title: 'Акцентированный'
    },
    dull: {
        inline: 'span',
        classes: 'news_Panel_dullText',
        title: 'Тусклый'
    },
    bigHeading: {
        block: 'h1',
        classes: 'news_Panel_bigHeadingText',
        title: 'Большой заголовок'
    }
];

В результате необходимый набор форматов будет добавлен в выпадающий список на панели редактирования.

  • Опции для загрузки изображения:
    • imageUploader — служит для загрузки и редактирования изображений. Если данная опция не указана, кнопка вставки изображения не отобразится. Загрузчик представляет собой объект с двумя методами:
      • getFiles — обязательный метод, необходимый для загрузки изображений. Должен возвращать Promise<IImageFile[]> и иметь два параметра:
        • target - HTMLElement, служащий для позиционирования открываемого окна;
        • opener - Контрол, являющийся опенером.
      • editImage — метод, используемый для редактирования изображения. Если он не реализован, то кнопка редактирования не появится в панели управления изображением. Также editImage должен возвращать Promise<IImageData> и иметь два параметра:
        • data - Объект метаданных изображения, реализующий IImageData;
        • opener - Контрол, являющийся опенером.
  • Опции для настройки вставки:
    • pasteConfig — конфигурация вставки имеет 3 параметра:
      • replaceYoutubeLinks — вставить ссылку в виде медиа-объекта;
      • allowImages — разрешить вставлять изображение;
      • allowedClasses — список разрешенных css-классов.
  • Опции для настройки стиля текста:
    • fontSizes — список разрешенных шрифтов, автоматически добавляемый в стилевую панель;
    • fontColors — список разрешенных цветов, автоматически добавляемый в палитру и стилевую панель.

Конфигурация набора элементов для тулбара

Конфигурирование через набор стандартных кнопок

Набор элементов для панели редактирования устанавливается с помощью опции toolbarItems. В опцию передается массив с объектным описанием кнопок. Набор стандартных элементов панели редактирования находится в ButtonsConstants из библиотеки RichEditor/extended.

Рассмотрим пример конфигурирования тулбара.

// TypeScript
import {Control} from 'UI/Base';
import {ButtonsConstants} from 'RichEditor/extended';
 
MyControl extends Control {
    private value: JsonML;
    private toolbarItems: object[];
     
    protected _beforeMount() {
        this.toolbarItems = [ButtonsConstants.EMOJI, ButtonsConstants.CODESAMPLE];
    }
}
<!-- WML -->
<RichEditor.extended:Editor bind:value="value" toolbarItems="{{toolbarItems}}"/>

В данном примере добавили кнопки emoji и codesample.

Создание собственных кнопок для панели редактирования

Для частных случаев предусмотрено создание прикладных кнопок для панели редактирования.

Рассмотрим на примере кнопки выделения информационным блоком:

В опции кнопок панели редактирования приходит editorModel — событийная модель, содержащая текущее состояние редактора, с помощью которой можно узнать о выделении (selection) и форматировании в редакторе.

Также, чтобы вызвать метод из API редактора, необходимо нотифицировать событие callMethod с именем метода (например, applyFormats,removeFormats и т.д.) в качестве первого параметра и аргументами в качестве остальных.

// TypeScript
import {Control} from 'UI/Base';
import * as template from 'wml!News/RTEButtons/InfoBlock';
import {RecordSet} from 'Types/collection';
import {IObservableObject} from 'Types/entity';
 
interface IOptions = {
    editorModel: IObservableObject
};
 
export default class InfoBlock extends Control<IOptions> {
    private isActive: boolean = false;
    private icons: string[] = ['icon-Info icon-medium'];
    protected _template: Function = template;
     
    protected _beforeMount({editorModel}): void {
        editorModel.subscribe('formatsChanged', this.formatsChangedHandler, this);
    }
     
    protected _beforeUnmount(): void {
        this._options.editorModel.unsubscribe('formatsChanged', this.formatsChangedHandler, this);
    }
     
    protected formatsChangedHandler(formats: RecordSet): void {
        this.isActive = formats.get('infoBlock').get('state');
    }
     
    protected clickHandler(): void {
        if (this.isActive) {
            this._notify('callMethod', ['removeFormats', ['infoBlock']], {bubbling: true});
        } else {
             
            // Инфоблок несовместим с форматом цитаты
            this._notify('callMethod', ['removeFormats', ['blockquote']], {bubbling: true});
            this._notify('callMethod', ['applyFormats', [{formatName: 'infoBlock', state: true}]], {bubbling: true});
        }
    }
}
<!-- WML -->
<Controls.toggle:Button
    value="{{isActive}}"
    inlineHeight="l"
    viewMode="pushButton"
    icons="{{icons}}"
    iconStyle="secondary"
    on:valueChanged="clickHandler()"/>

Для того чтобы созданная кнопка попала в панель редактирования, передайте ее в опцию toolbarItems:

// TypeScript
MyControl extends Control {
    ...
    protected _beforeMount() {
        this.toolbarItems = [id:'InfoBlock', template:'News/RTEButtons/InfoBlock'];
    }
}
  • id — ключ (уникальный идентификатор) кнопки;
  • template — путь до контрола.

Если при активации кнопки нужно использовать всплывающие окна Controls/popup:Sticky, то обязательно при открытии проставлять опцию actionOnScroll со значением close.

Настройка набора кнопок при изменении ширины тулбара

В БТР есть возможность задавать разные наборы элементов тулбара для узкого и широкого тулбара. У кнопок тулбара есть свойство showType, которое указывает, при какой ширине редактора стоит показывать кнопку.

Свойство может принимать следующие значения:

  • always - кнопка отображается при любой ширине тулбара;
  • compact - кнопка отображается только для компактного тулбара (ширина тулбара меньше 615px);
  • normal - кнопка отображается при нормальной ширине тулбара (ширина тулбара больше или равна 615px).

Если данное свойство не задано, то считается, что showType имеет значение always.

Рассмотрим пример задания свойства showType.

// TypeScript
protected _beforeMount() {
    this.toolbarItems = [
        {...buttonConstants.STYLES, showType: 'compact'},
        {...buttonConstants.CUSTOM_FORMAT, showType: 'normal'},
        {...buttonConstants.BOLD, showType: 'normal'},
        {...buttonConstants.ITALIC, showType: 'normal'},
        {...buttonConstants.UNDERLINE, showType: 'normal'},
        {...buttonConstants.STROKED, showType: 'normal'},
        {...buttonConstants.COLOR, showType: 'normal'},
        buttonConstants.ALIGN
    ];
}

Для дефолтного набора кнопок уже есть настройка набора элементов для разной ширины тулбара. При нехватке места команды оформления текста заменяются одним элементом, вызывающим всплывающее окно, содержащее эти команды.

Реализация прикладного БТР

Библиотека предоставляет набор контролов для реализации БТР со своим тулбаром:

  • RichEditor/extended:Toolbar — это панель, на которой размещены кнопки, каждая из которых имеет определенный функционал.
  • RichEditor/extended:Controller — это контроллер, который связывает панель редактирования с полем ввода текста. Для построения панели редактирования используйте контентную опцию toolbar, а для поля ввода — input.

Далее рассмотрим пример конфигурирования собственной кнопки.

<!-- WML -->
<RichEditor.extended:Controller bind:value="value" attr:class="ws-flexbox ws-flex-row-reverse">
    <ws:toolbar>
        <RichEditor.extended:Toolbar items="{{items}}"/>
    </ws:toolbar>
    <ws:input>
        <RichEditor.base:Editor/>
    </ws:input>
</RichEditor.extended:Controller>
// TypeScript
import {ButtonsConstants} from 'RichEditor/Extended';
class MyControl extends Control {
    private items: Array<HashMap<any>>
    protected _beforeMount() {
        this.items = [ButtonsConstants.EMOJI, ButtonsConstants.CODESAMPLE];
    }
}

Чтобы кнопки могли реагировать на изменения в редакторе (форматирование, выделение), необходимо в опцию model передать модель, которая предоставляется контролом RichEditor/extended:Controller.

<!-- WML -->
<RichEditor.extended:Controller bind:value="value" attr:class="ws-flexbox ws-flex-row-reverse">
    <ws:toolbar>
        <RichEditor.extended:Toolbar
            items="{{items}}"
            model="{{toolbar.model}}"/>
    </ws:toolbar>
    <ws:input>
        <RichEditor.base:Editor/>
    </ws:input>
</RichEditor.extended:Controller>

Валидация

Валидация производится аналогично полям ввода.

Используйте стандартные валидаторы:

  • RichEditor/validators:maxLength — валидация максимальной длины;
  • RichEditor/validators:isRequired — проверка на отсутствие значения.

События ввода данных

События ввода данных БТР аналогичны событиям полей ввода.

Редактирование по месту

Редактирование по месту производится аналогично полям ввода.

Оптимизация размеров загружаемых изображений

Опция imageUrlResolver вызывается при вставке/изменении размеров изображения и служит для предобработки размеров загруженных изображений. Её следует использовать для подгонки размеров изображения под реальные размеры редактора, учитывая дисплеи с повышенной плотностью пикселей. Базовый резолвер, который предобрабатывает размеры через сервис Previewer, доступен в Previewer/UrlHelper:getUrlOfResizedImage.

<!-- WML -->
<RichEditor.extended:Editor imageUrlResolver="{{_imageUrlResolver}}"/>
// TypeScript
import {getUrlOfResizedImage} from 'Previewer/UrlHelper';
export default class MyControl extends Control<...> {
    protected _imageUrlResolver: Function = getUrlOfResizedImage;
    ...
}