3 горизонтальные линии, бургер
3 горизонтальные линии, бургер
3 горизонтальные линии, бургер
3 горизонтальные линии, бургер

3 горизонтальные линии, бургер
Удалить все
ЗАГРУЗКА ...

Содержание



    Всё о quill blots, и то как сделать свой собственный

    Часы
    24.10.2024
    /
    Часы
    02.10.2025
    /
    Часы
    7 минут
    Глазик
    438
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Теги:
    JS
    Quilljs

    Список blot-ов (клякс) и то как их найти

    Клякса (blot) - это строительный блок документа для parchment. Их различные виды, и способы применения, и реализации можно посмотреть на моём онлайн редакторе quill.
    Как можно будет увидеть ниже, этих строительных блоков достаточно много. И каждый из них существует, чтобы выполнять определённую роль в документе. О роли каждого blot-а я расскажу отдельно. А пока, вот все виды клякс в quilljs:
    1. block
    2. block/embed
    3. break
    4. container
    5. cursor
    6. embed
    7. inline
    8. scroll
    9. text
    Для того чтобы импортировать любой из этого списка blot, в новую переменную в JS, введи название blot-а после blots, например вот так:
    let blot = Quill.imports["blots/block"]
    Чтобы посмотреть полный список всех доступных blot-ов, введи в консоль браузера следующее:
    Quill.imports

    Про предназначение каждого из блоков

    Inline blot. Примеры использования данного блока это bold, italik, или что-нибудь подчёркнутое. Это самый простой блок, он просто оборачивает выделенный в заранее указанный тег с заранее указанными классами. И он может быть обёрнут вокруг другого inline блока.
    Block blot. К примеру можно привести блок цитат, или блок кода, или заголовки. Важно понять как работает данный блок. Он не просто оборачивает в определённый тег выделенный блок, да именно блок, не текст, он его заменяет. То есть блоки block не могут быть внутри друг друга, как это есть с inline блоками.
    Container blot. Они созданы для того, чтобы преодолеть не возможность предыдущих блоков встраиваться в другие. Хотя и не без своих нюансов. В других статьях, вы увидите, что нам придётся заранее указывать элементы которые могут быть друг-в-друге ;) Примером реализации таких блоков являются списки и таблицы.
    Block/embed и embed. Работают так же как и обычные блоки, но с той лишь разницей, что контент который они встраивают не может быть отредактирован. Его можно перезагрузить или удалить, но не изменить. Это видео, формулы, изображения.
    Scroll blot. Представляет собой главный контейнер для всех остальных. Что он из себя представляет? По умолчанию это DIV элемент с классом ql-editor. Который может содержать следующие типы blot-ов:
    1. block
    2. embed
    3. container
    Ещё одной важной особенностью данного blot-а является то, что конструктор первым параметром принимает специальный объект - регистр. Сейчас об регистрах quill рано говорить, но скажем так, каждый регистр это уникальный набор кнопок и форматеров для редактирования текста. То есть, на одной странице можно иметь несколько текстовых редакторов со своим уникальным функционалом.
    Break blot. Это специальный нулевой-элемент. В Parchment библиотеке, каждый контейнер, у которого могут быть дети, должен иметь хотя бы одного. И под роль начального элемента создали этот blot.
    Text blot. Представляет собой обычную обёртку вокруг текста
    Cursor blot. Представляет собой вертикальную линию при редактировании. И знает, где и на каком блоке она находится.

    Расширяем функционал blot-ов по умолчанию, их методы

    В этой главе я собрал, все возможные методы для переопределения и набросал своих комментарий по поводу их работы. Сделал я это, ибо официальный сайт не обладает такой информацией, хотя его всё ещё можно найти через консоль браузера.

    Block blot

    Методы для собственной имплементации. Исходный код -> https://github.com/slab/parchment/blob/main/src/blot/block.ts
    static create(value?: unknown); static formats(domNode: HTMLElement, scroll: Root): any; constructor(scroll: Root, domNode: Node); format(name: string, value: any): void; formats(): { [index: string]: any }; formatAt( index: number, length: number, name: string, value: any ): void; insertAt(index: number, value: string, def?: any): void; replaceWith(name: string | Blot, value?: any): Blot; deleteAt(index: number, length: number): void; delta(): void; insertBefore(blot: Blot, ref?: Blot | null): void; length(): number; moveChildren(target: Parent, ref?: Blot | null): void; optimize(context: { [key: string]: any }): void; path(index: number) [Blot, number][]; removeChild(child: Blot): void; split(index: number, force: boolean | undefined = false): Blot | null;
    Переменные и их значения по умолчанию:
    static blotName = 'block'; static scope = Scope.BLOCK_BLOT; static tagName: string | string[] = 'P'; static allowedChildren: BlotConstructor[] = [InlineBlot, BlockBlot, LeafBlot ]; length: number; name: string;

    Inline blot

    Методы для собственной имплементации. Исходный код -> https://github.com/slab/parchment/blob/main/src/blot/inline.ts
    static create(value?: unknown): Node; static formats(domNode: HTMLElement, scroll: Root): any; static compare(self: string, other: string): number; constructor(scroll: Root, domNode: Node); format(name: string, value: any): void; formats(): { [index: string]: any }; formatAt( index: number, length: number, name: string, value: any ): void; optimize(context: { [key: string]: any }): void; replaceWith(name: string | Blot, value?: any): Blot; replaceWith(name: string | Blot, value?: any): Blot; update( mutations: MutationRecord[], context: { [key: string]: any } ): void; public wrap(name: string | Parent, value?: any): Parent;
    Переменные и их значения по умолчанию:
    static blotName = 'inline'; static order = [ 'cursor', 'inline', 'link', 'underline', 'strike', 'italic', 'bold', 'script', 'code', ]; static scope = Scope.INLINE_BLOT; static tagName: string | string[] = 'SPAN'; static allowedChildren: BlotConstructor[] = [InlineBlot, LeafBlot ]; length: number; name: string;

    Embed blot

    Методы для собственной имплементации. Исходный код -> https://github.com/slab/parchment/blob/main/src/blot/embed.ts
    static create(value?: unknown): Node; static formats(_domNode: HTMLElement, _scroll: Root): any; constructor(scroll: Root, domNode: Node); format(name: string, value: any): void; formatAt( index: number, length: number, name: string, value: any ): void; formats(): { [index: string]: any }; index(node: Node, offset: number): number; restore(node: Text): EmbedContextRange | null; update(mutations: MutationRecord[], context: Record<string, unknown>): void;
    Переменные и их значения по умолчанию:
    static scope = Scope.INLINE_BLOT; length: number; name: string; contentNode: HTMLSpanElement; leftGuard: Text; rightGuard: Text;

    Cursor blot

    Методы для собственной имплементации.
    static create(value?: unknown): Node; static formats(_domNode: HTMLElement, _scroll: Root): any; constructor(scroll: ScrollBlot, domNode: HTMLElement, selection: Selection): void; detach(): void; format(name: string, value: unknown): void; formatAt( index: number, length: number, name: string, value: any ): void; formats(): { [index: string]: any }; index(node: Node, offset: number): number; length(): number; position(): [Text, number]; remove(): void; restore(): EmbedContextRange | null; update(mutations: MutationRecord[], context: Record<string, unknown>): void; optimize(context?: unknown): void; value() string; // Will return ''
    Переменные и их значения по умолчанию:
    static blotName = 'cursor'; static className = 'ql-cursor'; static tagName = 'span'; static CONTENTS = '\uFEFF'; // Zero width no break space length: number; name: string;

    Text blot

    Методы для собственной имплементации. Исходный код -> https://github.com/slab/parchment/blob/main/src/blot/text.ts
    static create(value: string): Node; static value(domNode: Text): string; constructor(scroll: Root, node: Node); deleteAt(index: number, length: number): void; index(node: Node, offset: number): number; insertAt(index: number, value: string, def?: any): void; length(): number optimize(context: { [key: string]: any }): void; position(index: number, _inclusive = false): [Node, number]; split(index: number, force = false): Blot | null; update( mutations: MutationRecord[], _context: { [key: string]: any } ): void; value(): string;
    Переменные и их значения по умолчанию:
    static readonly blotName = 'text'; domNode: Text; static scope = Scope.INLINE_BLOT;

    Container blot

    Методы для собственной имплементации. Исходный код -> https://github.com/slab/parchment/blob/main/src/blot/abstract/container.ts
    static create(value: string): Node; constructor(scroll: Root, domNode: Node); checkMerge(): boolean; deleteAt(index: number, length: number): void ; formatAt( index: number, length: number, name: string, value: any ): void; optimize(context: { [key: string]: any }): void; insertAt(index: number, value: string, def?: any): void;
    Переменные и их значения по умолчанию:
    static blotName = 'container'; static scope = Scope.BLOCK_BLOT; static tagName: string | string[]; prev: BlockBlot | ContainerBlot | null; next: BlockBlot | ContainerBlot | null;

    Scroll blot

    Методы для собственной имплементации. Исходный код -> https://github.com/slab/parchment/blob/main/src/blot/scroll.ts
    static create(value: string): Node; constructor( public registry: Registry, node: HTMLDivElement, { emitter }: { emitter: Emitter } ); batchStart(): void; batchEnd(): void; emitMount(blot: Blot): void; emitUnmount(blot: Blot): void; emitEmbedUpdate(blot: Blot, change: unknown): void; deleteAt(index: number, length: number): void; enable(enabled = true): void; formatAt(index: number, length: number, format: string, value: unknown): void; insertAt(index: number, value: string, def?: unknown): void; insertBefore(blot: Blot, ref?: Blot | null): void; insertContents(index: number, delta: Delta): void; isEnabled(): boolean; leaf(index: number): [LeafBlot | null, number]; line(index: number): [Block | BlockEmbed | null, number]; lines(index = 0, length = Number.MAX_VALUE): (Block | BlockEmbed)[] optimize(context?: { [key: string]: any }): void; optimize( mutations?: MutationRecord[], context?: { [key: string]: any }): void; optimize(mutations = [], context = {}): void; path(index: number): number; remove(): void; // Do nothing update(source?: EmitterSource): void; update(mutations?: MutationRecord[]): void; update(mutations?: MutationRecord[] | EmitterSource): void; updateEmbedAt(index: number, key: string, change: unknown): void;
    Переменные и их значения по умолчанию:
    static blotName = 'scroll'; static className = 'ql-editor'; static tagName = 'DIV'; static defaultChild = Block; static allowedChildren = [Block, BlockEmbed, Container]; emitter: Emitter; batch: false | MutationRecord[];

    Как создать новый blot из старого или переопределить существующий

    Для примера переопределения существующего blot-а я буду использовать block blot. Начнём с импорта.
    let Block = Quill.import('blots/block');
    Дальше, нужно определить новый функционал blot-а. В моём случае, я хочу чтобы вместо тега <p> использовался <div> и добавлялся класс по имени "txt". Вот так я это сделаю:
    Block.tagName = 'div' class TextBlock extends Block{ static create(value){ let node = super.create(value); node.setAttribute('class','txt'); return node; } } // Регистрируем (обновляем blot block) Quill.register(TextBlock, true)
    Это по части модификации blot-ов. Но как сделать новый? У любого quill-блока есть 3 переменные, которые используются для отличия одного блока от другого. Первый это tagName, второй blotName и третий className.
    Для создания нового blot-а, нужно задать другое значение для blotName. Я продемонстрирую это на примере ссылок. Мы создадим 2 варианта ссылок:
    1. Внутренние ссылки
    2. Внешние ссылки
    // Импортируем необходимый blot let Inline = Quill.import('blots/inline') // Задаём значения для нового blot-а внутренней ссылки class InternalLink extends Inline{ constructor(scroll, domNode){ super(scroll, domNode); domNode.addEventListener('click', (ev) => { domNode.setAttribute('ref', 'me') }) } } InternalLink.tagName = 'a' InternalLink.className = 'ref-int' // Меняем имя blot-а InternalLink.blotName = 'internal-link' // Регистрируем новый форматер Quill.register({'formats/internal-link': InternalLink}) // Задаём значения для нового blot-а внешней ссылки class ExternalLink extends Inline{ constructor(scroll, domNode){ super(scroll, domNode); domNode.setAttribute('target', '_blank') domNode.setAttribute('ref', 'noreferrer nofollow external') } } ExternalLink.tagName = 'a' ExternalLink.className = 'ref-ext' // Меняем имя blot-а ExternalLink.blotName = 'external-link' // Регистрируем новый форматер Quill.register({'formats/external-link': ExternalLink})
    Ты наверное думаешь, что такое этот "форматер". Но по сути, я просто сделал кнопку для создания и удаления этого типа blot-а в редакторе.

    Не забудь поделиться, лайкнуть и оставить комментарий)

    Комментарии

    (0)

    captcha
    Отправить
    ЗАГРУЗКА ...
    Сейчас тут пусто. Буть первым (o゚v゚)ノ

    Другое

    Похожие статьи


    Quill formats (ql-formats), как их расширить и существующие виды

    Часы
    24.10.2024
    /
    Часы
    02.10.2025
    Глазик
    707
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    В этой статье я разберу типы форматеров (formats) quilljs, и объясню некоторые нюансы работы с таблицами, шрифтами, изображениями и видео. Так же покажу как переопределить форматер(ql-formats) на примере ссылки

    Как сделать собственный quill link tooltip(тултип для ссылок)

    Часы
    25.10.2024
    /
    Часы
    02.10.2025
    Глазик
    454
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    В этой статье ты найдёшь пример того как реализовать свой quill tooltip/тултип для вставки ссылок и поймёшь как это вообще работает

    Как сделать custom quill модуль оглавления статьи

    Часы
    29.10.2024
    /
    Часы
    02.10.2025
    Глазик
    345
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    В этой статье я покажу как сделать собственный модуль для QuillJS. Этот модуль будет генерировать оглавление статьи. Так же покажу как включать и отключать модули.

    Использованные термины


    Релевантные вопросы