execCommand() is now obsolete, what's the alternative?

JavascriptHtmlCssExeccommand

Javascript Problem Overview


I intended to use Document.execCommand() method along with contenteditable attribute to build my custom WYSIWYG editor. But when I checked the documentation for Document.execCommand(), I found that it's now obsolete. What's the modern (or extant) alternative for it?

Javascript Solutions


Solution 1 - Javascript

I created the Rich Editor for my platform's XML (HTML5 + XHTML) editing purposes. I would not say that document.execCommand() is completely dead because some parts of it still work fine. Unfortunately the primary issue for me was that browsers use a lot of different code to generate those styles which are not recognized by screen readers used by those who are blind or nearly so.

Additionally the most expensive time bug I ever had to conquer was a Gecko/Presto bug where the visual and technical selections (why they aren't the same thing, don't ask me) would result in part of the DOM being changed that the user did not intend and this would come down to the fact that the pixel count per character is low so if the Rich Editor did not honor visual selections a user would very quickly walk away. That required four months to conquer and there are other bugs too.

Ultimately it's a harsh though achievable endeavor though if you intend to build an HTML/XML editor like I did you should plan for at least six months if you plan to not only do it properly though test it to the point of hating cake to then only have someone come along and point out yet another bug.

Your primary focus JavaScript wise should be on the following:

In place of inconsistent code generated by using execCommand() from different browsers (often setting inline styling which would complicate your site's CSS if not outright negating it) you should stick to using the following elements which you not only can have control over though are compatible with screen readers:

  • em for emphasis (or "italics", <i> is deprecated).
  • strong for strongly read text (or "bold", <b> is deprecated).
  • u for underline (be sure your anchors are styled to differentiate from u elements; u might be considered "deprecated" though I will reverse this when I fix the standards in the next ten years or so, use it appropriately).
  • sub for sub-line text that appears vertically lower than normal text.
  • sup for supper-line text that appears vertically higher than normal text.
  • Do not use the <span> element to specifically add these styles as screen readers will not understand or reveal buggy behavior; it is still a valid generic inline element when used appropriately.

I actually have been intending to revise my Rich Editor (it's been getting patched though not yet properly rewritten) though you're welcome to look at the source code when it loads on a blog page in the site linked in my profile. The original project took me 11 months though with my experience now I think it would take me about three to four. If you're serious I highly recommend staying the hell away from frameworks and libraries. "But ... but, they make life easier!" ... until you want to use a new version and have to rewrite the entire project. Use pure JavaScript the first time and negate pointless maintenance. Good luck!


2021-09-24: I ended up resuming work on the Rich Editor II from roughly a year ago and managed to convert the code that changed styles from 100,515 characters to ~6,000 and reduce the file request (effective bandwidth after compression) by a full third. Here are the key parts to that success:

  1. The anchorNode and focusNode can switch depending on if you select left-to-right or right-to-left. Because I couldn't find any justification of why that would matter (for my platform) I made the an object (for anchorNode) on the left and the fn object (for focusNode) always on the right side.

  2. I resolved the Gecko/Presto issue using ~1,700 characters; you can find it on the site (visit a page that has a Rich form) first.

  3. To resolve the issue of selecting through numerous interchanges by <s>, <sub>, <sup>, <u> etc (you must test both simple and wildly convoluted examples) I ended up using window.getSelection().getRangeAt(0).commonAncestorContainer with cloneNode and then before processing that stripped what wasn't included in the selection. Then I simply used window.getSelection().deleteFromDocument(); to remove the selection and replace it with the new style element via document.createElement that I could easily appendChild the selection to and insert it at window.getSelection().getRangeAt(0).insertNode(id_('editor_rich_text').firstChild);.

Gecko browsers such as Waterfox, Pale Moon and the now utterly destroyed Firefox allow you to select multiple instances of text. To do so simply hold the Control key to create extra selections. Since it doesn't really help in any meaningful way (and this stuff is already convoluted enough as it is) I didn't go out of my way to support it at this time.

I'll be updating my platform either today or this weekend (as of this post edit) to reflect the new changes. I am keeping a lot of the older code due to numerous issues with Gecko browsers. I have expanded upon the functionality and resolved numerous bugs and did not have to resort to any hacks and as usual no garage (frameworks or libraries).


2021-09-26: For those interested in redo/undo functionality you'll have to resort to basically keeping text versions of the part of the DOM that you're editing. Sure, there could be other ways to implement it though those would be wildly convoluted. You basically just make a copy of the editor parent element using .cloneNode and then while it's in memory use something along the lines of while (e.firstChild) {xml += new XMLSerializer().serializeToString(e.firstChild);}. Since you'll be storing it as text it won't have the huge memory implications that the DOM has. You will literally be replacing the entire DOM in the editor as well as tracking every iteration of a change so it'll still be a hefty project. For my platform it's not necessary right now though I wanted to cover this as some people have mentioned it in the comments.

Solution 2 - Javascript

Year 2022 answer: The execCommand() is officially obsolete/deprecated but there's no alternative. So if you must have rich text support, you have to keep using execCommand() and figure out yourself what actually works with browsers that you want to support.

Note that real world user agents (browsers such as Chrome, Firefox and Safari) cannot drop support for execCommand() because so many services require support for it. The sad state of things is that HTML5 cannot specify any common ground here because browser vendors do not agree how execCommand() should work. So nothing can be specified for HTML5, which has the overall objective to specify all stuff – and only stuff – that's needed for full interoperability for any new browser to enter market. However, in my opinion HTML5 fails here because execCommand() compatibility is actually required for any new browser to enter market, so it would make sense to standardize at least one of the browser specific implementations as the official one.

All the current standarization efforts (Input Events 2, Clipboard API) fail to even try to cover the features that execCommand() actually does (for example, undo/redo, actually changing content within the selection range).

This situation has already been going for over five years so don't expect any rapid changes either.

Solution 3 - Javascript

Looks like the alternative will be Input Events Level 2.

While it is very tempting to create a self-made WYSIWYG editor, I personally will stick with execCommand until the new standard arrives. Because we all will just program a whole editor by ourselves, instead of reusing present working solutions.

Solution 4 - Javascript

The alternative to document.execCommand() is Clipboard API, via navigator.clipboard. Per MDN Web Docs (https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API):

> This API is designed to supersede accessing the clipboard using document.execCommand().

EDIT: As mentioned in the comment as well as the quoted text above, this only fulfills a subset of the requirements (clipboard access).

Solution 5 - Javascript

The reference documentation says it as warning.

> It is predicted that in the future both specs will be replaced by > Content Editable and Input Events.

And as every prediction, just wait to be sure.

Solution 6 - Javascript

you can use the

navigator.clipboard.writeText(text to be copied);

which does the exact same thing as document document.execCommand("copy");, Hope you find this helpful!

Solution 7 - Javascript

The conclusion here is that even though the w3C has a warning concerning execCommand(), it is still working and no standard alternative for it yet even now in 2022 unless one results in using javascript edition libraries.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOmarView Question on Stackoverflow
Solution 1 - JavascriptJohnView Answer on Stackoverflow
Solution 2 - JavascriptMikko RantalainenView Answer on Stackoverflow
Solution 3 - JavascriptMartin MeeserView Answer on Stackoverflow
Solution 4 - JavascriptSal_Vader_808View Answer on Stackoverflow
Solution 5 - JavascriptgerardnicoView Answer on Stackoverflow
Solution 6 - JavascriptAhmad EbrahimView Answer on Stackoverflow
Solution 7 - JavascriptAbdulsalamView Answer on Stackoverflow