mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 09:36:17 +08:00
refactor: refactor block2html in clipboard
This commit is contained in:
@@ -153,7 +153,7 @@ export class BlockHelper {
|
||||
|
||||
public async getEditableBlockPropertiesBySelectInfo(
|
||||
block: AsyncBlock,
|
||||
selectInfo: SelectBlock
|
||||
selectInfo?: SelectBlock
|
||||
) {
|
||||
const properties = block.getProperties();
|
||||
if (properties.text.value.length === 0) {
|
||||
@@ -169,13 +169,13 @@ export class BlockHelper {
|
||||
// Use deepClone method will throw incomprehensible error
|
||||
let textValue = JSON.parse(JSON.stringify(originTextValue));
|
||||
|
||||
if (selectInfo.endInfo) {
|
||||
if (selectInfo?.endInfo) {
|
||||
textValue = textValue.slice(0, selectInfo.endInfo.arrayIndex + 1);
|
||||
textValue[textValue.length - 1].text = text_value[
|
||||
textValue.length - 1
|
||||
].text.substring(0, selectInfo.endInfo.offset);
|
||||
}
|
||||
if (selectInfo.startInfo) {
|
||||
if (selectInfo?.startInfo) {
|
||||
textValue = textValue.slice(selectInfo.startInfo.arrayIndex);
|
||||
textValue[0].text = textValue[0].text.substring(
|
||||
selectInfo.startInfo.offset
|
||||
|
||||
@@ -1,31 +1,7 @@
|
||||
import { Protocol, BlockFlavorKeys } from '@toeverything/datasource/db-service';
|
||||
import { escape } from '@toeverything/utils';
|
||||
import { Editor } from '../editor';
|
||||
import { SelectBlock } from '../selection';
|
||||
import { ClipBlockInfo } from './types';
|
||||
|
||||
class DefaultBlockParse {
|
||||
public static html2block(el: Element): ClipBlockInfo[] | undefined | null {
|
||||
const tag_name = el.tagName;
|
||||
if (tag_name === 'DIV' || el instanceof Text) {
|
||||
return el.textContent?.split('\n').map(str => {
|
||||
const data = {
|
||||
text: escape(str),
|
||||
};
|
||||
return {
|
||||
type: 'text',
|
||||
properties: {
|
||||
text: { value: [data] },
|
||||
},
|
||||
children: [],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default class ClipboardParse {
|
||||
private editor: Editor;
|
||||
private static block_types: BlockFlavorKeys[] = [
|
||||
@@ -82,7 +58,7 @@ export default class ClipboardParse {
|
||||
|
||||
constructor(editor: Editor) {
|
||||
this.editor = editor;
|
||||
this.generate_html = this.generate_html.bind(this);
|
||||
// this.generate_html = this.generate_html.bind(this);
|
||||
this.parse_dom = this.parse_dom.bind(this);
|
||||
}
|
||||
// TODO: escape
|
||||
@@ -152,55 +128,6 @@ export default class ClipboardParse {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
public async generateHtml(): Promise<string> {
|
||||
const select_info = await this.editor.selectionManager.getSelectInfo();
|
||||
return await this.generate_html(select_info.blocks);
|
||||
}
|
||||
|
||||
public async page2html(): Promise<string> {
|
||||
const root_block_id = this.editor.getRootBlockId();
|
||||
if (!root_block_id) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const block_info = await this.get_select_info(root_block_id);
|
||||
return await this.generate_html([block_info]);
|
||||
}
|
||||
|
||||
private async get_select_info(blockId: string) {
|
||||
const block = await this.editor.getBlockById(blockId);
|
||||
if (!block) return null;
|
||||
const block_info: SelectBlock = {
|
||||
blockId: block.id,
|
||||
children: [],
|
||||
};
|
||||
const children_ids = block.childrenIds;
|
||||
for (let i = 0; i < children_ids.length; i++) {
|
||||
block_info.children.push(
|
||||
await this.get_select_info(children_ids[i])
|
||||
);
|
||||
}
|
||||
return block_info;
|
||||
}
|
||||
|
||||
private async generate_html(selectBlocks: SelectBlock[]): Promise<string> {
|
||||
let result = '';
|
||||
for (let i = 0; i < selectBlocks.length; i++) {
|
||||
const sel_block = selectBlocks[i];
|
||||
if (!sel_block || !sel_block.blockId) continue;
|
||||
const block = await this.editor.getBlockById(sel_block.blockId);
|
||||
if (!block) continue;
|
||||
const block_utils = this.editor.getView(block.type);
|
||||
const html = await block_utils.block2html(
|
||||
block,
|
||||
sel_block.children,
|
||||
this.generate_html
|
||||
);
|
||||
result += html;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { Editor } from '../editor';
|
||||
import { SelectBlock, SelectInfo } from '@toeverything/components/editor-core';
|
||||
import {
|
||||
AsyncBlock,
|
||||
SelectBlock,
|
||||
SelectInfo,
|
||||
} from '@toeverything/components/editor-core';
|
||||
import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types';
|
||||
import { Clip } from './clip';
|
||||
|
||||
@@ -83,4 +87,76 @@ export class ClipboardUtils {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async convertTextValue2HtmlBySelectInfo(
|
||||
blockOrBlockId: AsyncBlock | string,
|
||||
selectBlockInfo?: SelectBlock
|
||||
) {
|
||||
const block =
|
||||
typeof blockOrBlockId === 'string'
|
||||
? await this._editor.getBlockById(blockOrBlockId)
|
||||
: blockOrBlockId;
|
||||
const selectedProperties =
|
||||
await this._editor.blockHelper.getEditableBlockPropertiesBySelectInfo(
|
||||
block,
|
||||
selectBlockInfo
|
||||
);
|
||||
return this._editor.blockHelper.convertTextValue2Html(
|
||||
block.id,
|
||||
selectedProperties.text.value
|
||||
);
|
||||
}
|
||||
async convertBlock2HtmlBySelectInfos(
|
||||
blockOrBlockId: AsyncBlock | string,
|
||||
selectBlockInfos?: SelectBlock[]
|
||||
) {
|
||||
if (!selectBlockInfos) {
|
||||
const block =
|
||||
typeof blockOrBlockId === 'string'
|
||||
? await this._editor.getBlockById(blockOrBlockId)
|
||||
: blockOrBlockId;
|
||||
const children = await block?.children();
|
||||
return (
|
||||
await Promise.all(
|
||||
children.map(async childBlock => {
|
||||
const blockView = this._editor.getView(childBlock.type);
|
||||
return await blockView.block2html({
|
||||
editor: this._editor,
|
||||
block: childBlock,
|
||||
});
|
||||
})
|
||||
)
|
||||
).join('');
|
||||
}
|
||||
|
||||
return (
|
||||
await Promise.all(
|
||||
selectBlockInfos.map(async selectBlockInfo => {
|
||||
const block = await this._editor.getBlockById(
|
||||
selectBlockInfo.blockId
|
||||
);
|
||||
const blockView = this._editor.getView(block.type);
|
||||
return await blockView.block2html({
|
||||
editor: this._editor,
|
||||
block,
|
||||
selectInfo: selectBlockInfo,
|
||||
});
|
||||
})
|
||||
)
|
||||
).join('');
|
||||
}
|
||||
|
||||
async page2html() {
|
||||
const rootBlockId = this._editor.getRootBlockId();
|
||||
if (!rootBlockId) {
|
||||
return '';
|
||||
}
|
||||
const rootBlock = await this._editor.getBlockById(rootBlockId);
|
||||
const blockView = this._editor.getView(rootBlock.type);
|
||||
|
||||
return await blockView.block2html({
|
||||
editor: this._editor,
|
||||
block: rootBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,62 +50,38 @@ class Copy {
|
||||
const textClip = await this._getTextClip();
|
||||
clips.push(textClip);
|
||||
|
||||
// const htmlClip = await this._getHtmlClip();
|
||||
// clips.push(htmlClip);
|
||||
const htmlClip = await this._clipboardParse.generateHtml();
|
||||
htmlClip &&
|
||||
clips.push(new Clip(OFFICE_CLIPBOARD_MIMETYPE.HTML, htmlClip));
|
||||
const htmlClip = await this._getHtmlClip();
|
||||
|
||||
clips.push(htmlClip);
|
||||
// const htmlClip = await this._clipboardParse.generateHtml();
|
||||
// htmlClip &&
|
||||
// clips.push(new Clip(OFFICE_CLIPBOARD_MIMETYPE.HTML, htmlClip));
|
||||
|
||||
return clips;
|
||||
}
|
||||
|
||||
// private async _getHtmlClip(): Promise<Clip> {
|
||||
// const selectInfo: SelectInfo =
|
||||
// await this._editor.selectionManager.getSelectInfo();
|
||||
//
|
||||
// if (selectInfo.type === 'Range') {
|
||||
// const html = (
|
||||
// await Promise.all(
|
||||
// selectInfo.blocks.map(async selectBlockInfo => {
|
||||
// const block = await this._editor.getBlockById(
|
||||
// selectBlockInfo.blockId
|
||||
// );
|
||||
// const blockView = this._editor.getView(block.type);
|
||||
// const block2html = await blockView.block2html({
|
||||
// editor: this._editor,
|
||||
// block,
|
||||
// selectInfo: selectBlockInfo,
|
||||
// });
|
||||
//
|
||||
// if (
|
||||
// await this._editor.blockHelper.isBlockEditable(
|
||||
// block
|
||||
// )
|
||||
// ) {
|
||||
// const selectedProperties =
|
||||
// await this._editor.blockHelper.getEditableBlockPropertiesBySelectInfo(
|
||||
// block,
|
||||
// selectBlockInfo
|
||||
// );
|
||||
//
|
||||
// return (
|
||||
// block2html ||
|
||||
// this._editor.blockHelper.convertTextValue2Html(
|
||||
// block.id,
|
||||
// selectedProperties.text.value
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// return block2html;
|
||||
// })
|
||||
// )
|
||||
// ).join('');
|
||||
// console.log('html', html);
|
||||
// }
|
||||
//
|
||||
// return new Clip(OFFICE_CLIPBOARD_MIMETYPE.HTML, 'blockText');
|
||||
// }
|
||||
private async _getHtmlClip(): Promise<Clip> {
|
||||
const selectInfo: SelectInfo =
|
||||
await this._editor.selectionManager.getSelectInfo();
|
||||
|
||||
const htmlStr = (
|
||||
await Promise.all(
|
||||
selectInfo.blocks.map(async selectBlockInfo => {
|
||||
const block = await this._editor.getBlockById(
|
||||
selectBlockInfo.blockId
|
||||
);
|
||||
const blockView = this._editor.getView(block.type);
|
||||
return await blockView.block2html({
|
||||
editor: this._editor,
|
||||
block,
|
||||
selectInfo: selectBlockInfo,
|
||||
});
|
||||
})
|
||||
)
|
||||
).join('');
|
||||
|
||||
return new Clip(OFFICE_CLIPBOARD_MIMETYPE.HTML, htmlStr);
|
||||
}
|
||||
|
||||
private async _getAffineClip(): Promise<Clip> {
|
||||
const selectInfo: SelectInfo =
|
||||
|
||||
@@ -502,13 +502,7 @@ export class Editor implements Virgo {
|
||||
}
|
||||
|
||||
public async page2html(): Promise<string> {
|
||||
return '';
|
||||
// const parse = this.clipboard?.getClipboardParse();
|
||||
// if (!parse) {
|
||||
// return '';
|
||||
// }
|
||||
// const html_str = await parse.page2html();
|
||||
// return html_str;
|
||||
return this.clipboard?.clipboardUtils?.page2html?.();
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
@@ -8,5 +8,5 @@ export { Editor as BlockEditor } from './editor';
|
||||
export * from './selection';
|
||||
export { BlockDropPlacement, HookType, GroupDirection } from './types';
|
||||
export type { Plugin, PluginCreator, PluginHooks, Virgo } from './types';
|
||||
export { BaseView, getTextHtml } from './views/base-view';
|
||||
export { BaseView } from './views/base-view';
|
||||
export type { ChildrenView, CreateView } from './views/base-view';
|
||||
|
||||
@@ -135,13 +135,6 @@ export abstract class BaseView {
|
||||
return null;
|
||||
}
|
||||
|
||||
async block2html(
|
||||
block: AsyncBlock,
|
||||
children: SelectBlock[],
|
||||
generateHtml: (el: any[]) => Promise<string>
|
||||
): Promise<string> {
|
||||
return '';
|
||||
}
|
||||
async block2Text(
|
||||
block: AsyncBlock,
|
||||
// The selectInfo parameter is not passed when the block is selected in ful, the selectInfo.type is Range
|
||||
@@ -151,45 +144,12 @@ export abstract class BaseView {
|
||||
}
|
||||
|
||||
// TODO: Try using new methods
|
||||
// async block2html2(props: {
|
||||
// editor: Editor;
|
||||
// block: AsyncBlock;
|
||||
// // The selectInfo parameter is not passed when the block is selected in ful, the selectInfo.type is Range
|
||||
// selectInfo?: SelectBlock;
|
||||
// }) {
|
||||
// return '';
|
||||
// }
|
||||
async block2html(props: {
|
||||
editor: Editor;
|
||||
block: AsyncBlock;
|
||||
// The selectInfo parameter is not passed when the block is selected in ful, the selectInfo.type is Range
|
||||
selectInfo?: SelectBlock;
|
||||
}) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export const getTextHtml = (block: AsyncBlock) => {
|
||||
const generate = (textList: any[]) => {
|
||||
let content = '';
|
||||
textList.forEach(text_obj => {
|
||||
let text = text_obj.text || '';
|
||||
if (text_obj.bold) {
|
||||
text = `<strong>${text}</strong>`;
|
||||
}
|
||||
if (text_obj.italic) {
|
||||
text = `<em>${text}</em>`;
|
||||
}
|
||||
if (text_obj.underline) {
|
||||
text = `<u>${text}</u>`;
|
||||
}
|
||||
if (text_obj.inlinecode) {
|
||||
text = `<code>${text}</code>`;
|
||||
}
|
||||
if (text_obj.strikethrough) {
|
||||
text = `<s>${text}</s>`;
|
||||
}
|
||||
if (text_obj.type === 'link') {
|
||||
text = `<a href='${text_obj.url}'>${generate(
|
||||
text_obj.children
|
||||
)}</a>`;
|
||||
}
|
||||
content += text;
|
||||
});
|
||||
return content;
|
||||
};
|
||||
const text_list: any[] = block.getProperty('text').value;
|
||||
return generate(text_list);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user