summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/src/js/wysiwyg/plugin
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2019-05-13 15:26:12 +0200
committerChristophe Simonis <chs@odoo.com>2019-05-13 15:26:12 +0200
commit8dd5a85267b522ba569ab9ed44901f95fffbeb4f (patch)
treeddb62d1e83e1b810b96c05f6819ca66f8d6b4955 /addons/web_editor/static/src/js/wysiwyg/plugin
parent15716642e1975b4f2f29916011a4be29804cda88 (diff)
parent60e71302a38b36214efec1213882f573e3ea453c (diff)
[MERGE] forward port branch saas-12.3 up to 60e71302a38
Diffstat (limited to 'addons/web_editor/static/src/js/wysiwyg/plugin')
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/bullet.js5
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js22
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/helper.js83
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js1
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/link.js4
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/media.js6
-rw-r--r--addons/web_editor/static/src/js/wysiwyg/plugin/text.js2
7 files changed, 101 insertions, 22 deletions
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/bullet.js b/addons/web_editor/static/src/js/wysiwyg/plugin/bullet.js
index 506646d4697..dc2a444384b 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/bullet.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/bullet.js
@@ -173,6 +173,7 @@ var BulletPlugin = AbstractPlugin.extend({
} else {
ul = this.document.createElement(sorted === "ol" ? "ol" : "ul");
ul.className = ol.className;
+ $(ul).removeClass('o_checklist');
$(ul).insertBefore(ol).append(lis);
parent.removeChild(ol);
}
@@ -312,6 +313,10 @@ var BulletPlugin = AbstractPlugin.extend({
if (!range) {
return;
}
+ // list groups shouldn't be outdented like regular lists
+ if ($(dom.ancestor(range.sc, dom.isList)).hasClass('list-group')) {
+ return;
+ }
var self = this;
var nodes = [];
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js b/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js
index 74703b90e45..255561b02be 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/dropzone.js
@@ -19,6 +19,7 @@ var DropzonePlugin = Plugins.dropzone.extend({
attachDragAndDropEvent: function () {
this._super.apply(this, arguments);
this.$dropzone.off('drop');
+ this.$dropzone.on('dragenter', this._onDragenter.bind(this));
this.$dropzone.on('drop', this._onDrop.bind(this));
},
@@ -71,7 +72,7 @@ var DropzonePlugin = Plugins.dropzone.extend({
if (range.so >= dom.nodeLength(range.sc)) {
$(range.sc).append(spinner);
} else {
- $(range.sc).before(range.sc.childNodes[range.so]);
+ $(range.sc.childNodes[range.so]).before(spinner);
}
} else {
range.sc.splitText(range.so);
@@ -151,7 +152,7 @@ var DropzonePlugin = Plugins.dropzone.extend({
route: '/web_editor/add_image_base64',
params: {
res_model: options.res_model,
- res_id: options.res_id,
+ res_id: options.res_id || 0,
image_base64: imageBase64.split(';base64,').pop(),
filename: fileName,
},
@@ -161,9 +162,26 @@ var DropzonePlugin = Plugins.dropzone.extend({
* @private
* @param {JQueryEvent} e
*/
+ _onDragenter: function (e) {
+ var range = this.context.invoke('editor.createRange');
+ if (!this.editable.contains(range.sc)) {
+ var node = this.editable;
+ if (node && node.firstChild) {
+ node = node.firstChild;
+ }
+ range = this.context.invoke('editor.setRange', node, 0, node, 0);
+ range.select();
+ }
+ },
+ /**
+ * @private
+ * @param {JQueryEvent} e
+ */
_onDrop: function (e) {
e.preventDefault();
+ this.$editor.removeClass('dragover');
+
if (this.options.disableDragAndDrop) {
return;
}
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/helper.js b/addons/web_editor/static/src/js/wysiwyg/plugin/helper.js
index 4ba44fe3c9b..521afe6137a 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/helper.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/helper.js
@@ -109,12 +109,14 @@ var HelperPlugin = AbstractPlugin.extend({
this.orderStyle(node);
this.orderClass(otherNode);
this.orderStyle(otherNode);
- if (node.attributes.length !== otherNode.attributes.length) {
+ var nodeAttributes = this._getAttrsNoID(node);
+ var otherNodeAttributes = this._getAttrsNoID(otherNode);
+ if (nodeAttributes.length !== otherNodeAttributes.length) {
return false;
}
- for (var i = 0; i < node.attributes.length; i++) {
- var attr = node.attributes[i];
- var otherAttr = otherNode.attributes[i];
+ for (var i = 0; i < nodeAttributes.length; i++) {
+ var attr = nodeAttributes[i];
+ var otherAttr = otherNodeAttributes[i];
if (attr.name !== otherAttr.name || attr.value !== otherAttr.value) {
return false;
}
@@ -306,6 +308,7 @@ var HelperPlugin = AbstractPlugin.extend({
var range = this.context.invoke('editor.createRange');
var spaceToRemove = [];
+ var offset;
while ((node = nodes.pop())) {
next = node[prevOrNext];
while (next && !next.tagName) {
@@ -316,6 +319,31 @@ var HelperPlugin = AbstractPlugin.extend({
}
break;
}
+
+ // handle merge of text with p (useful in case of <li>text</li> with <li><p>text</p></li>)
+ if (next && dom.isText(node) && this.isNodeBlockType(next)) {
+ node = [next, next = node][0]; // swap node and next
+ direction = direction === 'next' ? 'prev' : 'next'; // switch direction
+ }
+ if (next && dom.isText(next) && this.isNodeBlockType(node)) {
+ if (this.isBlankNode(node, true)) {
+ $(node).empty();
+ }
+ $(node)[direction === 'next' ? 'append' : 'prepend'](next);
+ offset = direction === 'next' ? 0 : dom.nodeLength(next);
+ if (dom.isText(next[prevOrNext])) {
+ // merge text if needed
+ var sib = next[prevOrNext];
+ var firstText = (direction === 'next' ? sib : next).textContent;
+ var secondText = (direction === 'next' ? next : sib).textContent;
+ next.textContent = firstText + secondText;
+ $(sib).remove();
+ offset = firstText.length;
+ }
+ result = this.makePoint(next, offset);
+ break;
+ }
+
if (
!next ||
!(node.tagName || next.tagName === 'BR') ||
@@ -328,7 +356,7 @@ var HelperPlugin = AbstractPlugin.extend({
var newNext = next[prevOrNext];
$(next).remove();
next = newNext;
- var offset = (next ? direction === 'prev' : direction === 'next') ? dom.nodeLength(next) : 0;
+ offset = (next ? direction === 'prev' : direction === 'next') ? dom.nodeLength(next) : 0;
result = this.makePoint(next || node, offset);
if (!ifBrRemovedAndMerge) {
continue;
@@ -455,6 +483,11 @@ var HelperPlugin = AbstractPlugin.extend({
return this.makePoint(this.firstLeaf(blockToMergeFrom), 0);
}
+ // UL/OL can only have LI, UL or OR as direct children
+ if (dom.isList(blockToMergeInto) && !dom.isLi(blockToMergeFrom) && !dom.isList(blockToMergeFrom)) {
+ return;
+ }
+
return this.mergeNonSimilarBlocks(blockToMergeFrom, blockToMergeInto);
},
/**
@@ -601,22 +634,24 @@ var HelperPlugin = AbstractPlugin.extend({
var li = dom.ancestor(node, function (n) {
return n !== node && self.isNodeBlockType(n) || dom.isLi(n);
});
+ var nextElementSibling = direction === 'next' ? 'nextElementSibling' : 'previousElementSibling';
li = li && dom.isLi(li) ? li : undefined;
- if (li && direction === 'next') {
- if (li.nextElementSibling) {
+ if (li) {
+ if (li[nextElementSibling]) {
node = li;
} else {
node = dom.ancestor(node, function (n) {
- return ((n.tagName === 'UL' || n.tagName === 'OL') && n.nextElementSibling);
+ return ((n.tagName === 'UL' || n.tagName === 'OL') && n[nextElementSibling] &&
+ (direction === 'next' || dom.isList(n[nextElementSibling])));
});
}
}
- if (!node || !node[direction === 'next' ? 'nextElementSibling' : 'previousElementSibling']) {
+ if (!node || !node[nextElementSibling]) {
return false;
}
- node = node[direction === 'next' ? 'nextElementSibling' : 'previousElementSibling'];
+ node = node[nextElementSibling];
var ulFoldedSnippetNode = dom.ancestor(node, function (n) {
return $(n).hasClass('o_ul_folded');
@@ -633,7 +668,7 @@ var HelperPlugin = AbstractPlugin.extend({
node = this.firstBlockAncestor(node);
- li = dom.ancestor(node, function (n) {
+ li = dom.isList(node) ? undefined : dom.ancestor(node, function (n) {
return n !== node && self.isNodeBlockType(n) || dom.isLi(n);
});
li = li && dom.isLi(li) ? li : undefined;
@@ -1051,9 +1086,15 @@ var HelperPlugin = AbstractPlugin.extend({
* but without any.
*
* @param {Node} node
+ * @param {Boolean} brIsBlank true to consider nodes with BR element
+ * as ultimate only child to be blank
* @returns {Boolean}
*/
- isBlankNode: function (node) {
+ isBlankNode: function (node, brIsBlank) {
+ var self = this;
+ if (brIsBlank && dom.isBR(node)) {
+ return true;
+ }
if (dom.isVoid(node) || dom.isIcon(node)) {
return false;
}
@@ -1062,7 +1103,10 @@ var HelperPlugin = AbstractPlugin.extend({
}).test(node[dom.isText(node) ? 'textContent' : 'innerHTML'])) {
return true;
}
- if (node.childNodes.length && _.all(node.childNodes, this.isBlankNode.bind(this))) {
+ var areAllChildrenBlank = _.all(node.childNodes, function (node) {
+ return self.isBlankNode(node, brIsBlank);
+ });
+ if (node.childNodes.length && areAllChildrenBlank) {
return true;
}
return false;
@@ -1306,7 +1350,7 @@ var HelperPlugin = AbstractPlugin.extend({
$lastContents.after($contents);
}
}
- while (mergeFromBlock.parentNode && this.isBlankNode(mergeFromBlock.parentNode)) {
+ while (mergeFromBlock.parentNode && this.isBlankNode(mergeFromBlock.parentNode, true)) {
mergeFromBlock = mergeFromBlock.parentNode;
}
$(mergeFromBlock).remove();
@@ -1478,7 +1522,7 @@ var HelperPlugin = AbstractPlugin.extend({
if (isAfterBlank) {
$(node.previousSibling).remove();
}
- var isBeforeBlank = node.nextSibling && this.isBlankNode(node.nextSibling)
+ var isBeforeBlank = node.nextSibling && this.isBlankNode(node.nextSibling);
if (isBeforeBlank) {
$(node.nextSibling).remove();
}
@@ -1733,6 +1777,15 @@ var HelperPlugin = AbstractPlugin.extend({
// Private
//--------------------------------------------------------------------------
+ _getAttrsNoID: function (node) {
+ var nodeAttributes = [];
+ for (var i = 0; i < node.attributes.length; i++) {
+ if (node.attributes[i].name !== 'id') {
+ nodeAttributes.push(node.attributes[i]);
+ }
+ }
+ return nodeAttributes;
+ },
_insertTextNodeInEditableArea: function (range, text) {
// try to insert the text node in editable area
var textNode = this.document.createTextNode(text);
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js b/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js
index 3ab6a5f0317..94ec9306f7d 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js
@@ -296,6 +296,7 @@ var KeyboardPlugin = AbstractPlugin.extend({
var next = this.context.invoke('HelperPlugin.splitTree', ancestor, point, {
isSkipPaddingBlankHTML: !this.context.invoke('HelperPlugin.isNodeBlockType', point.node.parentNode) && !!point.node.parentNode.nextSibling
});
+ $(next).removeClass('o_checked');
while (next.firstChild) {
next = next.firstChild;
}
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/link.js b/addons/web_editor/static/src/js/wysiwyg/plugin/link.js
index 1b75339bf54..d8d261df980 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/link.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/link.js
@@ -358,12 +358,12 @@ var LinkPopover = Plugins.linkPopover.extend({
var $target = $(anchor);
- if (!$target.data('show_tooltip')) {
+ if (!$target.data('show_tooltip') && this.context.options.tooltip) {
$target.data('show_tooltip', true);
setTimeout(function () {
$target.tooltip({
title: _t('Double-click to edit'),
- trigger: 'manuel',
+ trigger: 'manual',
container: this.document.body,
placement: 'top'
}).tooltip('show');
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/media.js b/addons/web_editor/static/src/js/wysiwyg/plugin/media.js
index ce58a4eac86..e6a598a2813 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/media.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/media.js
@@ -43,6 +43,8 @@ var MediaPlugin = AbstractPlugin.extend({
'dblclick .note-editable': '_onDblclick',
},
+ mousePosition: {},
+
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
@@ -114,12 +116,12 @@ var MediaPlugin = AbstractPlugin.extend({
this.context.invoke('editor.saveTarget', target);
var $target = $(target);
- if (!$target.data('show_tooltip')) {
+ if (!$target.data('show_tooltip') && this.context.options.tooltip) {
$target.data('show_tooltip', true);
setTimeout(function () {
$target.tooltip({
title: _t('Double-click to edit'),
- trigger: 'manuel',
+ trigger: 'manual',
container: this.document.body,
}).tooltip('show');
setTimeout(function () {
diff --git a/addons/web_editor/static/src/js/wysiwyg/plugin/text.js b/addons/web_editor/static/src/js/wysiwyg/plugin/text.js
index d3ac908c507..16e22939cd4 100644
--- a/addons/web_editor/static/src/js/wysiwyg/plugin/text.js
+++ b/addons/web_editor/static/src/js/wysiwyg/plugin/text.js
@@ -85,7 +85,7 @@ var TextPlugin = AbstractPlugin.extend({
return;
}
nodes = textOnly ? this.document.createTextNode($(nodes).text()) : nodes;
- nodes = this._mergeAdjacentULs(nodes);
+ nodes = textOnly ? nodes : this._mergeAdjacentULs(nodes);
var point = this._getPastePoint();
// Prevent pasting HTML within a link: