fix(video & shift-enter)

This commit is contained in:
yanmao 2021-11-03 23:45:19 +08:00
parent d1c3366ac5
commit 160bfbaa0c
6 changed files with 61 additions and 43 deletions

View File

@ -222,6 +222,7 @@ class ChangeModel implements ChangeInterface {
container.empty().append(fragment);
card.render(undefined, (count) => {
this.initValue(undefined, false);
this.engine.trigger('paste:after');
if (callback) callback(count);
});
},

View File

@ -359,9 +359,6 @@ class Engine implements EngineInterface {
}
const html = this.node.html(dom);
this.change.setValue(html, undefined, callback);
// const range = this.change.range.get();
// range.shrinkToElementNode();
// this.change.range.select(range);
this.normalize();
this.nodeId.generateAll(this.container);
return this;

View File

@ -142,7 +142,7 @@ class Parser implements ParserInterface {
value = undefined;
continue;
} else {
if (!nodeApi.isBlock(newNode)) {
if (!nodeApi.isBlock(newNode, schema)) {
//把包含旧子节点的新节点追加到旧节点下
node.append(newNode);
} else {
@ -199,7 +199,7 @@ class Parser implements ParserInterface {
//当前节点是 inline 节点inline 节点不允许嵌套、不允许放入mark节点
inlineApi.flat(node);
//当前节点是 mark 节点
if (nodeApi.isMark(node)) {
if (nodeApi.isMark(node, schema)) {
//过滤掉当前mark节点属性样式并使用剩下的属性样式组成新的节点
const oldRules: Array<SchemaRule> = [];
let rule = schema.getRule(node);
@ -281,6 +281,21 @@ class Parser implements ParserInterface {
type = schema.getType(child);
if (type === undefined) {
passed = false;
const parent = child.parent();
if (
parent &&
nodeApi.isBlock(parent, schema) &&
parent.children().length === 1
) {
const newChild = $('<br />');
child.before(newChild);
child.remove();
child = newChild;
name = newChild.name;
attributes = {};
styles = {};
passed = true;
}
} else {
//过滤不符合规则的属性和样式
schema.filter(child, attributes, styles);
@ -324,7 +339,10 @@ class Parser implements ParserInterface {
}
} else if (child.isText()) {
let text = child[0].nodeValue ? escape(child[0].nodeValue) : '';
if (text === '' && nodeApi.isBlock(child.parent()!)) {
if (
text === '' &&
nodeApi.isBlock(child.parent()!, schema || undefined)
) {
if (!child.prev()) {
text = text.replace(/^[ \n]+/, '');
}
@ -337,9 +355,9 @@ class Parser implements ParserInterface {
const childNext = child.next();
if (
childPrev &&
nodeApi.isBlock(childPrev) &&
nodeApi.isBlock(childPrev, schema || undefined) &&
childNext &&
nodeApi.isBlock(childNext) &&
nodeApi.isBlock(childNext, schema || undefined) &&
text.trim() === ''
) {
text = text.trim();
@ -400,7 +418,10 @@ class Parser implements ParserInterface {
}
}
if (nodeApi.isVoid(name, schema ? schema : undefined)) {
if (
nodeApi.isVoid(name, schema ? schema : undefined) &&
child.children().length === 0
) {
result.push(' />');
} else {
result.push('>');
@ -489,7 +510,8 @@ class Parser implements ParserInterface {
const nodes = doc.body.childNodes;
while (nodes.length > 0) {
fragment.appendChild(nodes[0]);
const node = nodes[0];
fragment.appendChild(node);
}
return fragment;
}

View File

@ -36,9 +36,11 @@ class ShitEnter implements TypingHandleInterface {
const range = change.range.get();
const br = $('<br />');
inline.insert(br, range);
// Chrome 问题:<h1>foo<br /><cursor /></h1> 时候需要再插入一个 br否则没有换行效果
if (block.isLastOffset(range, 'end')) {
if (!br.next() || br.next()?.name !== 'br') {
if (
(!br.next() || br.next()?.name !== 'br') &&
(!br.prev() || br.prev()?.name !== 'br')
) {
const cloneBr = br.clone();
br.after(cloneBr);
range.select(cloneBr).collapse(false);

View File

@ -288,7 +288,10 @@ class ImageComponent extends Card<ImageValue> {
}
didRender() {
if (this.type === CardType.INLINE) {
if (
this.type === CardType.INLINE &&
this.getValue()?.status === 'done'
) {
this.toolbarModel?.setOffset([-12, 0, -12, 0]);
}
}

View File

@ -130,42 +130,33 @@ export default class VideoPlugin extends Plugin<{
pasteSchema(schema: SchemaInterface) {
schema.add({
type: 'block',
name: 'video',
isVoid: true,
name: 'div',
attributes: {
src: {
required: true,
value: '@url',
},
'data-value': '*',
'data-type': {
required: true,
value: VideoComponent.cardName,
},
},
});
}
pasteHtml(node: NodeInterface) {
if (!isEngine(this.editor)) return;
if (node.isElement() && node.name === 'video') {
const value = node.attributes('data-value');
let cardValue = decodeCardValue(value);
if (!cardValue.url) {
cardValue = {
url: node.attributes('src'),
name:
node.attributes('data-name') ||
node.attributes('name') ||
node.attributes('title') ||
node.attributes('src'),
cover: node.attributes('poster'),
status: 'done',
};
if (node.isElement()) {
const type = node.attributes('data-type');
if (type === VideoComponent.cardName) {
const value = node.attributes('data-value');
const cardValue = decodeCardValue(value) as VideoValue;
if (!cardValue.url) return;
this.editor.card.replaceNode(
node,
VideoComponent.cardName,
cardValue,
);
node.remove();
return false;
}
this.editor.card.replaceNode(
node,
VideoComponent.cardName,
cardValue,
);
node.remove();
return false;
}
return true;
}
@ -179,9 +170,11 @@ export default class VideoPlugin extends Plugin<{
if (value?.url && value.status === 'done') {
const { onBeforeRender } = this.options;
const { cover, url } = value;
const html = `<video data-value="${encodeCardValue(
const html = `<div data-type="${
VideoComponent.cardName
}" data-value="${encodeCardValue(
value,
)}" controls src="${sanitizeUrl(
)}"><video controls src="${sanitizeUrl(
onBeforeRender ? onBeforeRender('query', url) : url,
)}" poster="${
!cover
@ -191,7 +184,7 @@ export default class VideoPlugin extends Plugin<{
? onBeforeRender('cover', cover)
: cover,
)
}" webkit-playsinline="webkit-playsinline" playsinline="playsinline" style="outline:none;" />`;
}" webkit-playsinline="webkit-playsinline" playsinline="playsinline" style="outline:none;" /></div>`;
node.empty();
node.replaceWith($(html));
} else node.remove();