- 粘贴过程中有转换的情况下子节点无法进行正确的过滤
- 协同中会有一定的情况会造成卡片不渲染
- 格式刷插件双击会报错
This commit is contained in:
yanmao 2021-12-09 14:38:55 +08:00
parent 90f8fd8f64
commit cc6218aac7
7 changed files with 101 additions and 46 deletions

View File

@ -109,7 +109,7 @@ abstract class CardEntry<T extends CardValue = {}> implements CardInterface {
}
get loading() {
return !!this.root.attributes('data-card-loading');
return !!this.root.attributes(CARD_LOADING_KEY);
}
constructor({ editor, value, root }: CardOptions) {
@ -351,7 +351,7 @@ abstract class CardEntry<T extends CardValue = {}> implements CardInterface {
const loadingElement = $(
`<${
this.type === CardType.BLOCK ? 'div' : 'span'
} class="data-card-loading" ${DATA_ELEMENT}="${UI}" />`,
} class="${CARD_LOADING_KEY}" ${DATA_ELEMENT}="${UI}" />`,
);
loadingElement.append(
'<svg viewBox="0 0 1024 1024" class="data-card-spin" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true"> <path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"></path></svg>',
@ -359,7 +359,7 @@ abstract class CardEntry<T extends CardValue = {}> implements CardInterface {
center.empty().append(loadingElement);
}
didRender() {
if (this.loading) this.find('.data-card-loading').remove();
if (this.loading) this.find(`.${CARD_LOADING_KEY}`).remove();
setTimeout(() => {
this.root.removeAttributes(CARD_LOADING_KEY);
}, 100);

View File

@ -660,6 +660,7 @@ class CardModel implements CardModelInterface {
this.removeComponent(card);
}
cardNode.attributes(CARD_LOADING_KEY, 'true');
cardNode.empty();
}
//ready_card_key 待创建的需要重新生成节点,并替换当前待创建节点
card = this.create(name, {

View File

@ -129,8 +129,7 @@ class Parser implements ParserInterface {
if (node.isCard()) {
node.before(newNode);
node.remove();
value = undefined;
continue;
return newNode;
} else {
if (!nodeApi.isBlock(newNode, schema)) {
//把包含旧子节点的新节点追加到旧节点下
@ -139,12 +138,13 @@ class Parser implements ParserInterface {
// 替换
node.before(newNode);
node.remove();
break;
return newNode;
}
}
//排除之前的过滤规则后再次过滤
value = conversion.transform(node, (r) => oldRules.indexOf(r) < 0);
}
return;
}
normalize(
root: NodeInterface,
@ -175,7 +175,11 @@ class Parser implements ParserInterface {
const isCard = node.isCard();
//转换标签
if (conversion && (!schema.getType(node) || isCard)) {
this.convert(conversion, node, schema);
const newNode = this.convert(conversion, node, schema);
if (newNode) {
this.normalize(newNode, schema, conversion);
return;
}
}
if (isCard) return;
//分割

View File

@ -230,36 +230,51 @@ class CollapseComponent implements CollapseComponentInterface {
this.target = target;
let body = this.getBody();
if (CollapseComponent.renderLoading) {
const result = CollapseComponent.renderLoading(this.root);
let result = null;
if (
CollapseComponent.renderLoading ||
(result = this.engine.trigger('mention:loading', this.root))
) {
result = CollapseComponent.renderLoading
? CollapseComponent.renderLoading(this.root)
: result;
body = this.getBody();
if (result) body?.append(result);
} else if (data.filter((item) => !!item.key).length === 0) {
const result = CollapseComponent.renderEmpty(this.root);
const result =
this.engine.trigger('mention:empty', this.root) ||
CollapseComponent.renderEmpty(this.root);
body = this.getBody();
if (result) body?.append(result);
} else if (CollapseComponent.render) {
CollapseComponent.render(this.root, data, this.bindItem).then(
(result) => {
} else if (
CollapseComponent.render ||
(result = this.engine.trigger('mention:render', this.root))
) {
(CollapseComponent.render
? CollapseComponent.render(this.root, data, this.bindItem)
: result
).then((content: any) => {
const body = this.getBody();
if (result) body?.append(result);
if (content) body?.append(content);
this.#scrollbar?.destroy();
if (body)
this.#scrollbar = new Scrollbar(
body,
false,
true,
false,
);
this.#scrollbar = new Scrollbar(body, false, true, false);
this.select(0);
this.bindEvents();
this.#scrollbar?.refresh();
},
);
});
return;
} else {
data.forEach((data) => {
const result = CollapseComponent.renderItem
const triggerResult = this.engine.trigger(
'mention:render-item',
data,
this.root!,
);
const result = triggerResult
? triggerResult
: CollapseComponent.renderItem
? CollapseComponent.renderItem(data, this.root!)
: this.renderTemplate(data);
if (!result) return;

View File

@ -137,7 +137,9 @@ class Mention extends Card<MentionValue> {
this.changeToText();
},
onSelect: (_, data: { [key: string]: string }) => {
let newValue = {};
let newValue =
this.editor.trigger('mention:select', data) || {};
delete newValue['id'];
if (Mention.onSelect) {
newValue = Mention.onSelect(data) || {};
delete newValue['id'];
@ -152,6 +154,7 @@ class Mention extends Card<MentionValue> {
...newValue,
});
card.removeNode(this);
this.editor.trigger('mention:insert', component);
if (Mention.onInsert) Mention.onInsert(component);
},
});
@ -201,15 +204,17 @@ class Mention extends Card<MentionValue> {
const keyword = content.substr(1);
// 搜索关键词为空
if (keyword === '' && Mention.defaultData) {
this.component?.render(this.root, Mention.defaultData);
const defaultData =
this.editor.trigger('mention:default') || Mention.defaultData;
if (keyword === '' && defaultData) {
this.component?.render(this.root, defaultData);
return;
}
if (Mention.renderLoading) {
//if (Mention.renderLoading) {
CollapseComponent.renderLoading = Mention.renderLoading;
this.component?.render(this.root, []);
CollapseComponent.renderLoading = undefined;
}
//}
Mention.search(keyword).then((data) => {
this.component?.render(this.root, data);
});
@ -245,7 +250,11 @@ class Mention extends Card<MentionValue> {
if (this.#hideTimeout) clearTimeout(this.#hideTimeout);
});
this.#enterLayout.on('mouseleave', this.hideEnter);
this.editor.trigger('mention:enter', this.#enterLayout, {
key: unescape(key || ''),
name: unescape(name),
...info,
});
Mention.mouseEnter!(this.#enterLayout, {
key: unescape(key || ''),
name: unescape(name),
@ -270,7 +279,13 @@ class Mention extends Card<MentionValue> {
);
this.#container.on('click', () => {
if (!this.#container || !Mention.itemClick) return;
if (!this.#container) return;
this.editor.trigger('mention:item-click', this.#container, {
key: unescape(key || ''),
name: unescape(name),
...info,
});
if (Mention.itemClick)
Mention.itemClick(this.#container, {
key: unescape(key || ''),
name: unescape(name),
@ -333,8 +348,17 @@ class Mention extends Card<MentionValue> {
selection?.addRange(range.toRange());
}
}, 10);
this.component?.render(this.root, Mention.defaultData || []);
if (!Mention.defaultData) {
this.component?.render(
this.root,
this.editor.trigger('mention:default') ||
Mention.defaultData ||
[],
);
if (
!(Mention.defaultData
? Mention.defaultData
: this.editor.trigger('mention:default'))
) {
setTimeout(() => {
this.handleInput();
}, 50);

View File

@ -108,6 +108,8 @@ class MentionPlugin extends Plugin<Options> {
if (onInsert) MentionComponent.onInsert = onInsert;
MentionComponent.search = (keyword: string) => {
if (onSearch) return onSearch(keyword);
const reuslt = this.editor.trigger('mention:search', keyword);
if (reuslt !== undefined) return reuslt;
return new Promise((resolve) => {
if (action) {
this.#request?.abort();

View File

@ -107,7 +107,13 @@ export default class extends Plugin<Options> {
if (typeof removeCommand === 'function') removeCommand(range);
else command.execute(removeCommand);
this.paintMarks(activeMarks);
if (activeBlocks) this.paintBlocks(currentBlock, activeBlocks);
// 移除样式后会导致block被移除需要重新查找
const blocks = block.getBlocks(range);
if (activeBlocks) {
blocks.forEach((block) => {
this.paintBlocks(block, activeBlocks);
});
}
range.select(dummy);
range.collapse(true);
dummy.remove();
@ -118,11 +124,13 @@ export default class extends Plugin<Options> {
else command.execute(removeCommand);
this.paintMarks(activeMarks);
const blocks = block.getBlocks(range);
if (activeBlocks) {
blocks.forEach((block) => {
if (activeBlocks) this.paintBlocks(block, activeBlocks);
this.paintBlocks(block, activeBlocks);
});
}
}
}
paintMarks(activeMarks: NodeInterface[]) {
const { mark } = this.editor!;
@ -138,6 +146,7 @@ export default class extends Plugin<Options> {
const range = change.range.get();
const selection = range.createSelection('removeformat');
activeBlocks.forEach((block) => {
if (!currentBlock.inEditor()) return;
if (this.options.paintBlock) {
const paintResult = this.options.paintBlock(
currentBlock,