Page edit view incorrectly reporting dirty rich text
See original GitHub issueIssue Summary
When editing a page that contains Draftail rich text (either as a RichTextField or as a RichTextBlock in a StreamField), navigating away sometimes presents a warning that the page has been changed, even though it hasn’t.
This happens for me consistently in Firefox 64, although I haven’t been able to reproduce in other browsers. Specifically what is happening is this:
-
The JSON representing the rich text is generated in a nicely formatted way, with line breaks and indents:
-
The page edit view HTML contains this JSON as the
<input value>
, including those line breaks and indents: -
The dirty form check’s
initialData
(generated via$form.serialize()
) gets set with a serialized version of that initialvalue
, including line breaks: -
Certain seemingly innocuous events cause the
<input value>
to change, removing the line breaks and indents:I can make this happen by highlighting the
<input>
in Firefox Developer Tools and (less predictably) by clicking away to another tab and coming back. Some event seems to cause the normalization of this value to clean it up.At first I thought this might be some Firefox quirk around handling of special characters within
<input value>
, but I couldn’t reproduce it using some manually generated HTML with the same content. So my guess is this is somehow related to how/when Draftail/Draft.js monitors/updates its state, but I don’t know enough about those internals to pinpoint it further. -
Because the
<input value>
has been changed, the subsequent dirty form check here always fails:This presents the user with a warning when navigating away, even though they haven’t done anything.
Steps to Reproduce
-
Start a new project with
wagtail start myproject
-
Create a simple page type in models.py:
class TestPage(Page): body = RichTextField() content_panels = Page.content_panels + [ FieldPanel('body'), ]
-
Create an instance of this page, entering some content in the body field.
-
Save the page, then, after it reloads, try navigating away. You’ll see a warning even though you didn’t make any further changes.
A simple fix that works for me is to modify this line to remove the nice formatting (just remove the indent=4, separators=(',', ': ')
). This makes the JSON more normalized upon first load, and so subsequent refreshes don’t change it. This does have the slight downside of making the page HTML less readable, and also still relies on the Python JSON formatting exactly matching what the browser regenerates.
Another option would be to add some kind of initial refresh before initialData
is saved in the dirty check, to ensure that whatever formatting Draftail/Draft.js wants to do to its content happens once before we save the reference state.
Ping @thibaudcolas - any idea what is happening here?
- I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: yes
Technical details
- Python version: 3.6.3
- Django version: 2.1.4
- Wagtail version: 2.5a0 (current master)
- Browser version: Firefox 64.0
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:11 (11 by maintainers)
Top GitHub Comments
I can confirm it happens in Chrome, Safari, and Firefox.
An alternative solution might be to listen to change events on the form?
Good question. It sounds like something I wouldn’t want to have to orchestrate (the different parts of the client-side code of Wagtail are generally very loosely coordinated), but it also does sound like a much better fix. I’ll have a look, thanks for getting back to me so quickly.