feat(): 性能优化
This commit is contained in:
parent
cdd9f3ba03
commit
2b24d6a3db
|
@ -1237,7 +1237,8 @@ class Block implements BlockModelInterface {
|
|||
if (!first) {
|
||||
return;
|
||||
}
|
||||
const children = block.children();
|
||||
const blockElement = block.get<Element>();
|
||||
const children = blockElement?.childNodes || [];
|
||||
// 只有一个节点
|
||||
if (children.length === 1) {
|
||||
const node = first;
|
||||
|
@ -1256,8 +1257,8 @@ class Block implements BlockModelInterface {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (block.find('br').length === 0) return;
|
||||
// 没有br标签
|
||||
if (!blockElement?.querySelector('br')) return;
|
||||
|
||||
let container;
|
||||
let prevContainer;
|
||||
|
|
|
@ -72,12 +72,9 @@ 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
|
||||
|
|
|
@ -82,7 +82,8 @@ export default class Paste {
|
|||
}
|
||||
});
|
||||
//处理后如果不是一个有效的节点就移除包裹
|
||||
if (!this.schema.getType(node)) {
|
||||
let type = this.schema.getType(node);
|
||||
if (!type) {
|
||||
nodeApi.unwrap(node);
|
||||
return;
|
||||
}
|
||||
|
@ -90,13 +91,16 @@ export default class Paste {
|
|||
if (nodeApi.isList(node)) {
|
||||
node.css('padding-left', '');
|
||||
}
|
||||
|
||||
let attributes: { [k: string]: string } | undefined =
|
||||
node.attributes();
|
||||
// 删除空 style 属性
|
||||
if (node.attributes('style').trim() === '') {
|
||||
if ((attributes.style || '').trim() === '') {
|
||||
node.removeAttributes('style');
|
||||
}
|
||||
|
||||
// br 换行改成正常段落
|
||||
if (nodeApi.isBlock(node, this.schema)) {
|
||||
if (type === 'block') {
|
||||
this.engine.block.brToBlock(node);
|
||||
}
|
||||
// 删除空 span
|
||||
|
@ -107,24 +111,23 @@ export default class Paste {
|
|||
node = parent;
|
||||
parent = node.parent();
|
||||
if (!parent) return;
|
||||
type = undefined;
|
||||
attributes = undefined;
|
||||
}
|
||||
// 删除 google docs 根节点
|
||||
// <b style="font-weight:flat;" id="docs-internal-guid-e0280780-7fff-85c2-f58a-6e615d93f1f2">
|
||||
if (/^docs-internal-guid-/.test(node.attributes('id'))) {
|
||||
nodeApi.unwrap(node);
|
||||
return;
|
||||
}
|
||||
if (!attributes) attributes = node.attributes();
|
||||
// 跳过Card
|
||||
if (node.attributes(READY_CARD_KEY)) {
|
||||
if (attributes[READY_CARD_KEY]) {
|
||||
return;
|
||||
}
|
||||
const nodeIsBlock = nodeApi.isBlock(node, this.schema);
|
||||
const nodeIsBlock = type
|
||||
? type === 'block'
|
||||
: nodeApi.isBlock(node, this.schema);
|
||||
const nodeIsVoid = nodeApi.isVoid(node, this.schema);
|
||||
let parentIsBlock = nodeApi.isBlock(parent, this.schema);
|
||||
// 删除零高度的空行
|
||||
if (
|
||||
nodeIsBlock &&
|
||||
node.attributes('data-type') !== 'p' &&
|
||||
attributes['data-type'] !== 'p' &&
|
||||
!nodeIsVoid &&
|
||||
!parentIsBlock &&
|
||||
//!node.isSolid() &&
|
||||
|
@ -134,7 +137,7 @@ export default class Paste {
|
|||
return;
|
||||
}
|
||||
// 段落
|
||||
if (node.attributes('data-type') === 'p') {
|
||||
if (attributes['data-type'] === 'p') {
|
||||
node.removeAttributes('data-type');
|
||||
}
|
||||
if (nodeIsBlock && parent?.name === 'p') {
|
||||
|
|
|
@ -949,7 +949,7 @@ class Inline implements InlineModelInterface {
|
|||
repairBoth(node: NodeInterface | Node) {
|
||||
const nodeApi = this.editor.node;
|
||||
if (isNode(node)) node = $(node);
|
||||
if (node.parent() && !nodeApi.isVoid(node)) {
|
||||
if (node.get()?.parentNode && !nodeApi.isVoid(node)) {
|
||||
const zeroNode = $('\u200b', null);
|
||||
const prev = node.prev();
|
||||
const prevPrev = prev?.prev();
|
||||
|
@ -991,7 +991,7 @@ class Inline implements InlineModelInterface {
|
|||
if (next && next.isText()) {
|
||||
next.text('\u200b' + next.text());
|
||||
} else {
|
||||
node.after(this.editor.node.clone(zeroNode, true, false));
|
||||
node.after(nodeApi.clone(zeroNode, true, false));
|
||||
if (next?.name === 'br') {
|
||||
next.remove();
|
||||
}
|
||||
|
|
|
@ -659,14 +659,15 @@ class NodeModel implements NodeModelInterface {
|
|||
* @param props 属性
|
||||
*/
|
||||
setAttributes(node: NodeInterface, attrs: any) {
|
||||
let { style, ...attributes } = attrs;
|
||||
Object.keys(attributes).forEach((key) => {
|
||||
let style = attrs.style;
|
||||
Object.keys(attrs).forEach((key) => {
|
||||
if (key === 'style') return;
|
||||
if (key === 'className') {
|
||||
const value = attributes[key];
|
||||
const value = attrs[key];
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((name) => node.addClass(name));
|
||||
} else node.addClass(value);
|
||||
} else node.attributes(key, attributes[key].toString());
|
||||
} else node.attributes(key, attrs[key].toString());
|
||||
});
|
||||
if (typeof style === 'number') style = {};
|
||||
if (typeof style === 'string') style = getStyleMap(style);
|
||||
|
|
|
@ -9,7 +9,12 @@ import {
|
|||
ConversionRule,
|
||||
SchemaRule,
|
||||
} from '../types';
|
||||
import { CARD_ELEMENT_KEY, CARD_KEY, READY_CARD_KEY } from '../constants';
|
||||
import {
|
||||
CARD_ELEMENT_KEY,
|
||||
CARD_KEY,
|
||||
CARD_SELECTOR,
|
||||
READY_CARD_KEY,
|
||||
} from '../constants';
|
||||
import {
|
||||
escape,
|
||||
unescape,
|
||||
|
@ -105,6 +110,46 @@ class Parser implements ParserInterface {
|
|||
}
|
||||
if (paserBefore) paserBefore(this.root);
|
||||
}
|
||||
convert(
|
||||
conversion: ConversionInterface,
|
||||
node: NodeInterface,
|
||||
schema?: SchemaInterface,
|
||||
) {
|
||||
let value = conversion.transform(node);
|
||||
const oldRules: Array<ConversionRule> = [];
|
||||
const nodeApi = this.editor.node;
|
||||
while (value) {
|
||||
const { rule } = value;
|
||||
oldRules.push(rule);
|
||||
const { name, attributes, style } = value.node;
|
||||
delete attributes[DATA_ID];
|
||||
const newNode = $(`<${name} />`);
|
||||
nodeApi.setAttributes(newNode, {
|
||||
...attributes,
|
||||
style,
|
||||
});
|
||||
//把旧节点的子节点追加到新节点下
|
||||
newNode.append(node.children());
|
||||
if (node.isCard()) {
|
||||
node.before(newNode);
|
||||
node.remove();
|
||||
value = undefined;
|
||||
continue;
|
||||
} else {
|
||||
if (!nodeApi.isBlock(newNode, schema)) {
|
||||
//把包含旧子节点的新节点追加到旧节点下
|
||||
node.append(newNode);
|
||||
} else {
|
||||
// 替换
|
||||
node.before(newNode);
|
||||
node.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//排除之前的过滤规则后再次过滤
|
||||
value = conversion.transform(node, (r) => oldRules.indexOf(r) < 0);
|
||||
}
|
||||
}
|
||||
normalize(
|
||||
root: NodeInterface,
|
||||
schema: SchemaInterface,
|
||||
|
@ -112,7 +157,18 @@ class Parser implements ParserInterface {
|
|||
) {
|
||||
const nodeApi = this.editor.node;
|
||||
const inlineApi = this.editor.inline;
|
||||
//转换标签和分割 mark 和 inline 标签
|
||||
//转换标签和分割 mark 和 inline
|
||||
// 不分割,就只转换卡片
|
||||
if (!this.isNormalize) {
|
||||
if (!conversion) return;
|
||||
const cards = root.find(CARD_SELECTOR);
|
||||
cards.each((_, index) => {
|
||||
const cardNode = cards.eq(index);
|
||||
if (!cardNode) return;
|
||||
this.convert(conversion, cardNode, schema);
|
||||
});
|
||||
return;
|
||||
}
|
||||
root.traverse((node) => {
|
||||
if (
|
||||
node.equal(root) ||
|
||||
|
@ -122,48 +178,10 @@ class Parser implements ParserInterface {
|
|||
if (node.isElement()) {
|
||||
const isCard = node.isCard();
|
||||
//转换标签
|
||||
if (
|
||||
conversion &&
|
||||
((this.isNormalize && !schema.getType(node)) || isCard)
|
||||
) {
|
||||
let value = conversion.transform(node);
|
||||
const oldRules: Array<ConversionRule> = [];
|
||||
while (value) {
|
||||
const { rule } = value;
|
||||
oldRules.push(rule);
|
||||
const { name, attributes, style } = value.node;
|
||||
delete attributes[DATA_ID];
|
||||
const newNode = $(`<${name} />`);
|
||||
nodeApi.setAttributes(newNode, {
|
||||
...attributes,
|
||||
style,
|
||||
});
|
||||
//把旧节点的子节点追加到新节点下
|
||||
newNode.append(node.children());
|
||||
if (isCard) {
|
||||
node.before(newNode);
|
||||
node.remove();
|
||||
value = undefined;
|
||||
continue;
|
||||
} else {
|
||||
if (!nodeApi.isBlock(newNode, schema)) {
|
||||
//把包含旧子节点的新节点追加到旧节点下
|
||||
node.append(newNode);
|
||||
} else {
|
||||
// 替换
|
||||
node.before(newNode);
|
||||
node.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//排除之前的过滤规则后再次过滤
|
||||
value = conversion.transform(
|
||||
node,
|
||||
(r) => oldRules.indexOf(r) < 0,
|
||||
);
|
||||
}
|
||||
if (conversion && (!schema.getType(node) || isCard)) {
|
||||
this.convert(conversion, node, schema);
|
||||
}
|
||||
if (!this.isNormalize || isCard) return;
|
||||
if (isCard) return;
|
||||
//分割
|
||||
const filter = (node: NodeInterface) => {
|
||||
//获取节点属性样式
|
||||
|
|
|
@ -372,7 +372,6 @@ class TableComponent extends Card<TableValue> implements TableInterface {
|
|||
};
|
||||
this.scrollbar.on('change', handleScrollbarChange);
|
||||
}
|
||||
this.scrollbar?.refresh();
|
||||
this.selection.on('select', () => {
|
||||
this.conltrollBar.refresh();
|
||||
if (!isEngine(this.editor)) return;
|
||||
|
|
|
@ -82,7 +82,7 @@ div[data-card-key="table"].card-selected .data-table, div[data-card-key="table"]
|
|||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
z-index: 4;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
|
|
|
@ -344,6 +344,7 @@ class Table extends Plugin<Options> {
|
|||
element?.css('background-color');
|
||||
if (background) tds?.css('background', background);
|
||||
});
|
||||
this.editor.nodeId.generateAll(node, true);
|
||||
this.editor.card.replaceNode(node, TableComponent.cardName, {
|
||||
html: node
|
||||
.get<HTMLElement>()!
|
||||
|
|
Loading…
Reference in New Issue