From 0b9e0de79fadcf34a98da5caee3f247539049443 Mon Sep 17 00:00:00 2001 From: yanmao <55792257+yanmao-cc@users.noreply.github.com> Date: Mon, 20 Dec 2021 15:47:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A1=A8=E6=A0=BC=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E8=AF=84=E8=AE=BA=E6=A0=87=E8=AE=B0=E4=B8=A2?= =?UTF-8?q?=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/engine/src/change/index.ts | 12 ++++ packages/engine/src/node/entry.ts | 2 +- packages/engine/src/ot/consumer.ts | 3 +- plugins/mark-range/src/index.ts | 99 ++++++++++++++++++++-------- plugins/table/src/component/index.ts | 17 +++-- plugins/table/src/types.ts | 14 ++-- 6 files changed, 105 insertions(+), 42 deletions(-) diff --git a/packages/engine/src/change/index.ts b/packages/engine/src/change/index.ts index 34406f26..fa4088bf 100644 --- a/packages/engine/src/change/index.ts +++ b/packages/engine/src/change/index.ts @@ -120,6 +120,18 @@ class ChangeModel implements ChangeInterface { if (editableElement && editableElement.length > 0) { const card = this.engine.card.find(editableElement, true); if (card?.onChange) card?.onChange(trigger, editableElement); + } else { + applyNodes?.forEach((node) => { + editableElement = node.closest(EDITABLE_SELECTOR); + if (editableElement && editableElement.length > 0) { + const card = this.engine.card.find( + editableElement, + true, + ); + if (card?.onChange) + card?.onChange(trigger, editableElement); + } + }); } } diff --git a/packages/engine/src/node/entry.ts b/packages/engine/src/node/entry.ts index d853ee39..dd0b3999 100644 --- a/packages/engine/src/node/entry.ts +++ b/packages/engine/src/node/entry.ts @@ -172,7 +172,7 @@ class NodeEntry implements NodeInterface { attributes[DATA_ELEMENT] === EDITABLE || attributes[CARD_EDITABLE_KEY] === 'true' || (this.isElement() && - !!(this[0] as Element).querySelector(EDITABLE_SELECTOR)) + !!this.get()?.querySelector(EDITABLE_SELECTOR)) ); } diff --git a/packages/engine/src/ot/consumer.ts b/packages/engine/src/ot/consumer.ts index ef9d6d9d..3d074afa 100644 --- a/packages/engine/src/ot/consumer.ts +++ b/packages/engine/src/ot/consumer.ts @@ -352,7 +352,8 @@ class Consumer implements ConsumerInterface { const applyNode = this.handleOperation(op); if (applyNode) applyNodes.push(applyNode); }); - this.engine.change.change(); + if (ops.some((op) => !isCursorOp(op))) + this.engine.change.change(false, applyNodes); return applyNodes; } diff --git a/plugins/mark-range/src/index.ts b/plugins/mark-range/src/index.ts index 65db97c4..9b7bdba8 100644 --- a/plugins/mark-range/src/index.ts +++ b/plugins/mark-range/src/index.ts @@ -13,6 +13,9 @@ import { Selection, PluginOptions, uuid, + EDITABLE_SELECTOR, + CARD_SELECTOR, + transformCustomTags, } from '@aomao/engine'; import { Path } from 'sharedb'; @@ -393,6 +396,15 @@ export default class extends MarkPlugin { //设置新的id串 mark.attributes(this.getIdName(key), ids.join(',')); mark.removeAttributes(this.getPreviewName(key)); + const editableCard = mark.closest(EDITABLE_SELECTOR); + if (editableCard.length > 0) { + const cardComponent = this.editor.card.find( + editableCard, + true, + ); + if (cardComponent && cardComponent.onChange) + cardComponent.onChange('local', cardComponent.root); + } }); this.#isApply = true; } @@ -458,6 +470,7 @@ export default class extends MarkPlugin { .split(','); if (oldIds[0] === '') oldIds.splice(0, 1); //移除标记样式包裹 + const editableCard = mark.closest(EDITABLE_SELECTOR); if (oldIds.length === 1 && !!oldIds.find((i) => i === id)) { if (mark.isCard()) { mark.removeAttributes(this.MARK_KEY); @@ -474,6 +487,11 @@ export default class extends MarkPlugin { oldIds.splice(index, 1); mark.attributes(this.getIdName(key), oldIds.join(',')); } + if (editableCard.length > 0) { + const cardComponent = this.editor.card.find(editableCard, true); + if (cardComponent && cardComponent.onChange) + cardComponent.onChange('local', cardComponent.root); + } }); } @@ -621,9 +639,9 @@ export default class extends MarkPlugin { clip: 'rect(0, 0, 0, 0)', }); $(document.body).append(container); - if (value) container.html(value); + if (value) container.html(transformCustomTags(value)); - card.render(container); + card.render(container, undefined, false); const selection = container.window?.getSelection(); const range = ( @@ -645,33 +663,47 @@ export default class extends MarkPlugin { range.select(container, true).collapse(true); const paths: Array<{ id: Array; path: Array }> = []; - container.traverse((childNode) => { - const id = childNode.attributes(this.getIdName(key)); - if (!!id) { - const rangeClone = range.cloneRange(); + container.traverse( + (childNode) => { + const id = childNode.attributes(this.getIdName(key)); + if (!!id) { + const rangeClone = range.cloneRange(); - if (childNode.isCard()) { - rangeClone.select(childNode); - childNode.removeAttributes(this.getIdName(key)); - } else { - rangeClone.select(childNode, true); - const selection = rangeClone.createSelection(); - node.unwrap(childNode); - selection.move(); + if (childNode.isCard()) { + rangeClone.select(childNode); + childNode.removeAttributes(this.getIdName(key)); + } else { + rangeClone.select(childNode, true); + const selection = rangeClone.createSelection(); + node.unwrap(childNode); + selection.move(); + } + const rangePath = rangeClone + .shrinkToElementNode() + .shrinkToTextNode() + .toPath(undefined, container); + paths.push({ + id: id.split(','), + path: rangePath + ? [rangePath.start.path, rangePath.end.path] + : [], + }); + } + }, + false, + true, + ); + const cardNodes = container.find(CARD_SELECTOR); + cardNodes.each((_, index) => { + const cardNode = cardNodes.eq(index); + if (cardNode?.isEditableCard()) { + const card = this.editor.card.find(cardNode); + if (card) { + const value = card.getValue(); + card.setValue(value || {}); } - const rangePath = rangeClone - .shrinkToElementNode() - .shrinkToTextNode() - .toPath(undefined, container); - paths.push({ - id: id.split(','), - path: rangePath - ? [rangePath.start.path, rangePath.end.path] - : [], - }); } - }, false); - + }); value = parser.toValue(schema, conversion); container.remove(); return { @@ -699,9 +731,9 @@ export default class extends MarkPlugin { clip: 'rect(0, 0, 0, 0)', }); $(document.body).append(container); - if (value) container.html(value); + if (value) container.html(transformCustomTags(value)); - card.render(container); + card.render(container, undefined, false); const selection = container.window?.getSelection(); const range = ( selection @@ -743,6 +775,17 @@ export default class extends MarkPlugin { pathRange, ); }); + const cardNodes = container.find(CARD_SELECTOR); + cardNodes.each((_, index) => { + const cardNode = cardNodes.eq(index); + if (cardNode?.isEditableCard()) { + const card = this.editor.card.find(cardNode); + if (card) { + const value = card.getValue(); + card.setValue(value || {}); + } + } + }); value = parser.toValue(schema, conversion); container.remove(); return value; diff --git a/plugins/table/src/component/index.ts b/plugins/table/src/component/index.ts index f5a45a3f..1a5debe4 100644 --- a/plugins/table/src/component/index.ts +++ b/plugins/table/src/component/index.ts @@ -3,6 +3,7 @@ import { Card, CardToolbarItemOptions, CardType, + CardValue, EDITABLE_SELECTOR, isEngine, isMobile, @@ -344,12 +345,13 @@ class TableComponent extends Card implements TableInterface { this.alignToolButton?.html(alignHtml); } - getTableValue() { - if (!this.wrapper) return; + getValue() { + const value = super.getValue() as TableValue; + if (!this.wrapper) return value; const tableRoot = this.wrapper.find(Template.TABLE_CLASS); - if (!tableRoot) return; + if (!tableRoot) return value; const { tableModel } = this.selection; - if (!tableModel) return; + if (!tableModel) return value; const { schema, conversion } = this.editor; const container = $('
'); container.append(tableRoot.clone(true)); @@ -362,6 +364,7 @@ class TableComponent extends Card implements TableInterface { const { rows, cols, height, width } = tableModel; const html = parser.toValue(schema, conversion, false, true); return { + ...value, rows, cols, height, @@ -446,12 +449,12 @@ class TableComponent extends Card implements TableInterface { this.#changeTimeout = setTimeout(() => { this.conltrollBar.refresh(); this.selection.render('change'); - const oldValue = this.getValue(); + const oldValue = super.getValue(); if (oldValue?.noBorder) { this.noBorderToolButton?.addClass('active'); } else this.noBorderToolButton?.removeClass('active'); if (trigger === 'local') { - const value = this.getTableValue(); + const value = this.getValue(); if (value) this.setValue(value); } }, 100); @@ -624,7 +627,7 @@ class TableComponent extends Card implements TableInterface { if (!tableRoot) return; const value = this.getValue(); if (!value?.html) { - const tableValue = this.getTableValue(); + const tableValue = this.getValue(); if (tableValue) this.setValue(tableValue); this.onChange(); } diff --git a/plugins/table/src/types.ts b/plugins/table/src/types.ts index b4d1d1ad..c5bf5793 100644 --- a/plugins/table/src/types.ts +++ b/plugins/table/src/types.ts @@ -1,4 +1,9 @@ -import { CardInterface, ClipboardData, NodeInterface } from '@aomao/engine'; +import { + CardInterface, + CardValue, + ClipboardData, + NodeInterface, +} from '@aomao/engine'; import { EventEmitter2 } from 'eventemitter2'; export interface HelperInterface { @@ -99,7 +104,8 @@ export interface TemplateInterface { renderColsHeader(rows: number): string; } -export type TableValue = { +export interface TableValue extends CardValue { + id: string; rows: number; cols: number; width?: number; @@ -108,7 +114,7 @@ export type TableValue = { color?: string; noBorder?: boolean; overflow?: boolean; -}; +} export type TableMenuItem = { action?: string; @@ -154,8 +160,6 @@ export interface TableInterface extends CardInterface { * 渲染 */ render(): string | NodeInterface | void; - - getTableValue(): TableValue | undefined; } export type ControllOptions = {