Каким образом можно добавить новый функционал в редактор ProseMirror?

Здравствуйте. У меня есть задача по добавлению функционала чекбоксов для формирования todo-листа в редакторе ProseMirror в проекте на HumHub. Этот проект написан на Yii и не использует JS-фреймворки на фронтенде. Я пытаюсь реализовать это, опираясь на пример из <a href="http://https//glitch.com/edit/#!/grave-governor?path=index.js%3A70%3A0" rel="nofollow">ссылки</a>, но сталкиваюсь с трудностями, так как реализация в HumHub отличается от предоставленных примеров. 

В проекте файл, который меня интересует, находится по пути: /protected/humhub/modules/content/resources/js/humhub.ui.richtext.prosemirror.js.

Вот некоторые фрагменты кода: 
<pre><code class="javascript">/*
 * @link https://www.humhub.org/
 * @copyright Copyright (c) 2018 HumHub GmbH &amp; Co. KG
 * @license https://www.humhub.com/licences
 * @since 1.8
 */
humhub.module('ui.richtext.prosemirror', function(module, require, $) {
    // Ваш код
</pre> 

Можно ли получить рекомендации по тому, как лучше всего интегрировать эту функциональность в существующую архитектуру HumHub?
  • 18 октября 2024 г. 13:22
Ответы на вопрос 1
Добавление функционала чекбоксов для создания todo-листа в редактор ProseMirror требует несколько шагов, включая определение нового узла, создание плагина и интеграцию в существующий редактор. Давайте рассмотрим процесс поэтапно:

### 1. Определение нового узла

Сначала необходимо создать новый тип узла (node) для чекбоксов. В ProseMirror это можно сделать, определив schema, в которой вы опишете новый узел. Пример кода для нового узла может выглядеть следующим образом:

```javascript
import { Node } from "prosemirror-model";

const checkboxNode = {
    group: "block",
    inline: false,
    atom: true,
    attrs: {
        checked: { default: false }
    },
    toDOM(node) {
        const checked = node.attrs.checked ? "checked" : "";
        return ["div", { class: "todo-item" }, ["input", { type: "checkbox", checked }], ["span", node.textContent]];
    },
    parseDOM: [{
        tag: "div.todo-item",
        getAttrs(dom) {
            return { checked: dom.querySelector('input[type="checkbox"]').checked };
        }
    }]
};

// Добавление нового узла к схемам ProseMirror
schema.nodes.checkbox = checkboxNode;
```

### 2. Создание плагина

Затем нужно создать плагин, который будет обрабатывать вставку нового узла, когда вы хотите добавить чекбокс. Пример кода для плагина может выглядеть так:

```javascript
import { Plugin } from "prosemirror-state";

const checkboxPlugin = new Plugin({
    key: new PluginKey('checkbox'),
    props: {
        handleKeyDown(view, event) {
            if (event.key === 'Enter' && event.ctrlKey) {
                const { state, dispatch } = view;

                const { schema } = state;
                const transaction = state.tr.replaceSelectionWith(schema.nodes.checkbox.create());
                dispatch(transaction);
                return true; // предотвращает стандартное поведение
            }
            return false; // позволяем другим обработчикам обрабатывать событие
        }
    }
});
```

### 3. Интеграция с существующим редактором

Теперь интегрируйте новый узел и плагин в вашу схему ProseMirror и редактор. Это делается в файле `/protected/humhub/modules/content/resources/js/humhub.ui.richtext.prosemirror.js`.

```javascript
humhub.module('ui.richtext.prosemirror', function(module, require, $) {
    const { schema } = require('prosemirror-schema-basic');

    // Определить новый узел
    schema.nodes.checkbox = checkboxNode;

    // Добавить плагин для чекбоксов
    const plugins = [
        checkboxPlugin,
        // остальные плагины
    ];

    // Создание экземпляра редактора ProseMirror
    const editorView = new EditorView(document.querySelector("#editor"), {
        state: EditorState.create({
            schema,
            plugins
        })
    });
});
```

### 4. Обработка визуализации и взаимодействия

Не забудьте добавить CSS для стилизации вашего чекбокса и настройки визуального представления. Также можно добавить функции для получения состояния чекбоксов при отправке формы и их сохранения на сервере.

### Заключение

Этот процесс может потребовать некоторых дополнительных шагов в зависимости от особенностей вашего проекта и требований UX. Главное, чтобы контролировать, как сохраняются и восстанавливаются данные с сервером, чтобы убедиться, что чекбоксы отображаются правильно после перезагрузки страницы. 

Если возникнут сложности или потребуется более глубокая интеграция, обязательно ознакомьтесь с документацией ProseMirror и HumHub, чтобы понять особенности их архитектуры и API.
Похожие вопросы