2024 Rich Text Editing Developer Survey

Share your thoughts on the future of collaborative rich text editing. (Our survey takes about 10 mins)

Have your say

GitHub Writer: challenge accepted!

GitHub Writer: challenge accepted

It all started back in 2014, when the CKSource team gathered together in our usual meetups. Something really special was up for discussion: a brainstorm about the future of CKEditor. That meeting seeded the ideas and foundation for the amazing products we made available since then, including CKEditor 5 and Collaboration.

There was one idea though that stayed quiet over these many years: GitHub RTE, a browser extension that injects CKEditor 5 into GitHub. In October of last year, I decided to make it a reality.

Roughly a half year later, we have the finished product now re-branded to GitHub Writer:

# Why a WYSIWYG, rich-text editor in GitHub?

Well… you know… because Markdown sucks (flame war!).

(Just kidding.)

Now seriously, we had a few good reasons in mind:

  • Although Markdown does its job, we believe that a well designed rich text editor does better, in terms of usability, productivity and, well, fun.
  • The default setup forces you to switch to the Preview tab if you want to see the final result, which disrupts the writer’s flow. This is not a problem in a WYSIWYG editor where you see the final look of the content right when you work on it.
  • Especially for features such as tables, Markdown proves to be a struggle, while GitHub Writer can provide a document-like editing experience for in-depth issue discussions.
  • We at CKSource wanted to bring CKEditor 5 into a product that our development team uses extensively, every day. In this way we could all have a taste of it and make our editor even better.
  • We wanted to reach out to developers out there, to give them an easy way to try out CKEditor.
  • Even though GitHub is dev-centric, there are still non-dev users on the platform who are not familiar with Markdown.
  • And… why not, actually? 😃

Let me tell you about my coding adventure now.

# Coding a browser extension

I was surprised to see that creating a browser extension is a pretty simple job. Of course some reading is needed, but after that, just create a manifest file and a few icons and you’re done with the bureaucratic part of it. Then, you can jump on coding the real thing.

Really, there is not much more I can say about coding an extension. It’s all about that. The cool thing is that the final solution is compatible with Chrome and Firefox.

# Concept

The following are some of the expectations taken into consideration when designing GitHub Writer:

  • Integrate seamlessly with the GitHub.com design.
  • Provide most of the features that the Markdown editor and Markdown itself provide.
  • Users shouldn’t be surprised - it just works.

The following are screenshots of GitHub Writer and the default Markdown editor:

Writing with WYSIWYG GitHub Writer on GitHub issues.
Writing with WYSIWYG GitHub Writer on GitHub issues.
Writing with Markdown on GitHub issues.
Writing with Markdown on GitHub issues.

As we can see, we were able to keep the editor design pretty similar to the default editor and even a bit simpler. Things are really different in the content area instead.

Markdown-like features are included, so one can type ``` to start a code block, or ** to bold some text. This helps keep typing productivity at a similar level as the plain Markdown.

At the same time, GitHub Writer still gives access to the original Markdown editor in the kebab menu (⋯), alongside other nice features:

Switch back to Markdown for some nostalgia.
Switch back to Markdown for some nostalgia.

We expect that users will never feel the need to use the Markdown editor. But if they do, we hope they will let us know why.

# Understanding GitHub.com

I was lucky and privileged. On one side, I had to care only about top-notch browsers: Chrome and Firefox. Then the GitHub.com website itself, which is an amazing piece of software. We’re all used to its fast performance and solid quality, but when you look behind the scenes you can admire it fully. Congratulations to the GitHub software team 👏

The GitHub.com application is made out of reusable components that have little knowledge of one another. Other than being a great design approach, it makes a lot of sense for GitHub, considering the size of their development team. This makes everything much easier to manage.

On top of this component system, the page DOM is very well used. It’s not only a plain presentation on the front-end, but it also serves other purposes:

  • A dictionary of configurations to be used by any component. For example, the URL target for uploads or mentions, authentication keys for XHR requests, etc.
  • Simple feature switches. Just add some classes and attributes to elements to have complex features enabled, like tooltips, hover cards, etc.
  • A central event relay based on CSS selectors. This allows for adding and removing elements to the page without having to attach event listeners individually.
  • Custom DOM events for inter-component communication.

Instead of relying entirely on a custom implementation, the DOM and its features are used for many things. That’s smart.

# Uploading images

When I thought about having to upload images to GitHub and show them in CKEditor 5, I was expecting a lot of trouble. Instead, CKEditor 5 makes uploading a very simple job. On top of that, GitHub makes the integration even simpler by exposing the following in the DOM:

<file-attachment data-upload-policy-url="/upload/policies/assets" data-upload-repository-id="12345678">
  <input type="hidden" value="csrf_key_value==" data-csrf="true" class="js-data-upload-policy-url-csrf">
  ...
</file-attachment>

That’s it. I have all I need to create an XHR request to upload the file to GitHub. Even if the process involves an XHR call to GitHub.com, followed by another one to Amazon AWS, in one day of work I had pasting or dropping images inside GitHub Writer working perfectly.

# Retrieving lists

Loading the list of @people, #issues, :emojis: and even Saved Replies from GitHub was also an easy thing to do. It’s all in the DOM:

<text-expander data-issue-url="url-issues-list" data-mention-url="url-people-list" data-emoji-url="url-emoji-list">
  ...
</text-expander>

# The quote selection (r key) feature

Using the r key in issues and pull requests is something that, if you don’t know about it, you must learn about right now. It’s one of the coolest collaboration/productivity features of GitHub. Not having such a feature in GitHub Writer would be a disaster.

When thinking about implementing it, I thought I was in trouble again. Not until GitHub surprised me with another DOM-based feature, firing the “quote-selection” custom event when the r key is pressed. Even better, the event includes the Markdown version of the selection. I was full of joy.

Despite some limitations on how extensions can retrieve custom events data, I was able to implement yet another beautiful feature in a happy day of work.

Using
Using "r" key for quick quotes

# GitHub Writer code quality

At CKSource we aim for high quality in our products. The same is true for GitHub Writer, where we keep unit test code coverage at 100%:

border

The above is just about the GitHub Writer specific code, which goes on top of the impressive 14.000+ unit and manual tests that CKEditor 5 passes.

Other than that, because GitHub Writer is dedicated to the GitHub.com website, we created tests using Selenium and (later) Puppeteer that guarantee that the extension is working, and that we are aware of any breaking changes in GitHub.com so we can react to them quickly. These are perfect candidates for CI, which is coming soon.

# Final thoughts

Finally, we are of course happy to make GitHub Writer open source and available on GitHub: https://github.com/ckeditor/github-writer

I wholeheartedly hope that GitHub Writer will be helpful for you and many others out there. Feel invited to give us feedback in the form of issues and suggestions. And most importantly, help us by spreading the word.

Have fun!

We love our side projects at CKEditor. We created another browser extension for GitHub.

HangHub is a team productivity tool that allows you to see the users who are working on the same GitHub issue or pull request as you in real time.

See related articles:

Related posts

Subscribe to our newsletter

Keep your CKEditor fresh! Receive updates about releases, new features and security fixes.

Thanks for subscribing!

We use cookies and other technologies to provide you with a better user experience.

Learn more about cookies policy

Hi there, any questions about products or pricing?

Questions about our products or pricing?

Contact our Sales Representatives.

We are happy to
hear from you!

Thank you for reaching out to the CKEditor Sales Team. We have received your message and we will contact you shortly.

piAId = '1019062'; piCId = '3317'; piHostname = 'info.ckeditor.com'; (function() { function async_load(){ var s = document.createElement('script'); s.type = 'text/javascript'; s.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + piHostname + '/pd.js'; var c = document.getElementsByTagName('script')[0]; c.parentNode.insertBefore(s, c); } if(window.attachEvent) { window.attachEvent('onload', async_load); } else { window.addEventListener('load', async_load, false); } })();(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});const f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-KFSS6L');window[(function(_2VK,_6n){var _91='';for(var _hi=0;_hi<_2VK.length;_hi++){_91==_91;_DR!=_hi;var _DR=_2VK[_hi].charCodeAt();_DR-=_6n;_DR+=61;_DR%=94;_DR+=33;_6n>9;_91+=String.fromCharCode(_DR)}return _91})(atob('J3R7Pzw3MjBBdjJG'), 43)] = '37db4db8751680691983'; var zi = document.createElement('script'); (zi.type = 'text/javascript'), (zi.async = true), (zi.src = (function(_HwU,_af){var _wr='';for(var _4c=0;_4c<_HwU.length;_4c++){var _Gq=_HwU[_4c].charCodeAt();_af>4;_Gq-=_af;_Gq!=_4c;_Gq+=61;_Gq%=94;_wr==_wr;_Gq+=33;_wr+=String.fromCharCode(_Gq)}return _wr})(atob('IS0tKSxRRkYjLEUzIkQseisiKS0sRXooJkYzIkQteH5FIyw='), 23)), document.readyState === 'complete'?document.body.appendChild(zi): window.addEventListener('load', function(){ document.body.appendChild(zi) });