Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor Driver Support #2566

Closed
askvortsov1 opened this issue Jan 25, 2021 · 4 comments
Closed

Editor Driver Support #2566

askvortsov1 opened this issue Jan 25, 2021 · 4 comments

Comments

@askvortsov1
Copy link
Sponsor Member

askvortsov1 commented Jan 25, 2021

A WYSIWYG editor is probably among the most requested Flarum features of all time (https://discuss.flarum.org/d/1537-pick-three-features-you-d-love-to-see-in-flarum), with numerous extension attempts (https://discuss.flarum.org/t/extensions?q=editor). However, this has been challenging for several reasons:

  • Any editor must be compatible with s9e/textformatter (so no Quill or HTML-based, must output plain markdown)
  • A good editor should look modern and have small bundle size (so no tinyMCE, ckEditor, or anything of that sort)
  • We should be able to add support for custom elements/customizations
  • A succesful editor would need to integrate with mentions and emoji's autocomplete dropdowns
  • Inserting an editor into the existing textarea tends to class with mdarea, used in Markdown
  • Some users might prefer a raw markdown experience
  • Use of execCommand is a no-go (https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand)

So I set out to experiment and explore potential improvements that would enable smooth integration of a WYSIWYG editor with Flarum. For this experiment I used proseMirror, a library for building editors. Other options:

Try 1

I attempted to do what most rich text extensions so far have done, and extend/override various methods of TextEditor. This works on a basic level. https://github.com/askvortsov1/flarum-rich-text

Observations:

  • Switching between mdarea and a replacement is messy while the editor is open, simpler to go with one or the other, and control which one in user settings
  • Mentions and emoji autocomplete dropdowns work by wrapping TextEditor's textarea html element in a div wrapper, then manipulating that. We can't assume that textarea will exist
  • On a similar note, direct interactions by extensions with whichever editor is used should be avoided at all costs: we should expand SuperTextarea to act as a full abstraction for the text editor

Try 2

I tried going in a significantly different direction, and including a basic proseMirror setup directly in core. I added styles and customizations so that it exactly resembled the html textarea-based solution. Then, flarum/markdown could extend that basic proseMirror config to add markdown support. I was also hoping to get mentions working with this solution, but wasn't able to get that done. #2567, flarum/markdown#23

Observations:

  • This caused minified forum size to skyrocket from 350kb to 550kb. Ouch...
  • If someone prefers a raw markdown editor over WYSIWYG, this leaves them without a choice. To that end, I don't think it aligns with Flarum's philosophy to make bundled extension functionality dependent on a rich text editor.
  • Splitting configuration across 2 packages (core and markdown) gets REALLY messy. It would be preferable to keep things in one package as much as possible.
  • prosemirror is organized as a large number (4 core, >8 module) npm packages that really clutter core's package.json. Furthermore, the markdown config modifications required those same packages again, meaning that either we'd have duplicated code, or we needed to load literally all of it into expose loader, and extend webpack config for markdown. I ended up going with the latter, since when I tried the first option, the duplicate packages broke the editor. Needless to say, this was a huge mess, and we should keep config together as much as possible.

My Proposal

I don't think core should include a complex, full rich text editor. It's messy, and IMO it goes against the Flarum philosophy. That being said, with a few simple steps, Flarum could do a lot better in terms of enabling WYSIWYG as an extension. I propose the following:

  • We should adopt a driver-based architecture for frontend editors (based on [Proof of Concept] ProseMirror (WIP) #2567)
    • The public API for the driver should be contained in app.composer.editor.
    • A TS interface for it should be added, based on SuperTextarea and some methods from ProseMirrorEditor (focus, destroy, etc)
    • The actual HTML element for the editor shouldn't be hardcoded into the component, it should be inserted by the driver as part of the driver's boot process. That being said, we still need a "base editor" component that mentions/emoji would wrap.
    • The driver instance should be constructed and created by a buildEditorDriver method of TextEditor
  • Markdown should be responsible for rendering and markdown-specific controls
    • mdarea should be brought into core (without the inline bug introduced in beta 14). It's not WYSIWYG as much as it makes dealing with lists easier, and it's pretty miniscule. Without the inlines, we're not really using any markdown-specific features.
    • MarkdownToolbar and all the apply utils should be brought into core (https://github.com/flarum/core/issues/1872) as part of that main driver
  • mentions and emoji should stop interacting directly with the textarea, and work entirely through the driver
  • A bundled extension using proseMirror should be created. It should depend on markdown to offer markdown support, and (if possible) should be extensible so that custom elements can be added (such as with mentions), and so that the menu bar can be extended (by fof/upload, for instance). We might want to wait for the Allow optional dependency / one-of-several dependency requirements to control extension boot order #1318 feature for this.

Outstanding questions:

@askvortsov1 askvortsov1 changed the title [Investigation] ProseMirror WYSIWYG Editor [Investigation] WYSIWYG Editor Jan 25, 2021
@luceos
Copy link
Member

luceos commented Jan 26, 2021

I like your proposal. As to your question, I think that we should bundle a decent WYSIWYG by default that includes mentions. Yet allow for a fully trimmed down Composer as well. So removing the bundled editor should provide the option for alternate solutions, even if that means having to lose mentions functionality as well. A good mentions extensions will never fully be independent from the editor, because rendering, parsing and linking suggestions while keeping user privacy in mind is not easy.

@askvortsov1
Copy link
Sponsor Member Author

fully be independent from the editor, because rendering, parsing and linking suggestions while keeping user privacy in mind is not easy

Well, actually, it kind of is. If we continue to literally encode mentions as @USERNAME, the current approach of hovering a dropdown above and entering that into the composer via the editor interface works fine. And of course we could adopt something like https://www.npmjs.com/package/prosemirror-suggest for cleaner integration, but that's just style.

What I means is that if we want to abstract away the username in favor of id / display name, https://github.com/flarum/core/issues/1734#issuecomment-644391424 would make it cumbersome to type out mentions, so it would integrate well with proseMirror but not the standard editor.

@askvortsov1
Copy link
Sponsor Member Author

askvortsov1 commented Feb 10, 2021

To clarify: the milestone item is the above-listed 4 PRs that switch to an editor driver solution. Once that's merged I'll be releasing a third-party rich text editor extension. I designed it to be highly extensible; as a proof of concept, I'll also be releasing an update to https://discuss.flarum.org/d/18922-markdown-tables, which includes support for editing the table via WYSIWYG.

There are currently no plans for core to include a rich text editor directly due to the bundle size increase involved (the solution I got working performs extremely well and is extensible, but is ~350 kb minified, which is equivalent to all of core's forum JS. This would be the case for other editors as well). We might decide to ship one as a bundled extension sometime in the future, but that decision has not yet been made, and will not be made until after stable is released.

@askvortsov1
Copy link
Sponsor Member Author

Another benefit of the above refactors I forgot to mention: TextEditor is now completely detached from composer: all it cares is that a composer attr is passed in, and it'll set the editor driver instance as a property on that. But that composer attr could be anything. So it should be very easy to use TextEditor for other stuff (moderator notes/warnings, discussion templates, etc).

Sometime in the future (separate from this PR), we should moveTextEditor and the editor driver from forum to common; that way, it will be usable in the admin dashboard, e.g. for flarum/issue-archive#360

@askvortsov1 askvortsov1 changed the title [Investigation] WYSIWYG Editor Editor Driver Support Feb 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants