Looks decent. The approach taken is the right one: we do something very similar with the Squire rich text editor (https://github.com/neilj/Squire) which I wrote for FastMail's webmail. Basically the browser can't be trusted to do any formatting itself, which is a slightly depressing state of affairs, especially as there has been zero improvements in this area for the last 5 years. I guess it's not shiny enough for browser devs to focus on.
Looking through the code, a few things jumped out that should be looked at:
* The HTML sanitisation using document.implementation doesn't account for DOM clobbering so is currently bypassable with the right malicious content. I recommend using https://github.com/cure53/DOMPurify for this rather than writing your own. It's tricky to get all the edge cases right, so better to use something that's been reviewed by several people (and in DOMPurify's case also undergone a formal security review). Again, we use this at FastMail as part of our webmail.
Nice to see this particular bit of info high up in the README (though "as seen in Basecamp 3" would fit well in the Github repo description line):
> Trix is an open-source project from Basecamp, the creators of Ruby on Rails. Millions of people trust their text to Basecamp, and we built Trix to give them the best possible editing experience. See Trix in action in the all-new Basecamp 3.
Nothing gets me more interested in trying out a JavaScript library than seeing that it's used in a mainstream production product, especially a money-making/critical product by very same the company that created/maintains it...it's a bit of guarantee that the API is relatively mature/won't-go-crazy and that someone has a vested interest in keeping the library up to date with changes in the Web. That was why React was so much more appealing to me than Angular, relative to their respective public release dates...React was already in production at Instagram and parts of Facebook, whereas I don't think Angular was in any of Google's main public facing products (i.e. search, YouTube, Maps)
Great timing, we were just looking for a new editor for our project. Since there are so many choices, here's a list of everything mentioned in this post.
Redactor - http://imperavi.com/redactor/ - we used this in production but quality has gone down, v2 is half the functionality at 3x the price, not recommended anymore
Since there are quality of life improvements that are often invisible at first sight, I'd like to point out a few ProseMirror hidden features:
- Typing "- " at the start of a line creates an unordered list, and typing "1. " creates an ordered list.
- Typing the '"' character correctly replaces it with the right unicode character, and you can undo that replacement by hitting backspace. The same goes with "--".
- Surprisingly, the keyboard shortcuts are often inconsistent across editors; ProseMirror tends to rely on widely-used shortcuts.
That said, as I mention here[0], I am most hopeful for Slack's text editor, which supports many more enhanced features -- but unfortunately doesn't seem open-source, and is currently quite buggy.
One thing this gets right that heaps of other WYSIWYG's get wrong is lists. You can create a proper multi-level list here with order and unordered lists nested inside each other correctly. This sort of stuff is actually important for creating accessible documents as things like flowcharts need a plain text version and nesting lists is a reasonable way of displaying these.
Absolutely. I do note though that headers (h1, h2, etc.) are not supported (unless there's a way to customize the format bar past what I saw in the demo). Switching from ul/ol/li to h1, h2 and back has been a MAJOR headache for us when we tried to offer text-editing features based on an older library called wysihtml5. Medium also dodges that altogether. Text editing is still extremely complicated.
My litmus test for WYSIWYG lists — which Trix fails — is
1. start a numbered list
2. put several paragraphs...
> including some nested block element e.g. quote
... inside one list item
3. Then continue the numbered list (not from 1!)
This is something that's trivial to express in markdown, LaTeX etc but annoying to impossible with WYSIWYG where being in a list pretends to be a per-paragraph boolean property. In many WYSIWYGs you can't semantically put block-level stuff "into" a list item, only fake it by pressing Enter, cancelling numbering on the new paragraph and increasing indent to align with list item.
This makes it a nightmare to continue the list afterwards, because actually I've already closed it. Surprisingly, while many WYSIWYG editors are only ready to start a new "1. " list, they do allow me to paste the compound item into the middle of an existing list without interrupting its numbering. Sometimes there are other rituals involving liberal consumption of Shift+Enter and Backspace, dancing with text, and promising my firstborn to be contentEditable...
Anyway Trix fails it on the simpler task of multiple paragraphs in a list item. I haven't looked at the code but it seems its content model (at least strictly enforced) for list items is something like:
- a single block element (can be a quote or code)
- followed by zero or more sublist items.
It's good that Trix won't let me increase indent on a paragraph that doesn't fit its content model. But I need a stronger model for my docs...
Now a quote does allow multiple block content! What happens when I put a quote inside a list and then add sub-lists inside the quote? Madness:
I'd hope the continuous outer / non-continuous inner numbering is just styling bugs and not a crazy model?
P.S. A smaller usability issue: how do you make a numbered list with bullet sublist (or vice versa)? Enter->increase indent->switch to bullets works but Enter->switch to bullets leaves me with no option to increase indent. Unnecessarily confusing.
Anyway, lists are why I hate all WYSIWYG with passion as a user. I wish WYSIWYM with explicitly visible structure (cf. TeXmacs) was more popular.
This is a very astute observation. When I was developing Gate One I experimented with something similar for terminals (using contenteditable to work around issues with keeping elements up-to-date while retaining formatting) but ultimately ran into severe performance problems. That was years ago though and browsers have gotten much better at handling contenteditable with larger amounts of text.
However, the more tags you add to contenteditable elements (i.e. for formatting) the more work the browser has to do every time there's a page reflow and there will be a reflow every time the text changes. So the more formatting, the slower (less responsive) it will be.
The workaround for this (no idea if it's used in this editor) is to divide the document up into lots of individual <div> elements with contenteditable=true and make sure that all outside-the-view elements are removed or at least hidden via 'display: none' and merely re-show them on-the-fly as the user moves about the page. Keeping a page or two above and below the view pre-rendered can help with responsiveness and you'd also have to make sure to pre-fill all the document's unseen space with whitespace so that the user can scroll to any position accurately even if the browser is still retrieving and rendering that portion of the document.
I came very close to implementing such a solution but ultimately decided on something else entirely (server-side rendering and a difference-based terminal update protocol). It's a great idea for an editor and tows the line of, "what we're supposed to be doing" on the web but ultimately it requires a lot of complicated code. Far more complicated that one would think at first glance.
quick experiment: after copying the original text 200 times into the text box it starts to be unbearable to write any new text. However, if one just inserts 200k characters with no formatting, the editor doesn't seem to slow down.
This looks interesting especially the part about "Trix sidesteps these inconsistencies by treating contenteditable as an I/O device". We recently started using froala (https://www.froala.com/wysiwyg-editor/v2.0) and are really happy with it so far.
Has anyone tried to embed Trix into React?
How all this custom tags and polyfills will behave inside react component tree (even though shouldComponentUpdate will always return false)?
It's also open source. The developers (Basecamp) are obviously deeply invested in the Ruby stack.
If you want to install it with NPM, you could a create pull request with a package.json file and some helpful information for the authors about how to submit to the NPM registry, no?
This is the point of open source software you realise - that you can not just use the software, but that you can help improve it for yourself and others.
Going from the README, the main difference is the architecture.
It creates a layer of indirection between user actions and the DOM. This has two advantages:
* For developers of Trix itself, it eases the pain of cross-browser development - as the README says, contenteditable is inconsistent across browsers.
* For developers using Trix, you get a clean API (Trix.editor) so you can edit the document programmatically without your own cross-browser development.
* Pressing the <tab> key doesn't insert a tab as I would expect. I'm using Firefox latest on Win8
* The * character doesn't turn into a bulleted list item as I would expect. This is probably more of a nice to have for people use to that behavior in MS Word.
It reminds me of Prosemirror: "By strictly separating its document data structure from the browser's DOM, ProseMirror sidesteps most of the mess that is contentEditable, and ensures that the document stays entirely under the control of the editor." http://prosemirror.net/
Last time I saw Basecamp (then 37signals) working on a rich text editor is a long time ago. What happened to WysiHat? I know it had another developer than the two guys who made Trix.
What I especially liked about WysiHat was the complete bareness of the toolbar, just plain HTMl links. Is that also possible with Trix?
I was involved with the Wysihat project too. What we found is that its approach, like most other editors', is fundamentally broken. We created Trix to solve the problem. https://github.com/basecamp/trix#different-by-design
I think you'll find Trix's toolbar easy to style however you'd like, but if not, it ought to be straightforward to implement your own using the API.
Yes, they are all terrible. I don't know if this will be any better. They all highlight how bad the web is as an environment to host applications. A rich text editor - something that is a trivial toy project in any other application development environment - is impossible to build on the web in 2015.
Yes, almost all of them have major issues. It's really hard to get something that works with all the main text use cases but can also support images and some basic layout features (like drag/drop, move stuff around, etc).
have fun with that on mobile where like all browsers, javascript is single threaded
the reason why we use contenteditable is that it can be done in 15kb and the browser can do it natively, then you just clean up the resulting code on the backend
[+] [-] nmjenkins|10 years ago|reply
Looking through the code, a few things jumped out that should be looked at:
* Native TreeWalker implementations are buggy in some browsers. In the end we decided it was safer to just implement the bit we needed ourselves (see comment at top of https://github.com/neilj/Squire/blob/master/source/TreeWalke...).
* The HTML sanitisation using document.implementation doesn't account for DOM clobbering so is currently bypassable with the right malicious content. I recommend using https://github.com/cure53/DOMPurify for this rather than writing your own. It's tricky to get all the edge cases right, so better to use something that's been reviewed by several people (and in DOMPurify's case also undergone a formal security review). Again, we use this at FastMail as part of our webmail.
[+] [-] danso|10 years ago|reply
> Trix is an open-source project from Basecamp, the creators of Ruby on Rails. Millions of people trust their text to Basecamp, and we built Trix to give them the best possible editing experience. See Trix in action in the all-new Basecamp 3.
Nothing gets me more interested in trying out a JavaScript library than seeing that it's used in a mainstream production product, especially a money-making/critical product by very same the company that created/maintains it...it's a bit of guarantee that the API is relatively mature/won't-go-crazy and that someone has a vested interest in keeping the library up to date with changes in the Web. That was why React was so much more appealing to me than Angular, relative to their respective public release dates...React was already in production at Instagram and parts of Facebook, whereas I don't think Angular was in any of Google's main public facing products (i.e. search, YouTube, Maps)
[+] [-] kacperpotega|10 years ago|reply
Edit: Nevermind, just saw the edit on the comment below :)
[+] [-] impactmass|10 years ago|reply
[+] [-] manigandham|10 years ago|reply
Trix - https://github.com/basecamp/trix - demo here: http://trix-editor.org/ by basecamp and used in v3, handles files/images well
Squire - https://github.com/neilj/Squire - used in FastMail webmail, better for text than images
ProseMirror - http://prosemirror.net/ - not great with images
Scribe - https://github.com/guardian/scribe - by the Guardian team
CKEditor - http://ckeditor.com/ - solid and very customizable, lots of plugins, a little dated in look/feel
Quill - http://quilljs.com/
Summernote - http://summernote.org/
wysihtml - http://wysihtml.com/
Etherpad - http://etherpad.org/ - collaborative realtime editing
TinyMCE - http://www.tinymce.com/ - older editor but still good
Textbox.IO - https://textbox.io/ - new from the owners of tinymce project
Froala - https://www.froala.com/wysiwyg-editor - solid editor, newer features like drag/drop images, v2 RC3 just released
Redactor - http://imperavi.com/redactor/ - we used this in production but quality has gone down, v2 is half the functionality at 3x the price, not recommended anymore
[+] [-] espadrine|10 years ago|reply
- Typing "- " at the start of a line creates an unordered list, and typing "1. " creates an ordered list.
- Typing the '"' character correctly replaces it with the right unicode character, and you can undo that replacement by hitting backspace. The same goes with "--".
- It hints at automatic emoji insertion here: http://prosemirror.net/demo_dino.html
- Surprisingly, the keyboard shortcuts are often inconsistent across editors; ProseMirror tends to rely on widely-used shortcuts.
That said, as I mention here[0], I am most hopeful for Slack's text editor, which supports many more enhanced features -- but unfortunately doesn't seem open-source, and is currently quite buggy.
[0]: http://espadrine.tumblr.com/post/129926358821/web-editors
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] sleepyhead|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] stephentmcm|10 years ago|reply
[+] [-] VeejayRampay|10 years ago|reply
[+] [-] cben|10 years ago|reply
This makes it a nightmare to continue the list afterwards, because actually I've already closed it. Surprisingly, while many WYSIWYG editors are only ready to start a new "1. " list, they do allow me to paste the compound item into the middle of an existing list without interrupting its numbering. Sometimes there are other rituals involving liberal consumption of Shift+Enter and Backspace, dancing with text, and promising my firstborn to be contentEditable...
Anyway Trix fails it on the simpler task of multiple paragraphs in a list item. I haven't looked at the code but it seems its content model (at least strictly enforced) for list items is something like:
- a single block element (can be a quote or code) - followed by zero or more sublist items.
It's good that Trix won't let me increase indent on a paragraph that doesn't fit its content model. But I need a stronger model for my docs...
Now a quote does allow multiple block content! What happens when I put a quote inside a list and then add sub-lists inside the quote? Madness:
I'd hope the continuous outer / non-continuous inner numbering is just styling bugs and not a crazy model?P.S. A smaller usability issue: how do you make a numbered list with bullet sublist (or vice versa)? Enter->increase indent->switch to bullets works but Enter->switch to bullets leaves me with no option to increase indent. Unnecessarily confusing.
Anyway, lists are why I hate all WYSIWYG with passion as a user. I wish WYSIWYM with explicitly visible structure (cf. TeXmacs) was more popular.
[+] [-] ipsum2|10 years ago|reply
http://jsbin.com/cazewaxoje/1
[+] [-] amelius|10 years ago|reply
[+] [-] riskable|10 years ago|reply
However, the more tags you add to contenteditable elements (i.e. for formatting) the more work the browser has to do every time there's a page reflow and there will be a reflow every time the text changes. So the more formatting, the slower (less responsive) it will be.
The workaround for this (no idea if it's used in this editor) is to divide the document up into lots of individual <div> elements with contenteditable=true and make sure that all outside-the-view elements are removed or at least hidden via 'display: none' and merely re-show them on-the-fly as the user moves about the page. Keeping a page or two above and below the view pre-rendered can help with responsiveness and you'd also have to make sure to pre-fill all the document's unseen space with whitespace so that the user can scroll to any position accurately even if the browser is still retrieving and rendering that portion of the document.
I came very close to implementing such a solution but ultimately decided on something else entirely (server-side rendering and a difference-based terminal update protocol). It's a great idea for an editor and tows the line of, "what we're supposed to be doing" on the web but ultimately it requires a lot of complicated code. Far more complicated that one would think at first glance.
[+] [-] qute|10 years ago|reply
[+] [-] ayushgta|10 years ago|reply
[+] [-] tmikaeld|10 years ago|reply
[+] [-] m0dest|10 years ago|reply
[+] [-] braindead_in|10 years ago|reply
[+] [-] ipsum2|10 years ago|reply
[+] [-] morokhovets|10 years ago|reply
There is https://github.com/souporserious/react-trix but it looks like it does nothing at the moment.
[+] [-] picardo|10 years ago|reply
Edit: yes, it's not a Ruby gem. I stand corrected.
[+] [-] stephenr|10 years ago|reply
If you want to install it with NPM, you could a create pull request with a package.json file and some helpful information for the authors about how to submit to the NPM registry, no?
This is the point of open source software you realise - that you can not just use the software, but that you can help improve it for yourself and others.
[+] [-] sstephenson|10 years ago|reply
[+] [-] unknown|10 years ago|reply
[deleted]
[+] [-] lemevi|10 years ago|reply
It's not JavaScript, Trix is written in CoffeScript.
[+] [-] pbreit|10 years ago|reply
[+] [-] smileysteve|10 years ago|reply
[+] [-] mmahemoff|10 years ago|reply
It creates a layer of indirection between user actions and the DOM. This has two advantages:
* For developers of Trix itself, it eases the pain of cross-browser development - as the README says, contenteditable is inconsistent across browsers.
* For developers using Trix, you get a clean API (Trix.editor) so you can edit the document programmatically without your own cross-browser development.
[+] [-] timdavila|10 years ago|reply
* Pressing the <tab> key doesn't insert a tab as I would expect. I'm using Firefox latest on Win8
* The * character doesn't turn into a bulleted list item as I would expect. This is probably more of a nice to have for people use to that behavior in MS Word.
[+] [-] fokinsean|10 years ago|reply
[+] [-] saint-loup|10 years ago|reply
[+] [-] rambambam|10 years ago|reply
[+] [-] sstephenson|10 years ago|reply
I think you'll find Trix's toolbar easy to style however you'd like, but if not, it ought to be straightforward to implement your own using the API.
[+] [-] akulbe|10 years ago|reply
It seems very common to me, over the last several years, to see $NEW_SHINY_EDITOR, and I wonder why.
Are the alternatives that bad? Or is it just a matter of another dev wanting to scratch their own itch?
[+] [-] jacobsenscott|10 years ago|reply
[+] [-] stephenr|10 years ago|reply
[+] [-] manigandham|10 years ago|reply
Yes, almost all of them have major issues. It's really hard to get something that works with all the main text use cases but can also support images and some basic layout features (like drag/drop, move stuff around, etc).
[+] [-] drikerf|10 years ago|reply
[+] [-] ck2|10 years ago|reply
have fun with that on mobile where like all browsers, javascript is single threaded
the reason why we use contenteditable is that it can be done in 15kb and the browser can do it natively, then you just clean up the resulting code on the backend
[+] [-] cookiecaper|10 years ago|reply
[+] [-] nimitkalra|10 years ago|reply