diff --git a/addons/mail/static/src/components/message/message.js b/addons/mail/static/src/components/message/message.js index 146e1c66809..3d7c5a5bcfa 100644 --- a/addons/mail/static/src/components/message/message.js +++ b/addons/mail/static/src/components/message/message.js @@ -104,6 +104,12 @@ class Message extends Component { _constructor() {} mounted() { + // Remove all readmore before if any before reinsert them with _insertReadMoreLess. + // This is needed because _insertReadMoreLess is working with direct DOM mutations + // which are not sync with Owl. + for (const el of [...this._contentRef.el.querySelectorAll(':scope .o_Message_readMoreLess')]) { + el.remove(); + } this._insertReadMoreLess($(this._contentRef.el)); this._update(); } @@ -309,6 +315,8 @@ class Message extends Component { * Those text nodes need to be wrapped in a span (toggle functionality). * All consecutive elements are joined in one 'read more/read less'. * + * FIXME This method should be rewritten (task-2308951) + * * @private * @param {jQuery} $element */ @@ -362,7 +370,7 @@ class Message extends Component { for (const group of groups) { // Insert link just before the first node const $readMoreLess = $('', { - class: 'o_Message_readMore', + class: 'o_Message_readMoreLess', href: '#', text: READ_MORE, }).insertBefore(group[0]); diff --git a/addons/mail/static/src/components/message/message.scss b/addons/mail/static/src/components/message/message.scss index 1106c56d992..ebb04174383 100644 --- a/addons/mail/static/src/components/message/message.scss +++ b/addons/mail/static/src/components/message/message.scss @@ -122,7 +122,7 @@ justify-content: center; } -.o_Message_readMore { +.o_Message_readMoreLess { display: block; } diff --git a/addons/mail/static/src/widgets/form_renderer/form_renderer_tests.js b/addons/mail/static/src/widgets/form_renderer/form_renderer_tests.js index 6952e9cc8da..2fcc01b3966 100644 --- a/addons/mail/static/src/widgets/form_renderer/form_renderer_tests.js +++ b/addons/mail/static/src/widgets/form_renderer/form_renderer_tests.js @@ -426,6 +426,169 @@ QUnit.test('chatter should become enabled when creation done', async function (a ); }); +QUnit.test('read more/less links are not duplicated when switching from read to edit mode', async function (assert) { + assert.expect(5); + + this.data['mail.message'].records = [{ + author_id: [100, "Someone"], + // "data-o-mail-quote" added by server is intended to be compacted in read more/less blocks + body: ` +
+ Dear Joel Willis,
+ Thank you for your enquiry.
+ If you have any questions, please let us know. +

+ Thank you,
+ --
+ System +
+
+ `, + id: 1000, + model: 'res.partner', + res_id: 1, + }]; + this.data['res.partner'].records = [{ + display_name: "first partner", + id: 1, + }]; + await this.createView({ + data: this.data, + hasView: true, + // View params + View: FormView, + model: 'res.partner', + res_id: 1, + arch: ` +
+ + + +
+ +
+
+ `, + }); + assert.containsOnce( + document.body, + '.o_Chatter', + "there should be a chatter" + ); + assert.containsOnce( + document.body, + '.o_Message', + "there should be a message" + ); + assert.containsOnce( + document.body, + '.o_Message_readMoreLess', + "there should be only one read more" + ); + + await afterNextRender(() => { + document.querySelector('.o_form_button_edit').click(); + }); + assert.containsOnce( + document.body, + '.o_Message_readMoreLess', + "there should still be only one read more after switching to edit mode" + ); + + await afterNextRender(() => { + document.querySelector('.o_form_button_cancel').click(); + }); + assert.containsOnce( + document.body, + '.o_Message_readMoreLess', + "there should still be only one read more after switching back to read mode" + ); +}); + +QUnit.test('read more links becomes read less after being clicked', async function (assert) { + assert.expect(6); + + this.data['mail.message'].records = [{ + author_id: [100, "Someone"], + // "data-o-mail-quote" added by server is intended to be compacted in read more/less blocks + body: ` +
+ Dear Joel Willis,
+ Thank you for your enquiry.
+ If you have any questions, please let us know. +

+ Thank you,
+ --
+ System +
+
+ `, + id: 1000, + model: 'res.partner', + res_id: 1, + }]; + this.data['res.partner'].records = [{ + display_name: "first partner", + id: 1, + }]; + await this.createView({ + data: this.data, + hasView: true, + // View params + View: FormView, + model: 'res.partner', + res_id: 1, + arch: ` +
+ + + +
+ +
+
+ `, + }); + assert.containsOnce( + document.body, + '.o_Chatter', + "there should be a chatter" + ); + assert.containsOnce( + document.body, + '.o_Message', + "there should be a message" + ); + assert.containsOnce( + document.body, + '.o_Message_readMoreLess', + "there should be a read more" + ); + assert.strictEqual( + document.querySelector('.o_Message_readMoreLess').textContent, + 'read more', + "read more/less link should contain 'read more' as text" + ); + + await afterNextRender(() => { + document.querySelector('.o_form_button_edit').click(); + }); + assert.strictEqual( + document.querySelector('.o_Message_readMoreLess').textContent, + 'read more', + "read more/less link should contain 'read more' as text" + ); + + await afterNextRender(() => { + document.querySelector('.o_Message_readMoreLess').click(); + }); + assert.strictEqual( + document.querySelector('.o_Message_readMoreLess').textContent, + 'read less', + "read more/less link should contain 'read less' as text after it has been clicked" + ); +}); + QUnit.test('Form view not scrolled when switching record', async function (assert) { assert.expect(6);