fix(): 粘贴导致换行消失
This commit is contained in:
parent
c1cf65a254
commit
c30fcbd044
|
@ -72,9 +72,12 @@ class ChangeModel implements ChangeInterface {
|
||||||
private _change() {
|
private _change() {
|
||||||
if (!this.isComposing()) {
|
if (!this.isComposing()) {
|
||||||
this.engine.card.gc();
|
this.engine.card.gc();
|
||||||
|
console.time('change');
|
||||||
const value = this.getValue({
|
const value = this.getValue({
|
||||||
ignoreCursor: true,
|
ignoreCursor: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.timeEnd('change');
|
||||||
if (!this.valueCached || value !== this.valueCached) {
|
if (!this.valueCached || value !== this.valueCached) {
|
||||||
const trigger =
|
const trigger =
|
||||||
this.changeTrigger.length === 2
|
this.changeTrigger.length === 2
|
||||||
|
@ -243,6 +246,8 @@ class ChangeModel implements ChangeInterface {
|
||||||
return new Parser(
|
return new Parser(
|
||||||
container.get<HTMLElement>()?.outerHTML || '',
|
container.get<HTMLElement>()?.outerHTML || '',
|
||||||
this.engine,
|
this.engine,
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
).toValue(schema, conversion);
|
).toValue(schema, conversion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,8 @@ export default class Paste {
|
||||||
node.remove();
|
node.remove();
|
||||||
if (!parent) return;
|
if (!parent) return;
|
||||||
node = parent;
|
node = parent;
|
||||||
|
parent = node.parent();
|
||||||
|
if (!parent) return;
|
||||||
}
|
}
|
||||||
// 删除 google docs 根节点
|
// 删除 google docs 根节点
|
||||||
// <b style="font-weight:flat;" id="docs-internal-guid-e0280780-7fff-85c2-f58a-6e615d93f1f2">
|
// <b style="font-weight:flat;" id="docs-internal-guid-e0280780-7fff-85c2-f58a-6e615d93f1f2">
|
||||||
|
|
|
@ -281,7 +281,11 @@ export default class Clipboard implements ClipboardInterface {
|
||||||
// 合并列表
|
// 合并列表
|
||||||
this.editor.list.merge(listNodes);
|
this.editor.list.merge(listNodes);
|
||||||
const parser = new Parser(contents, this.editor);
|
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) {
|
if (callback) {
|
||||||
callback({ html, text });
|
callback({ html, text });
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,7 +319,7 @@ class Engine implements EngineInterface {
|
||||||
node.removeAttributes('spellcheck');
|
node.removeAttributes('spellcheck');
|
||||||
node.removeAttributes('data-gramm');
|
node.removeAttributes('data-gramm');
|
||||||
node.removeAttributes('role');
|
node.removeAttributes('role');
|
||||||
return new Parser(node, this).toHTML().html;
|
return new Parser(node, this).toHTML();
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(value: string, callback?: (count: number) => void) {
|
setValue(value: string, callback?: (count: number) => void) {
|
||||||
|
|
|
@ -58,12 +58,18 @@ const stylesToString = (styles: { [k: string]: string }) => {
|
||||||
class Parser implements ParserInterface {
|
class Parser implements ParserInterface {
|
||||||
root: NodeInterface;
|
root: NodeInterface;
|
||||||
private editor: EditorInterface;
|
private editor: EditorInterface;
|
||||||
|
/**
|
||||||
|
* 对节点进行正常化转换,在解析编辑器值的时候设置为false可以提升性能。设置为ture的时候可以对不确定的html进行转换,例如粘贴的时候
|
||||||
|
*/
|
||||||
|
private isNormalize = true;
|
||||||
constructor(
|
constructor(
|
||||||
source: string | Node | NodeInterface,
|
source: string | Node | NodeInterface,
|
||||||
editor: EditorInterface,
|
editor: EditorInterface,
|
||||||
paserBefore?: (node: NodeInterface) => void,
|
paserBefore?: (node: NodeInterface) => void,
|
||||||
|
isNormalize: boolean = true,
|
||||||
) {
|
) {
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
|
this.isNormalize = isNormalize;
|
||||||
const { node } = this.editor;
|
const { node } = this.editor;
|
||||||
if (typeof source === 'string') {
|
if (typeof source === 'string') {
|
||||||
source = source.replace(/<a\s{0,1000}\/>/gi, '<a></a>');
|
source = source.replace(/<a\s{0,1000}\/>/gi, '<a></a>');
|
||||||
|
@ -114,8 +120,12 @@ class Parser implements ParserInterface {
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
if (node.isElement()) {
|
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);
|
let value = conversion.transform(node);
|
||||||
const oldRules: Array<ConversionRule> = [];
|
const oldRules: Array<ConversionRule> = [];
|
||||||
while (value) {
|
while (value) {
|
||||||
|
@ -130,10 +140,7 @@ class Parser implements ParserInterface {
|
||||||
});
|
});
|
||||||
//把旧节点的子节点追加到新节点下
|
//把旧节点的子节点追加到新节点下
|
||||||
newNode.append(node.children());
|
newNode.append(node.children());
|
||||||
if (
|
if (isCard) {
|
||||||
node.attributes(CARD_KEY) ||
|
|
||||||
node.attributes(READY_CARD_KEY)
|
|
||||||
) {
|
|
||||||
node.before(newNode);
|
node.before(newNode);
|
||||||
node.remove();
|
node.remove();
|
||||||
value = undefined;
|
value = undefined;
|
||||||
|
@ -156,11 +163,7 @@ class Parser implements ParserInterface {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (!this.isNormalize || isCard) return;
|
||||||
node.attributes(CARD_KEY) ||
|
|
||||||
node.attributes(READY_CARD_KEY)
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
//分割
|
//分割
|
||||||
const filter = (node: NodeInterface) => {
|
const filter = (node: NodeInterface) => {
|
||||||
//获取节点属性样式
|
//获取节点属性样式
|
||||||
|
@ -473,26 +476,15 @@ class Parser implements ParserInterface {
|
||||||
}
|
}
|
||||||
this.editor.trigger('parse:html-before', this.root);
|
this.editor.trigger('parse:html-before', this.root);
|
||||||
element.traverse((domNode) => {
|
element.traverse((domNode) => {
|
||||||
const node = domNode.get<HTMLElement>();
|
if (domNode.isText()) return;
|
||||||
if (
|
if (domNode.css('user-select') === 'none') {
|
||||||
node &&
|
domNode.remove();
|
||||||
node.nodeType === Node.ELEMENT_NODE &&
|
|
||||||
'none' === node.style['user-select'] &&
|
|
||||||
node.parentNode
|
|
||||||
) {
|
|
||||||
node.parentNode.removeChild(node);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.editor.trigger('parse:html', element);
|
this.editor.trigger('parse:html', element);
|
||||||
element.find('p').css(this.editor.container.css());
|
element.find('p').css(this.editor.container.css());
|
||||||
this.editor.trigger('parse:html-after', element);
|
this.editor.trigger('parse:html-after', element);
|
||||||
return {
|
return element.html();
|
||||||
html: element.html(),
|
|
||||||
text: new Parser(element, this.editor).toText(
|
|
||||||
this.editor.schema,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -78,7 +78,7 @@ export interface ParserInterface {
|
||||||
* @param inner 内包裹节点
|
* @param inner 内包裹节点
|
||||||
* @param outter 外包裹节点
|
* @param outter 外包裹节点
|
||||||
*/
|
*/
|
||||||
toHTML(inner?: Node, outter?: Node): { html: string; text: string };
|
toHTML(inner?: Node, outter?: Node): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回DOM树
|
* 返回DOM树
|
||||||
|
|
|
@ -620,7 +620,7 @@ export default class extends MarkPlugin<Options> {
|
||||||
: Range.create(this.editor)
|
: Range.create(this.editor)
|
||||||
).cloneRange();
|
).cloneRange();
|
||||||
|
|
||||||
const parser = new Parser(container, this.editor);
|
const parser = new Parser(container, this.editor, undefined, false);
|
||||||
const { schema, conversion } = this.editor;
|
const { schema, conversion } = this.editor;
|
||||||
if (!range) {
|
if (!range) {
|
||||||
container.remove();
|
container.remove();
|
||||||
|
@ -697,7 +697,7 @@ export default class extends MarkPlugin<Options> {
|
||||||
: Range.create(this.editor)
|
: Range.create(this.editor)
|
||||||
).cloneRange();
|
).cloneRange();
|
||||||
|
|
||||||
const parser = new Parser(container, this.editor);
|
const parser = new Parser(container, this.editor, undefined, false);
|
||||||
const { schema, conversion } = this.editor;
|
const { schema, conversion } = this.editor;
|
||||||
if (!range) {
|
if (!range) {
|
||||||
container.remove();
|
container.remove();
|
||||||
|
|
|
@ -206,6 +206,14 @@ class Table extends Plugin<Options> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteSchema(schema: SchemaInterface) {
|
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 = {
|
schema.find((r) => r.name === 'table')[0].attributes = {
|
||||||
class: ['data-table'],
|
class: ['data-table'],
|
||||||
'data-table-no-border': '*',
|
'data-table-no-border': '*',
|
||||||
|
|
Loading…
Reference in New Issue