fix(): 粘贴导致换行消失

This commit is contained in:
yanmao 2021-11-20 18:24:25 +08:00
parent c1cf65a254
commit c30fcbd044
8 changed files with 41 additions and 30 deletions

View File

@ -72,9 +72,12 @@ class ChangeModel implements ChangeInterface {
private _change() {
if (!this.isComposing()) {
this.engine.card.gc();
console.time('change');
const value = this.getValue({
ignoreCursor: true,
});
console.timeEnd('change');
if (!this.valueCached || value !== this.valueCached) {
const trigger =
this.changeTrigger.length === 2
@ -243,6 +246,8 @@ class ChangeModel implements ChangeInterface {
return new Parser(
container.get<HTMLElement>()?.outerHTML || '',
this.engine,
undefined,
false,
).toValue(schema, conversion);
}

View File

@ -105,6 +105,8 @@ export default class Paste {
node.remove();
if (!parent) return;
node = parent;
parent = node.parent();
if (!parent) return;
}
// 删除 google docs 根节点
// <b style="font-weight:flat;" id="docs-internal-guid-e0280780-7fff-85c2-f58a-6e615d93f1f2">

View File

@ -281,7 +281,11 @@ export default class Clipboard implements ClipboardInterface {
// 合并列表
this.editor.list.merge(listNodes);
const parser = new Parser(contents, this.editor);
let { html, text } = parser.toHTML(inner, outter);
let html = parser.toHTML(inner, outter);
const text = new Parser(html, this.editor).toText(
this.editor.schema,
true,
);
if (callback) {
callback({ html, text });
}

View File

@ -319,7 +319,7 @@ class Engine implements EngineInterface {
node.removeAttributes('spellcheck');
node.removeAttributes('data-gramm');
node.removeAttributes('role');
return new Parser(node, this).toHTML().html;
return new Parser(node, this).toHTML();
}
setValue(value: string, callback?: (count: number) => void) {

View File

@ -58,12 +58,18 @@ const stylesToString = (styles: { [k: string]: string }) => {
class Parser implements ParserInterface {
root: NodeInterface;
private editor: EditorInterface;
/**
* false可以提升性能ture的时候可以对不确定的html进行转换
*/
private isNormalize = true;
constructor(
source: string | Node | NodeInterface,
editor: EditorInterface,
paserBefore?: (node: NodeInterface) => void,
isNormalize: boolean = true,
) {
this.editor = editor;
this.isNormalize = isNormalize;
const { node } = this.editor;
if (typeof source === 'string') {
source = source.replace(/<a\s{0,1000}\/>/gi, '<a></a>');
@ -114,8 +120,12 @@ class Parser implements ParserInterface {
)
return;
if (node.isElement()) {
const isCard = node.isCard();
//转换标签
if (conversion && (!schema.getType(node) || node.isCard())) {
if (
conversion &&
((this.isNormalize && !schema.getType(node)) || isCard)
) {
let value = conversion.transform(node);
const oldRules: Array<ConversionRule> = [];
while (value) {
@ -130,10 +140,7 @@ class Parser implements ParserInterface {
});
//把旧节点的子节点追加到新节点下
newNode.append(node.children());
if (
node.attributes(CARD_KEY) ||
node.attributes(READY_CARD_KEY)
) {
if (isCard) {
node.before(newNode);
node.remove();
value = undefined;
@ -156,11 +163,7 @@ class Parser implements ParserInterface {
);
}
}
if (
node.attributes(CARD_KEY) ||
node.attributes(READY_CARD_KEY)
)
return;
if (!this.isNormalize || isCard) return;
//分割
const filter = (node: NodeInterface) => {
//获取节点属性样式
@ -473,26 +476,15 @@ class Parser implements ParserInterface {
}
this.editor.trigger('parse:html-before', this.root);
element.traverse((domNode) => {
const node = domNode.get<HTMLElement>();
if (
node &&
node.nodeType === Node.ELEMENT_NODE &&
'none' === node.style['user-select'] &&
node.parentNode
) {
node.parentNode.removeChild(node);
if (domNode.isText()) return;
if (domNode.css('user-select') === 'none') {
domNode.remove();
}
});
this.editor.trigger('parse:html', element);
element.find('p').css(this.editor.container.css());
this.editor.trigger('parse:html-after', element);
return {
html: element.html(),
text: new Parser(element, this.editor).toText(
this.editor.schema,
true,
),
};
return element.html();
}
/**

View File

@ -78,7 +78,7 @@ export interface ParserInterface {
* @param inner
* @param outter
*/
toHTML(inner?: Node, outter?: Node): { html: string; text: string };
toHTML(inner?: Node, outter?: Node): string;
/**
* DOM树

View File

@ -620,7 +620,7 @@ export default class extends MarkPlugin<Options> {
: Range.create(this.editor)
).cloneRange();
const parser = new Parser(container, this.editor);
const parser = new Parser(container, this.editor, undefined, false);
const { schema, conversion } = this.editor;
if (!range) {
container.remove();
@ -697,7 +697,7 @@ export default class extends MarkPlugin<Options> {
: Range.create(this.editor)
).cloneRange();
const parser = new Parser(container, this.editor);
const parser = new Parser(container, this.editor, undefined, false);
const { schema, conversion } = this.editor;
if (!range) {
container.remove();

View File

@ -206,6 +206,14 @@ class Table extends Plugin<Options> {
}
pasteSchema(schema: SchemaInterface) {
schema.data.blocks.forEach((blockSchema) => {
if (!blockSchema.allowIn) {
blockSchema.allowIn = [];
}
if (blockSchema.allowIn.indexOf('td') < 0) {
blockSchema.allowIn.push('td');
}
});
schema.find((r) => r.name === 'table')[0].attributes = {
class: ['data-table'],
'data-table-no-border': '*',