From 4e21d6180b909ecd0e9df00c4c66467df4eb77d1 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 7 Aug 2019 13:31:01 +0000 Subject: [FIX] web_editor: do to try to inline css for readonly html fields closes odoo/odoo#35539 Signed-off-by: Christophe Simonis --- addons/web_editor/static/src/js/backend/convert_inline.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/backend/convert_inline.js b/addons/web_editor/static/src/js/backend/convert_inline.js index a3fc6282ede..b15f49339fe 100644 --- a/addons/web_editor/static/src/js/backend/convert_inline.js +++ b/addons/web_editor/static/src/js/backend/convert_inline.js @@ -396,7 +396,7 @@ FieldHtml.include({ * @override */ commitChanges: function () { - if (this.nodeOptions['style-inline']) { + if (this.nodeOptions['style-inline'] && this.mode === "edit") { this._toInline(); } return this._super(); @@ -452,7 +452,7 @@ FieldHtml.include({ * @override */ _onLoadWysiwyg: function () { - if (this.nodeOptions['style-inline']) { + if (this.nodeOptions['style-inline'] && this.mode === "edit") { this._fromInline(); } this._super(); -- cgit v1.2.3 From 8e4b8be4e6465204038798db137451c95a8050b6 Mon Sep 17 00:00:00 2001 From: Gorash Date: Thu, 21 Mar 2019 12:16:01 +0000 Subject: [FIX] web_editor: remove virtual corrector/completion keyboard glitch For the ours need, we can not let the contentEditable behavior. Indeed, this one does not have the same behavior according to the browser. The DOM node could be erase, merge, cut, in them according to the keyboard interactions. The problem is that if we have to manage these behaviors, we have to manage everything. It was already the case in the previous version, however before we created an editor by zone and by a hack we mix the history. In the case of the virtual keyboard of some OS / Phone, the events are different and the autocompletion does not update (bug that prevents modification interactions with javascript). In order to solve these problems, we use another event for the insertion of the characters. However, we must also force the update of the corrector by forcing a blur and a focus. The current version is a temporary version. We are currently working on a version that uses a virtual dom and does not need to do excessive prevent default. --- .../web_editor/static/src/js/backend/field_html.js | 3 + .../static/src/js/wysiwyg/plugin/keyboard.js | 167 ++++++++------------- 2 files changed, 67 insertions(+), 103 deletions(-) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/backend/field_html.js b/addons/web_editor/static/src/js/backend/field_html.js index 9f6cfaa586a..dc4d1d0af16 100644 --- a/addons/web_editor/static/src/js/backend/field_html.js +++ b/addons/web_editor/static/src/js/backend/field_html.js @@ -177,6 +177,8 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { * @returns {Object} */ _getWysiwygOptions: function () { + var iPhone = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; + return { recordInfo: { context: this.record.getContext(this.recordParams), @@ -195,6 +197,7 @@ var FieldHtml = basic_fields.DebouncedField.extend(TranslatableFieldMixin, { 'SHIFT+TAB': null, }, mac: { + 'ENTER': iPhone ? null : 'insertParagraph', 'TAB': null, 'SHIFT+TAB': null, }, 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 94ec9306f7d..534fdcab523 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js @@ -9,18 +9,27 @@ dom.isAnchor = function (node) { return (node.tagName === 'A' || node.tagName === 'BUTTON' || $(node).hasClass('btn')) && !$(node).hasClass('fa') && !$(node).hasClass('o_image'); }; +var keycode = ({ + '8': 'BACKSPACE', + '9': 'TAB', + '13': 'ENTER', + '46': 'DELETE', +}); -var KeyboardPlugin = AbstractPlugin.extend({ - events: { - 'summernote.keydown': '_onKeydown', - 'DOMNodeInserted .note-editable': '_removeGarbageSpans', - }, - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- +var iPhone = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; +var KeyboardPlugin = AbstractPlugin.extend({ + events: iPhone ? + { + 'DOMNodeInserted .note-editable': '_removeGarbageSpans', + } : + { + 'summernote.keydown': '_onKeydown', + 'DOMNodeInserted .note-editable': '_removeGarbageSpans', + 'keypress .note-editable': '_onKeyPress', + 'textInput .note-editable': '_onTextInput', + }, //-------------------------------------------------------------------------- // Private @@ -1014,76 +1023,40 @@ var KeyboardPlugin = AbstractPlugin.extend({ * @returns {Boolean} true if case handled */ _onKeydown: function (se, e) { - var self = this; - var handled = false; - if (e.ctrlKey && e.key === 'a') { e.preventDefault(); this._selectAll(); return; } + if (!keycode[e.keyCode]) { + return; + } - if (e.key && - (e.key.length === 1 || e.key === "Dead" || e.key === "Unidentified") && - !e.ctrlKey && !e.altKey && !e.metaKey) { - - if (e.key === "Dead" || e.key === "Unidentified") { - this._accented = true; - } - - // Record undo only if either: - clearTimeout(this.lastCharIsVisibleTime); - // e.key is punctuation or space - var stopChars = [' ', ',', ';', ':', '?', '.', '!']; - if (stopChars.indexOf(e.key) !== -1) { - this.lastCharVisible = false; - } - // or not on top of history stack (record undo after undo) - var history = this.context.invoke('HistoryPlugin.getHistoryStep'); - if (history && history.stack.length && history.stackOffset < history.stack.length - 1) { - this.lastCharVisible = false; - } - // or no new char for 500ms - this.lastCharIsVisibleTime = setTimeout(function () { - self.lastCharIsVisible = false; - }, 500); - if (!this.lastCharIsVisible) { - this.lastCharIsVisible = true; - this.context.invoke('HistoryPlugin.recordUndo'); - } - - if (e.key !== "Dead") { - this._onVisibleChar(e, this._accented); - } - } else { - this.lastCharIsVisible = false; - this.context.invoke('editor.clearTarget'); - this.context.invoke('MediaPlugin.hidePopovers'); - this.context.invoke('editor.beforeCommand'); - switch (e.keyCode) { - case 8: // BACKSPACE - handled = this._onBackspace(e); - break; - case 9: // TAB - handled = this._onTab(e); - break; - case 13: // ENTER - handled = this._onEnter(e); - break; - case 46: // DELETE - handled = this._onDelete(e); - break; - } - if (handled) { - this._preventTextInEditableDiv(); - this.context.invoke('editor.saveRange'); - e.preventDefault(); - this.context.invoke('editor.afterCommand'); - } + this.context.invoke('editor.clearTarget'); + this.context.invoke('MediaPlugin.hidePopovers'); + this.context.invoke('editor.beforeCommand'); + var handled = false; + switch (keycode[e.keyCode]) { + case 'BACKSPACE': + handled = this._onBackspace(e); + break; + case 'TAB': + handled = this._onTab(e); + break; + case 'ENTER': + handled = this._onEnter(e); + break; + case 'DELETE': + handled = this._onDelete(e); + break; } - if (e.key !== "Dead") { - this._accented = false; + if (handled) { + e.preventDefault(); + this._preventTextInEditableDiv(); + this.context.invoke('editor.saveRange'); + this.context.invoke('editor.afterCommand'); } + return handled; }, /** * Handle BACKSPACE keydown event. @@ -1223,45 +1196,33 @@ var KeyboardPlugin = AbstractPlugin.extend({ return false; }, /** - * Handle visible char keydown event. + * Handle char input. * * @private * @param {jQueryEvent} e - * @returns {Boolean} true if case is handled and event default must be prevented */ - _onVisibleChar: function (e, accented) { - var self = this; + _onKeyPress: function (e) { + console.log(e.originalEvent); e.preventDefault(); - if (accented) { - this.editable.normalize(); - var baseRange = this.context.invoke('editor.createRange'); - - var $parent = $(baseRange.sc.parentNode); - var parentContenteditable = $parent.attr('contenteditable'); - $parent.attr('contenteditable', false); - - var accentPlaceholder = this.document.createElement('span'); - $(baseRange.sc).after(accentPlaceholder); - $(accentPlaceholder).attr('contenteditable', true); - - var range = this.context.invoke('editor.setRange', accentPlaceholder, 0); - range.select(); + this.context.invoke('HelperPlugin.insertTextInline', e.key); + }, + /** + * Handle char input. + * + * @private + * @param {jQueryEvent} e + */ + _onTextInput: function (e) { + e.originalEvent.preventDefault(); - setTimeout(function () { - var accentedChar = accentPlaceholder.innerHTML; - $(accentPlaceholder).remove(); - if (parentContenteditable) { - $parent.attr('contenteditable', parentContenteditable); - } else { - $parent.removeAttr('contenteditable'); - } - baseRange.select(); - self.context.invoke('HelperPlugin.insertTextInline', accentedChar); - }); - } else { - this.context.invoke('HelperPlugin.insertTextInline', e.key); + var text = e.originalEvent.data; + if (!text) { + return; } - return true; + if (text === 'Spacebar') { + text = ' '; + } + this.context.invoke('HelperPlugin.insertTextInline', text); }, }); -- cgit v1.2.3 From cfbe4bbe429de18b06ca78628cfe7c6caf98ea4c Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Tue, 6 Aug 2019 14:08:59 +0000 Subject: [FIX] web_editor: fix snippets reloading traceback --- addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js index d13ddf63038..c325458b3f2 100644 --- a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js +++ b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js @@ -746,6 +746,7 @@ var SnippetsMenu = Widget.extend({ }, }); this.cacheSnippetTemplate[this.options.snippets] = this._defLoadSnippets; + return this.cacheSnippetTemplate[this.options.snippets]; }, /** * Sets the instance variables $editor, $body and selectorEditableArea. -- cgit v1.2.3 From 97e6b7f126584af854d5a67180240f4cc429a29b Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Wed, 7 Aug 2019 06:25:50 +0000 Subject: =?UTF-8?q?[FIX]=C2=A0web=5Feditor:=20fix=20snippets=20preview=20o?= =?UTF-8?q?n=20drop=20not=20displaying?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/web_editor/static/src/js/wysiwyg/plugin/media.js | 2 +- addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'addons/web_editor/static/src') 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 6e539787a67..d08df439e2f 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/media.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/media.js @@ -932,7 +932,7 @@ _.extend(wysiwygTranslation.image, { dom.isVideo = function (node) { node = node && !node.tagName ? node.parentNode : node; return (node.tagName === "IFRAME" || node.tagName === "DIV") && - (node.parentNode.className && node.parentNode.className.indexOf('media_iframe_video') !== -1 || + (node.parentNode && node.parentNode.className && node.parentNode.className.indexOf('media_iframe_video') !== -1 || node.className.indexOf('media_iframe_video') !== -1); }; diff --git a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js index c325458b3f2..408e9607924 100644 --- a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js +++ b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js @@ -1359,6 +1359,7 @@ var SnippetsMenu = Widget.extend({ if (!dropped) { dropped = true; $(this).first().after($toInsert).addClass('d-none'); + $toInsert.removeClass('oe_snippet_body'); } }, out: function () { @@ -1367,6 +1368,7 @@ var SnippetsMenu = Widget.extend({ dropped = false; $toInsert.detach(); $(this).removeClass('d-none'); + $toInsert.addClass('oe_snippet_body'); } }, }); -- cgit v1.2.3 From 5578b98ad7dcbee97cb2eaea29f91daae4914060 Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Wed, 7 Aug 2019 07:08:14 +0000 Subject: [FIX] web_editor: fix selecting snippet template text --- addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js | 1 + 1 file changed, 1 insertion(+) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js index 408e9607924..4193aef5332 100644 --- a/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js +++ b/addons/web_editor/static/src/js/wysiwyg_snippets/snippets.editor.js @@ -678,6 +678,7 @@ var SnippetsMenu = Widget.extend({ // on text changes this.$document.on('click.snippets_menu', '.o_default_snippet_text', function (ev) { $(ev.target).selectContent(); + $(ev.target).removeClass('o_default_snippet_text'); }); this.$document.on('keyup.snippets_menu', function () { var range = Wysiwyg.getRange(this); -- cgit v1.2.3 From d0e80593304415b605bc28f00239a391604a4fcf Mon Sep 17 00:00:00 2001 From: David Monjoie Date: Wed, 7 Aug 2019 09:04:35 +0000 Subject: [FIX] web_editor: disable custom handling for Safari MacOS --- addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js | 11 ++++++++--- addons/web_editor/static/src/js/wysiwyg/plugin/text.js | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'addons/web_editor/static/src') 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 534fdcab523..141d4c1bf2e 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js @@ -16,9 +16,9 @@ var keycode = ({ '46': 'DELETE', }); +var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); var iPhone = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; - var KeyboardPlugin = AbstractPlugin.extend({ events: iPhone ? { @@ -1203,8 +1203,10 @@ var KeyboardPlugin = AbstractPlugin.extend({ */ _onKeyPress: function (e) { console.log(e.originalEvent); - e.preventDefault(); - this.context.invoke('HelperPlugin.insertTextInline', e.key); + if (!isSafari || iPhone) { + e.preventDefault(); + this.context.invoke('HelperPlugin.insertTextInline', e.key); + } }, /** * Handle char input. @@ -1213,6 +1215,9 @@ var KeyboardPlugin = AbstractPlugin.extend({ * @param {jQueryEvent} e */ _onTextInput: function (e) { + if (isSafari && !iPhone) { + return; + } e.originalEvent.preventDefault(); var text = e.originalEvent.data; 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 5337661fa76..2b7d10d02fd 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/text.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/text.js @@ -766,6 +766,11 @@ var TextPlugin = AbstractPlugin.extend({ * @param {jQueryEvent} e */ _onPaste: function (se, e) { + var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); + var iPhone = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; + if (isSafari && !iPhone) { + return; + } se.preventDefault(); se.stopImmediatePropagation(); e.preventDefault(); -- cgit v1.2.3 From b384a00fe26131d716dd0c87f3fcf0a164f95aee Mon Sep 17 00:00:00 2001 From: Goaman Date: Wed, 7 Aug 2019 10:13:13 +0000 Subject: [FIX] web_editor: Do not remove block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not remove block in _removeNextEmptyUnbreakable. Before this commit, when you tried to remove insert a character in a td, with an empty td after the first one. The function _removeNextEmptyUnbreakable removed the empty td. It was for example breaking snippet in the website and mass_mailing. closes odoo/odoo#32096 Signed-off-by: Adrien Dieudonné (adr) --- addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'addons/web_editor/static/src') 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 141d4c1bf2e..9ac05220e45 100644 --- a/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js +++ b/addons/web_editor/static/src/js/wysiwyg/plugin/keyboard.js @@ -827,7 +827,7 @@ var KeyboardPlugin = AbstractPlugin.extend({ } }, /** - * Remove the first unbreakable ancestor's next sibling if empty. + * Remove the first unbreakable ancestor's next sibling if not a block and empty. * * @private * @param {Node} node @@ -843,7 +843,7 @@ var KeyboardPlugin = AbstractPlugin.extend({ var isNextContainsOnlyInvisibleText = nextUnbreakable && _.all($(nextUnbreakable).contents(), function (n) { return dom.isText(n) && !self.context.invoke('HelperPlugin.isVisibleText', n); }); - if (isNextEmpty || isNextContainsOnlyInvisibleText) { + if (!dom.isBlock(nextUnbreakable) && (isNextEmpty || isNextContainsOnlyInvisibleText)) { $(nextUnbreakable).remove(); } }, -- cgit v1.2.3