diff --git a/addons/web_editor/static/src/js/common/ace.js b/addons/web_editor/static/src/js/common/ace.js
index 91e31e1dbf1..61089330a76 100644
--- a/addons/web_editor/static/src/js/common/ace.js
+++ b/addons/web_editor/static/src/js/common/ace.js
@@ -40,7 +40,35 @@ function checkXML(xml) {
var xmlDoc = (new window.DOMParser()).parseFromString(xml, 'text/xml');
var error = xmlDoc.getElementsByTagName('parsererror');
if (error.length > 0) {
- return _getCheckReturn(false, parseInt(error[0].innerHTML.match(/[Ll]ine[^\d]+(\d+)/)[1], 10), error[0].innerHTML);
+ const errorEl = error[0];
+ const sourceTextEls = errorEl.querySelectorAll('sourcetext');
+ let codeEls = null;
+ if (sourceTextEls.length) {
+ codeEls = [...sourceTextEls].map(el => {
+ const codeEl = document.createElement('code');
+ codeEl.textContent = el.textContent;
+ const brEl = document.createElement('br');
+ brEl.classList.add('o_we_source_text_origin');
+ el.parentElement.insertBefore(brEl, el);
+ return codeEl;
+ });
+ for (const el of sourceTextEls) {
+ el.remove();
+ }
+ }
+ for (const el of [...errorEl.querySelectorAll(':not(code):not(pre):not(br)')]) {
+ const pEl = document.createElement('p');
+ for (const cEl of [...el.childNodes]) {
+ pEl.appendChild(cEl);
+ }
+ el.parentElement.insertBefore(pEl, el);
+ el.remove();
+ }
+ errorEl.innerHTML = errorEl.innerHTML.replace(/\r?\n/g, '
');
+ errorEl.querySelectorAll('.o_we_source_text_origin').forEach((el, i) => {
+ el.after(codeEls[i]);
+ });
+ return _getCheckReturn(false, parseInt(error[0].innerHTML.match(/[Ll]ine[^\d]+(\d+)/)[1], 10), errorEl.innerHTML);
}
} else if (typeof window.ActiveXObject != 'undefined' && new window.ActiveXObject('Microsoft.XMLDOM')) {
var xmlDocIE = new window.ActiveXObject('Microsoft.XMLDOM');
@@ -296,6 +324,10 @@ var ViewEditor = Widget.extend({
this.$editor.width(width);
this.aceEditor.resize();
this.$el.width(width);
+
+ if (this.$errorLine) {
+ this.$errorLine.popover('update');
+ }
}
function storeEditorWidth() {
localStorage.setItem('ace_editor_width', this.$el.width());
@@ -309,7 +341,14 @@ var ViewEditor = Widget.extend({
resizing = true;
}
function stopResizing() {
- resizing = false;
+ if (resizing) {
+ resizing = false;
+
+ if (this.errorSession) {
+ // To trigger an update of the error display
+ this.errorSession.setScrollTop(this.errorSession.getScrollTop() + 1);
+ }
+ }
}
function updateWidth(e) {
if (!resizing) return;
@@ -691,17 +730,13 @@ var ViewEditor = Widget.extend({
*/
_showErrorLine: function (line, message, resID, type) {
if (line === undefined || line <= 0) {
- if (this.$errorLine) {
- this.$errorLine.removeClass('o_error');
- this.$errorLine.off('.o_error');
- this.$errorLine = undefined;
- this.$errorContent.removeClass('o_error');
- this.$errorContent = undefined;
- }
+ __restore.call(this);
return;
}
- if (type) this._switchType(type);
+ if (type) {
+ this._switchType(type);
+ }
if (this._getSelectedResource() === resID) {
__showErrorLine.call(this, line);
@@ -714,17 +749,66 @@ var ViewEditor = Widget.extend({
this._displayResource(resID, this.currentType);
}
- function __showErrorLine(line) {
- this.aceEditor.gotoLine(line);
- this.$errorLine = this.$viewEditor.find('.ace_gutter-cell').filter(function () {
- return parseInt($(this).text()) === line;
- }).addClass('o_error');
- this.$errorLine.addClass('o_error').on('click.o_error', function () {
- var $message = $('