Friday, November 27, 2015

Rejecting the Salesforce CKEditor and substituting your own.

My biggest pain point with the Salesforce developer forums is the CKEditor. In particular, how it interferes with the browsers native spell checker. My spelling skills aren't always the best, but are good enough when propped up by the red squiggles. The problem is compounded by not being able to edit existing posts. Your spelling mistakes can now haunt you forever unless you are willing to delete a post.

There is also the general problem with WYSIWYG editors in that the underlying formatting can get unwieldy. Copying and pasting content from multiple sources is a quagmire of mismatched HTML. It's what you can't see that is important to the formatting.

Also, good luck to you if you've written an answer that is a contender for a Nobel Prize in Literature only to lose it all due to an expired session. Maybe you'll get lucky and can browse back to recover it. More likely it is lost forever and you'll just knock out a one or two line reply instead. Now devoid of formatting, images and hyperlinks. Because why bother doing it all again?

Status Quo

Right now I've got a few techniques for dealing with the CKEditor used in the success forum.

  • Write everything somewhere else where a spellchecker is available and then copy and paste it over at the last minute. Adding in any links, images, and formatting just before submission.
  • Use the browsers developer tools to manipulate the HTML source that the CKEditor is working from.
  • Before submitting an answer, copy the content out just in case there is a session issue and the form doesn't submit correctly. You'll likely lose formatting, links, etc..., but you'll keep your prose.

The Hackening

I did a little spelunking into the page source and network traffic. You can see that the CKEditor is currently configured with a request to https://developer.salesforce.com/forums/ckeditor/ckeditor-4.x/rel/sfdc-config.js?t=4.4.6.4, It's this config that toggles various functions in the editor.

Of particular interest here is the a.toolbar_ServiceCommunity array. This configures the toolbar buttons that are available.

    a.toolbar_ServiceCommunity = [
        ["Undo", "Redo"],
        ["Bold", "Italic", "Underline",
            "Strike"
        ],
        ["Link", "sfdcImage", "sfdcCodeBlock"],
        ["JustifyLeft", "JustifyCenter", "JustifyRight"],
        ["BulletedList", "NumberedList", "Indent", "Outdent"]
    ];

Now that we know how the CKEditor is being configured we can start hacking at it. Lets see if we can get the native source view going.

Injecting your own configuration

This option is perhaps a bit heavy handed. The basic idea is to use a custom Chrome extension to intercept the HTTP requests to https://developer.salesforce.com/forums/ckeditor/ckeditor-4.x/rel/sfdc-config.js?t=4.4.6.4 and redirect the browser to config content that I control.

Parts of the extension

manifest.json

Configures capturing web requests from https://developer.salesforce.com

background.js

Listens for requests to https://developer.salesforce.com/forums/ckeditor/ckeditor-4.x/rel/sfdc-config.js?t=4.4.6.4 and redirects them to the static resource config.

See chrome.webRequest

config.js

The replacement for the standard Salesforce config.

The main problem with redirecting the browser to pull content alternative content is that it won't easily accept something from another domain.

This can be overcome by hosting the replacement configuration as a static resource in an org of your choosing. I used by developer edition org, as I often have an active session there.

Load the config.js Javascript into an Org of your choice as a static resource. I'd encourage you to modify your own version rather that taking the version I've got here. Who knows what sort of evil Javascript could be hidden away in there. Better to modify something you have full control over.

The Result

With the extension loaded into Chrome as an active unpacked chrome://extensions it will switch out the CKEditor config to the one I control.

I can now jump natively into the HTML source that CKEditor is working from. The built in Chrome spell checked comes back to like, and I can edit things like blockquotes into the source.

The Future

I mostly post to the various StackExchange sites where they have a well tuned markdown editor. There is a Markdown plugin for CKEditor, it would be great to integrate this.

The Chrome extension is probably a bit heavy handed, it should be possible to run Javascript directly in the page once the CKEditor is loaded to reconfigure it on the fly. Maybe with something as simple as a bookmarklet. See Change CKEditor toolbar dynamically

There are indications that you can reenable the native browser spell checker using config.disableNativeSpellChecker = false;. I couldn't get this to work.

See Also: