springload / draftail

📝🍸 A configurable rich text editor built with Draft.js

Home Page:https://www.draftail.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BUG: Pasting subscript and superscript from Word removes the formatting, even when they are enabled

coredumperror opened this issue · comments

What is the current behavior?
Pasting the block of text from this word doc removes the superscript and subscript formatting, while preserving the bold and italics.
draftail-test.docx

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. GIFs and screenshots are very helpful too.
To reproduce, open the attached .docx file, copy it's contents, then paste them into a RichText editor on a Wagtail site. I've added Superscript and Subscript behavior to my Draftail editor via the following hook:

@hooks.register('register_rich_text_features')
def register_core_draftail_plugins(features):
    # Add a "Subscript" plugin.
    features.register_editor_plugin(
        'draftail', 'subscript', draftail_features.InlineStyleFeature({
            'type': 'SUBSCRIPT',
            'icon': 'fa-subscript'
        })
    )
    features.register_converter_rule('contentstate', 'subscript', {
        'from_database_format': {'sub': InlineStyleElementHandler('SUBSCRIPT')},
        'to_database_format': {'style_map': {'SUBSCRIPT': 'sub'}},
    })
    features.default_features.append('subscript')

    # Add a "Superscript" plugin.
    features.register_editor_plugin(
        'draftail', 'superscript', draftail_features.InlineStyleFeature({
            'type': 'SUPERSCRIPT',
            'icon': 'fa-superscript'
        })
    )
    features.register_converter_rule('contentstate', 'superscript', {
        'from_database_format': {'sup': InlineStyleElementHandler('SUPERSCRIPT')},
        'to_database_format': {'style_map': {'SUPERSCRIPT': 'sup'}},
    })
    features.default_features.append('superscript')

What is the expected behavior?
Pasting superscript and subscript text from Word should preserve the formatting in Draftail.

Which versions of Draftail + Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draftail or Draft.js?
I'm in macOS Mojave, pasting from Word for Mac 16.25 into Chrome 74. The reason I discovered this is because my clients are reporting seeing the same behavior when pasting from Word for Windows on Windows 7, most likely into IE11 (though some use Firefox). My sites run Wagtail 2.3 (which appears to use Draftail 0.17.2), but I've confirmed that this happens with Wagtail 2.5.1 as well (with whatever version of Draftail it ships with).

I'm afraid I have no knowledge of whether this worked in any previous versions of Draftail.

Additional info
I do have one odd bit of behavior to report, which may be related? I've read the Draftail docs, and it seems like I should be able to use this dict in my hook to enable the use of SUPERSCRIPT in Draftail: {'type': 'SUPERSCRIPT'}. But if I try to use only that, I see "Sup" in my toolbar, instead of X2). Pasting superscript text still fails to retain its formatting, though.

Note also that when I paste from superscript text copied from a Draftail editor, the formatting is preserved. So it's not that pasting doesn't work at all. It just doesn't seem to work when copied from Word, Outlook, or Pages.

Hmmm... and I'm just now realizing that this might actually be a bug in draftjs-filters, rather than Draftail. But I have no idea how to check.

Wagtail 2.3 appears to use v1.0.0 of Draftjs filters, while 2.5.1 uses 2.2.3. Though I did still see this behavior with Wagtail 2.5.1, so I'm not sure it's something that's been fixed since v1.0.0.

Hey @coredumperror, thanks for the detailed report.

Unfortunately this behavior is from Draft.js (open issue: facebookarchive/draft-js#166), and not something that can directly be changed in either Draftail or draftjs-filters. It’s Draft.js that decides what gets preserved (or not) when copy-pasting rich content, draftjs-filters just further remove extra content because Draft.js itself has no awareness of what formatting is enabled or not.

I think Draft.js supporting subscript and superscript might just be a matter of making a pull request to it, with changes to:

  • Map <sub> tag to SUBSCRIPT style
  • Map <sup> tag to SUPERSCRIPT style
  • Map vertical-align: bottom; inline style to SUBSCRIPT style?
  • Map vertical-align: top; inline style to SUPERSCRIPT style?

I’ll have a go at doing this, and confirm whether it’s ok/needed to use vertical-align styles like this – I’ll do further research to determine which rich text sources use tags or inline styles for this.

While at it, I might also have a look at whether it would be sensible to completely override Draft.js’ HTML processing so those types of changes could be made in Draftail alone (and to hopefully fix other known issues with the processing). I’ve considered this in the past and decided it wasn’t worth it, but this seems like a good time to reconsider.

Thanks for the heads up, and the potential for future improvements. :)

Just a note that I haven’t forgotten about this, and it’s getting more likely I’ll have time to fix the issue.

I think I’ll both provide a PR for Draft.js itself, and also implement an override as described above. I don’t think it’s needed to solve this one shortcoming, but I also have many other use cases in mind where Draft.js’ one-size-fits-all approach just doesn’t cut it.

Also I’m not sure why I put this as an enhancement – even if it’s an issue with Draft.js itself, I’d still consider it a bug.

Cool. Glad to hear it.

Did anything ever come of this? My team is still getting complaints about superscript/subscript not pasting in from Word properly.

Yes, although no fix ready to be used yet.

I initially attempted to make a PR to Draft.js as mentioned above, but this stalled due to them doing a rewrite of their copy-paste processing in the newer version (v0.11.0) while I was halfway through my changes. In this newer version, they also introduced APIs that make it much simpler to completely override the copy-paste behavior, which is the only option I’m currently considering – it’d solve many more issues for us than just improved copy-pasting from specific editors.

Now – I’m working on Draft.js v0.11.0 compatibility so we actually make use of those APIs in Draftail. I’m currently reviewing the new copy-paste processing to see whether we can ship a release with it, or whether there are regressions compared to the current behavior.

Cool beans! Once that gets done, I'd definitely appreciate a heads up.