[FIX] web_editor: properly evaluate if a range is an image
The previous implementation apparently came from an old version of summernote (see https://github.com/odoo/odoo/commit/d33086c03fc1a0882be38ae62989b7f72df20d3b). This commits should improve it to handle all known cases. See https://github.com/odoo/odoo/issues/20877
This commit is contained in:
@@ -886,34 +886,60 @@ range.WrappedRange.prototype.reRange = function (keep_end, isNotBreakable) {
|
||||
|
||||
return new range.WrappedRange(sc, so, ec, eo);
|
||||
};
|
||||
// isOnImg: judge whether range is an image node or not
|
||||
/**
|
||||
* Returns the image the range is in or matches (if any, false otherwise).
|
||||
*
|
||||
* @todo this implementation may not cover all corner cases but should do the
|
||||
* trick for all reproductible ones
|
||||
* @returns {DOMElement|boolean}
|
||||
*/
|
||||
range.WrappedRange.prototype.isOnImg = function () {
|
||||
// If not a selection but a cursor position, just check if a point's
|
||||
// ancestor is an image or not
|
||||
if (this.sc === this.ec && this.so === this.eo) {
|
||||
return dom.ancestor(this.sc, dom.isImg);
|
||||
}
|
||||
|
||||
var startPoint = {node: this.sc, offset: this.so};
|
||||
var endPoint = {node: this.ec, offset: this.eo};
|
||||
|
||||
var nb = 0;
|
||||
var image;
|
||||
var startPoint = {node: this.sc.childNodes.length && this.sc.childNodes[this.so] || this.sc};
|
||||
startPoint.offset = startPoint.node === this.sc ? this.so : 0;
|
||||
var endPoint = {node: this.ec.childNodes.length && this.ec.childNodes[this.eo] || this.ec};
|
||||
endPoint.offset = endPoint.node === this.ec ? this.eo : 0;
|
||||
|
||||
if (dom.isImg(startPoint.node)) {
|
||||
nb ++;
|
||||
image = startPoint.node;
|
||||
}
|
||||
var textNode;
|
||||
dom.walkPoint(startPoint, endPoint, function (point) {
|
||||
if (!dom.isText(endPoint.node) && point.node === endPoint.node && point.offset === endPoint.offset) {
|
||||
// If the element has children (not a text node and not empty node),
|
||||
// the element cannot be considered as selected (these children will
|
||||
// be processed to determine that)
|
||||
if (dom.hasChildren(point.node)) {
|
||||
return;
|
||||
}
|
||||
var node = point.node.childNodes.length && point.node.childNodes[point.offset] || point.node;
|
||||
var offset = node === point.node ? point.offset : 0;
|
||||
var isImg = dom.ancestor(node, dom.isImg);
|
||||
if (!isImg && ((!dom.isBR(node) && !dom.isText(node)) || (offset && node.textContent.length !== offset && node.textContent.match(/\S|\u00A0/)))) {
|
||||
|
||||
// Check if an ancestor of the current point is an image
|
||||
var pointImg = dom.ancestor(point.node, dom.isImg);
|
||||
var isText = dom.isText(point.node);
|
||||
|
||||
// Check if a visible element is selected, i.e.
|
||||
// - If an ancestor of the current is an image we did not see yet
|
||||
// - If the point is not in a br or a text (so a node with no children)
|
||||
// - If the point is in a non empty text node we already saw
|
||||
if (pointImg ?
|
||||
(image !== pointImg) :
|
||||
((!dom.isBR(point.node) && !isText) || (textNode === point.node && point.node.textContent.match(/\S|\u00A0/)))) {
|
||||
nb++;
|
||||
}
|
||||
if (isImg && image !== isImg) {
|
||||
image = isImg;
|
||||
nb ++;
|
||||
|
||||
// If an ancestor of the current point is an image, then save it as the
|
||||
// image we are looking for
|
||||
if (pointImg) {
|
||||
image = pointImg;
|
||||
}
|
||||
// If the current point is a text node save it as the last text node
|
||||
// seen (if we see it again, this might mean it is selected)
|
||||
if (isText) {
|
||||
textNode = point.node;
|
||||
}
|
||||
});
|
||||
|
||||
return nb === 1 && image;
|
||||
};
|
||||
range.WrappedRange.prototype.deleteContents = function (towrite) {
|
||||
|
||||
Reference in New Issue
Block a user