Browse Source

Fix editing logic for links. Closes #4145

pull/4160/head
Artur Arseniev 5 years ago
parent
commit
40fa88f278
  1. 86
      src/dom_components/model/ComponentLink.js
  2. 7
      src/dom_components/view/ComponentTextView.js
  3. 2
      src/parser/model/ParserHtml.js

86
src/dom_components/model/ComponentLink.js

@ -1,53 +1,41 @@
import Component from './ComponentText';
import { forEach } from 'underscore';
import { toLowerCase } from 'utils/mixins';
import ComponentText from './ComponentText';
export default Component.extend(
{
defaults: {
...Component.prototype.defaults,
type: 'link',
tagName: 'a',
traits: ['title', 'href', 'target']
},
/**
* Returns object of attributes for HTML
* @return {Object}
* @private
*/
getAttrToHTML(...args) {
const attr = Component.prototype.getAttrToHTML.apply(this, args);
delete attr.onmousedown;
return attr;
}
},
{
isComponent(el) {
let result;
if (toLowerCase(el.tagName) === 'a') {
result = {
type: 'link',
editable: 0
};
// The link is editable only if, at least, one of its
// children is a text node (not empty one)
const children = el.childNodes;
const len = children.length;
if (!len) delete result.editable;
for (let i = 0; i < len; i++) {
const child = children[i];
if (child.nodeType == 3 && child.textContent.trim() != '') {
delete result.editable;
break;
}
}
}
const type = 'link';
export default class ComponentLink extends ComponentText {}
ComponentLink.prototype.defaults = {
...ComponentText.getDefaults(),
type,
tagName: 'a',
traits: ['title', 'href', 'target'],
};
ComponentLink.isComponent = (el, opts = {}) => {
let result;
return result;
}
if (toLowerCase(el.tagName) === 'a') {
const textTags = opts.textTags || [];
result = { type, editable: false };
// The link is editable only if, at least, one of its
// children is a text node (not empty one)
const children = el.childNodes;
const len = children.length;
if (!len) delete result.editable;
forEach(children, child => {
const { tagName } = child;
if (
(child.nodeType == 3 && child.textContent.trim() !== '') ||
(tagName && textTags.indexOf(toLowerCase(tagName)) >= 0)
) {
delete result.editable;
}
});
}
);
return result;
};

7
src/dom_components/view/ComponentTextView.js

@ -43,7 +43,11 @@ export default ComponentView.extend({
parent = parent.parent();
}
delegate = parent;
if (parent && parent.get('editable')) {
delegate = parent;
} else {
result = true;
}
}
}
@ -62,6 +66,7 @@ export default ComponentView.extend({
// text components will not block the editing (#1394)
if (!result) {
if (delegate) {
ev?.stopPropagation?.();
em.setSelected(delegate);
delegate.trigger('active', ev);
}

2
src/parser/model/ParserHtml.js

@ -316,7 +316,7 @@ export default config => {
}
em && em.trigger(`${event}:root`, { input: str, root: el });
const result = this.parseNode(el);
const result = this.parseNode(el, cf);
// I have to keep it otherwise it breaks the DomComponents.addComponent (returns always array)
const resHtml = result.length === 1 && !c.returnArray ? result[0] : result;
res.html = resHtml;

Loading…
Cancel
Save