And here, not even 24 hours later, one just falls into my lap.
You'll want to add "cursor: hand;" to your CSS when someone hovers over the styling buttons. Because right now, it default to the cursor point, which doesn't given a clue to the user that the styling buttons are clickable.
Edit: yes, it's not a Ruby gem. I stand corrected.
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.
Trix also supports "content attachments" (currently undocumented) which allow embedding arbitrary HTML as attachments in the document. Basecamp 3 uses this feature to embed @mentions with avatars, and various oEmbed types, in messages and comments.
What would be useful though, would be an editor that supported "design" and not just text.
Creating an editor for that does sound like a simple task, doesn't it? Except the tools the browser gives you just don't work, as we've experienced first-hand over the years in the form of customer bug reports.
That's why we built Trix.
About rich text editors, since there are so many editors (even native) that lag on input I have just assumed that is something that only I care about.
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.
We (the Guardian) created Scribe to tackle this:
https://github.com/guardian/scribe
(I can't take any credit personally though alas!)
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?
The readme explains how our approach is different from other WYSIWYG editors. (Most others are just toolbars that call execCommand.)
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).
This will be a pain to use.
My problem is that I don't want to use them. Unless they use markdown or another simple formatting language behind the scene, and allow you to switch to a simple `<textarea>` input, you can't avoid them.
I already have a text editor, I already have a way to generate "rich" text, I don't need another tool with another set of bindings, quirks, bugs and incompatibilities. Every editor has its own way to deal with very basic stuff: when writing a list what happens if you press return twice? Backspace on an empty element? Tab? You can't know beforehand.
I'm fine with giving tools to non-technical users, but there should be a way to disable such editors completely so it can adapt to any workflow.
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.
Probably the hardest thing to do is handle copying and pasting, partly because most browsers give you very little control over this, so you have to resort to terrible hacks. You also have to decide how much of the formatting in the clipboard item was "intentional" and how much should be cleaned. I see if you copy/paste just a word from within Trix, it pastes it as a whole block with the block's formatting around it. I suspect this may surprise many users who expect it just to copy the word (the inline bit, not the block around it in editor parlance). Once you start going down this rabbit hole, you end up having to do things like take one DOM tree and recursively merge the "edges" with the adjacent trees to get it to behave as the user expects. I think we do a pretty decent job with Squire, but I'm sure there are still more edge cases we haven't covered.
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
- 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
They've removed features like html code view (which is basic and needed since no editor is perfect), formatting for pasted-in text is worse (even from just another webpage), image handling is broken (cant resize or even move around anymore), and lots of stability bugs in general.
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:
1. foo
2. | bar
| baz (this was Enter, not Shift+Enter)
3. | 1. sublist
4. | 1. | ququux
| | multi-line/paragraph.
5. | 1. #code () {####
| ###...########
| 1. #}############
6. | WAT?
7. | * ulist...
8. | * | 1. | - he he
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.
P.S. Squire doesn't seem to allow block content inside lists. Only Shift+Enter linebreaks.
ProseMirror does allow block content (it defaults to markdown content model); continuing the numbered list after non-sublist items required the paste-into-existing-list dance.
Firepad does allow non-item content but doesn't align it like part of the list. It does tend to continue the numbering afterwards, not sure what are its exact rules.
None of this is IMHO satisfactory UX. I've observed many people struggle with lists in any WYSIWYG I've ever seen :-(
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.
They don't use contenteditable in the traditional way:
> Trix sidesteps these inconsistencies by treating contenteditable as an I/O device: when input makes its way to the editor, Trix converts that input into an editing operation on its internal document model, then re-renders that document back into the editor.
I find this a fine solution.
> 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)
Edit: Nevermind, just saw the edit on the comment below :)
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.
Did projects prior to being hosted on GitHub require a Code of Conduct or is that a new thing.
Also, sad that it's in Coffeescript.
* 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.
From the documentation:
> Eventually we expect all browsers to implement these standards. In the meantime, Trix includes polyfills for missing functionality.
Haven't seriously used any of those but I'd put my money on ProseMirror as the most principled one.
There is https://github.com/souporserious/react-trix but it looks like it does nothing at the moment.
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
On topic: Thanks, Basecamp. I like the minimalism and focus on function of this project. Contenteditable approaches to formatting text needed some love. I look forward to trying this out in my next project.