Skip to content

Instantly share code, notes, and snippets.

@JeanOsorio
Last active August 1, 2022 15:35
Show Gist options
  • Save JeanOsorio/eb6dfd300acce98db28d183d79529c44 to your computer and use it in GitHub Desktop.
Save JeanOsorio/eb6dfd300acce98db28d183d79529c44 to your computer and use it in GitHub Desktop.
How to Create a WYSIWYG

How to crate a WYSIWYG

What is a WYSIWYG

The WYSIWYG or What You See Is What You Get is a text editor that allows a user to type and immediately watch the text resulting in styled like bold, italic, underline or strikethrough fonts, as you can imagine the main functionality of the WYSIWYG is to ease the creation of rich text; is commonly used in blogs text editor or the creation of documents like google docs.

Most use WYSIWYG libraries

At the time of the writing of this entry the most popular WYSIWYG libraries are:

CKEditor

Tiny or TinyMCE

Editor.js

Theses three library offer a basic and open source editor, but in the case of tinyMCE and CKEditor they offer some extra options for a price.

Why create our own WYSIWYG component?

Most of the time our users are going to use only the basic functionality like bold, italic and underline text; and although the libraries mentioned before has these basic functionality, we are going to depend on a third party, so there is always an extra work to add some other functionalities or desing it order to make those WYSIWIG editors look and feel like our own.

Also those library have a very basic functionality without the monthly payment, so if we decide to create our own component we are going to get the freedom to give this component the right or need funcionalities, look and feel and anything we need to make it work in our user workflow.

How write a WYSIWYG componente?

For the following information, we are assuming the development of the WYSIWYG component would be a component created using React

Considerations

There are so many use cases that involved the creation of the WYSIWYG component and I would not try to address all at this initial proposal.

  1. The most common way use in the creation of a WYSIWYG component is using the execCommand API offered by the browser, but this API was deprecated and is not recommended anymore as you can see in the following link
  2. Are we considering the autosave functionality? If the answer is yes, we have two possible path to accomplish this. Create a buffer (using something like a weakMap) with the information typed and formatted by the user or create a debouncing function that delayed the call to the server and avoids saving the user content after every key pressed.
  3. Are we are going to consider simultaneous editing? If the answer is yes, we need to introduce a socket functionality to our backend in order to allow two or many other users working at the same time in the same document or text.
  4. Are we are going to consider the code visualization functionality? If we want to allow our user to change between preview mode and code we need to implement another component (a textarea component) that will show the content as raw code.
  5. Are we consider the attached image functionality? For this, we are going to need an artifact that allows the user to upload their image to a repository like a bucket in a cloud and get the URL of the uploaded file in order to append the image to the text.
  6. We are dealing with HTML tags, so we have to use the dangerouslySetInnerHTML in order to repaint the content a user wrote and wants to edit later in the future.

Diagram

the following image is a representation of a WYSIWYG component (based on the TinyMCE editor) wysiwyg components

Based on the atomic design methodology we can list the components we are going to need for the creation of our WYSIWYG component as follow:

Atom:

  • Button (color red)
  • Icon
  • Select (color yellow)
  • Writing area (color green)
  • Textarea (optional)

Molecules:

  • Toolbar (using the atom components like buttons and selects)

Organisms:

  • WYSIWYG (component using the union of the atoms and molecules)

Version with execCommand

Although the execCommand has been declared deprecated as you can see here and here, this API is still supported by all browsers as you can see in the following link but as the documentation suggests, there is still not an alternative API to the execCommand, and with the whole process and different faces that a new implementation has to face by the TC39 we as a developer have a long wait before use anything different to the execCommand.

Basically, our writing area component should have the property contenteditable=true and this allows the component to write directly to him; on the other hand, our toolbar button components should invoke the execCommand method using the corresponding parameter as we can see here this would apply the proper decoration to our text link bold, italic, change font type or size, etc.

From then we need to use the outer HTML to save the content in our database as a string, then then re-render this string as HTML content using dangerouslySetInnerHTML as you can see in the following example

With all this (and a little extra work) we have a complete functional WYSIWYG using the execCommand API.

Version without execCommand

In the hypothetical scenario where the execCommand does not exist, we can use the Selection API, but as you can imagine this would require a lot of extra work because, unlike the execCommand, we can not specify what action should the browser apply to the selection, we need to wrap the selection with the correspondent HTML tag like <b></b> for bold, <i></i> for italic, <u></u> and for other styles like color o change fonts we need to create the styled using CSS and then apply to the selected text using a div or span tag depending on the case. I found this example of someone implemente a WYSIWYG using the Selection API.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment