Рецепты: click, double-click, меню и сквозной сценарий
Реакция на клик и двойной клик, контекстное меню для ячейки таблицы, выполнение внешней команды и полный сценарий транспортной системы от события до DOCX.
Конкретные примеры click, double-click и меню
Заголовок раздела «Конкретные примеры click, double-click и меню»7.1. Реакция на click / double-click
Заголовок раздела «7.1. Реакция на click / double-click»- ПРЕДЛАГАЕМЫЙ — API; BUSINESS ACTION НЕ ПРАВИТ DOCX НАПРЯМУЮ
editor.interactions.on("elementActivated", async (event) => { const { gesture, target } = event;
if (gesture === "click" && target.kind === "comment") { hostSidebar.openComment(target.nodeId); }
if (gesture === "doubleClick" && target.hostData?.type === "shipment") { await hostApp.openShipment(target.hostData.id); }});7.2. Контекстное меню для ячейки таблицы
Заголовок раздела «7.2. Контекстное меню для ячейки таблицы»ПРЕДЛАГАЕМЫЙ ДЕКЛАРАТИВНЫЙ PROVIDER
editor.contextMenu.registerProvider("transport-suite", async (ctx) => { if (ctx.target.kind !== "tableCell") return [];
return [ { id: "transport.openCargo", label: "Открыть карточку груза", enabled: Boolean(ctx.target.hostData?.id) }, { id: "transport.bindRoute", label: "Привязать к маршруту", enabled: !ctx.readOnly }, { type: "separator" }, { id: "a4.table.insertRowBelow", label: "Вставить строку ниже", command: { type: "insert_table_row", position: "below" } } ];});7.3. Выполнение внешний команды
Заголовок раздела «7.3. Выполнение внешний команды»ПРЕДЛАГАЕМЫЙ COMMAND DISPATCH; RUST ВОЗВРАЩАЕТ RECEIPT
editor.commands.register("transport.bindRoute", async (ctx) => { const route = await hostUi.chooseRoute(); if (!route) return;
return ctx.session.execute({ operationId: crypto.randomUUID(), expectedRevision: ctx.revision, target: ctx.target, command: { type: "replace_target_text", text: route.displayName } });});| Почему меню декларативное внешнее приложение возвращает ID, label, state и typed command, а A4 рисует меню и проверяет capability. Это сохраняет единое поведение, локализацию, accessibility и безопасность; произвольный HTML/JS внутри canvas не требуется. |
|---|
Сценарий транспортной системы от события до DOCX
Заголовок раздела «Сценарий транспортной системы от события до DOCX»Пример: правый клик по строке «Груз / Маршрут / Статус»
Заголовок раздела «Пример: правый клик по строке «Груз / Маршрут / Статус»»-
Пользователь делает right-click. Surface переводит client coordinates в координаты страницы и вызывает canonical hit-test.
-
A4 возвращает target. Например tableCell с nodeId, row/column identity, ancestors и revision 42.
-
A4 запрашивает providers. внешнее приложение получает только нормализованный context, а не DOM-ссылку.
-
Provider добавляет действия. «Открыть карточку груза» и «Привязать к маршруту» появляются рядом с разрешёнными встроенными пунктами.
-
Пользователь выбирает маршрут. Business UI возвращает route ID; document command формируется отдельно.
-
Rust принимает или отклоняет. expectedRevision и capability исключают применение к устаревшей или неподходящей цели.
-
Поверхность обновляется. contentChanged/commandStateChanged доставляют новый revision; affected scene pages перерисовываются.
-
Save/reopen подтверждает результат. DOCX сохраняется отдельным путём или атомарно публикуется и повторно читается model-docx.
Пример нормализованного context payload
Заголовок раздела «Пример нормализованного context payload»ПРЕДЛАГАЕМЫЙ WIRE PAYLOAD
{ "schema": "a4.-interaction-context.v1", "gesture": "contextMenu", "revision": 42, "readOnly": false, "target": { "kind": "tableCell", "nodeId": "body.block[18].row[2].cell[1]", "ancestors": [{"kind":"table","nodeId":"body.block[18]"}], "capabilities": ["read","editText","insertRow"], "hostData": {"type":"shipment","id":"SHP-009173"} }, "hit": {"pageIndex":3,"xMilliPx":412000,"yMilliPx":286000}}Обработка конфликта revision
Заголовок раздела «Обработка конфликта revision»РЕКОМЕНДУЕМАЯ ПРЕДСКАЗУЕМАЯ ОШИБКА
{ "ok": false, "error": { "code": "revision_conflict", "expectedRevision": 42, "actualRevision": 43, "retry": "refresh_target_and_command_state" }}