2

I want my editors to be able to use keyboard shortcuts for applying headings.

I've been experimenting with the "keystrokes" approach on the ckeditor site. It works for some things, but not the headings. For instance, the following applies an additional mapping for 'bold' using Ctrl + Shift + u:

config.keystrokes = [
    [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 85 /*U*/, 'bold' ],
];

Why can't I enable the headings?

Right now this is what my config.js looks like:

CKEDITOR.editorConfig = function( config ) {
    // Define changes to default configuration here.
    // For complete reference see:
    // http://docs.ckeditor.com/#!/api/CKEDITOR.config

    // The toolbar groups arrangement, optimized for two toolbar rows.
    config.toolbarGroups = [
        { name: 'styles', groups: [ 'styles' ] },
        { name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
        { name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] },
        { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
        { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },
        { name: 'document',    groups: [ 'mode', 'document', 'doctools' ] },
        { name: 'others' },
        { name: 'forms' },
        { name: 'tools' }
    ];

    // Remove some buttons provided by the standard plugins, which are
    // not needed in the Standard(s) toolbar.
    config.removeButtons = 'Underline,Styles,Strike,Image,Outdent,Indent,Blockquote,Cut,Copy,Paste,PasteFromWord,Undo,Redo';

    // Set the most common block elements.
    config.format_tags = 'p;h1;h2;h3;h4';

    // Simplify the dialog windows.
    config.removeDialogTabs = 'image:advanced;link:advanced';

    // Whether to escape basic HTML entities in the document, including: 
    // (nbsp,gt,lt,amp)
    config.basicEntities = false;
    config.entities_additional = 'lt,gt,amp,quot'
    config.entities_latin = false;
    config.entities_greek = false; 
    config.disableNativeSpellChecker = false;
    config.removePlugins = 'wsc,scayt';
    config.scayt_autoStartup = false;
    config.height = 1000;

    config.keystrokes =
        [    
            [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 85 /*U*/, 'bold' ],
            [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 73 /*I*/, 'h1' ],
        ];
};

I'm hoping to keep my changes restricted to the ckeditor directory (ideally only inside config.js).

Morteza Asadi
  • 1,819
  • 2
  • 22
  • 39
doub1ejack
  • 10,627
  • 20
  • 66
  • 125

2 Answers2

1

You have to create a new command in your HTML page for each of the headings you want to apply. For <h1>:

var editor1 = CKEDITOR.replace( 'editor1' );
editor1.on( 'instanceReady', function( evt ) {
    evt.editor.addCommand( 'h1' , new CKEDITOR.styleCommand( new CKEDITOR.style({ element: 'h1' } )) );
    // other commands for 'h2', 'h3' etc
    evt.editor.setKeystroke( CKEDITOR.CTRL + CKEDITOR.SHIFT + 85 /*U*/, 'h1');
    // other keystrokes for 'h2', 'h3', etc
});
Wizard
  • 2,961
  • 2
  • 13
  • 22
  • I'd prefer to keep this within the ckeditor directory if possible. Can this approach be used in the config.js file, or another existing ckeditor file? Or perhaps this needs to be a custom plugin? – doub1ejack Jul 06 '17 at 13:13
  • I really don't know if it can be done in config.js or in another file inside ckeditor folder, but it could be done as a custom plugin. – Wizard Jul 06 '17 at 13:19
0

There is surprisingly little documentation around the intricacies of ckeditor's keystrokes so I'm going to share some code that demonstrates two approaches to adding keyboard shortcuts.

The first approach can be done for some elements simply by editing the config.js file. The second uses a custom plugin.

ckeditor/config.js

CKEDITOR.editorConfig = function( config ) {

   [ ... ]

    /* This is the easy way to add keystrokes, but it only works for
     * default commands like bold, italic, link (shown here), etc.  
     * This is the approach recommended in the ckeditor docs.
     *
     * @see: http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.keystrokes
     */
    config.keystrokes = [ [ CKEDITOR.CTRL + 75 /*K*/, 'link' ] ];

    /* It's hard to get keyboard shortcuts for elements that don't have
     * default ckeditor commands - headings included.  I created
     * a simple plugin that lets me define additional shortcuts. The 
     * plugin needs to be declared as follows:
     */
    config.extraPlugins = 'customkeyboardshortcuts';
};

This is an extraordinarily simple plugin, so all it requires is:

  • being added to config.js as in the example above
  • a directory name that matches the plugin name (eg "customkeyboardshortcuts")
  • a js file named plugin.js with the following contents

ckeditor/plugins/customkeyboardshortcuts/plugin.js

CKEDITOR.plugins.add( 'customkeyboardshortcuts', {

    // The plugin initialization logic goes inside this method.
    init: function( editor ) {

        /* The heading formats do not have ckeditor commands associated with them
         * by default in ckeditor. We use a plugin to give them command names
         * in order to set the keystrokes below.
         *
         * (If the headings had command names by default then we wouldn't need a plugin
         * at all and could just take the "keystrokes" approach in config.js - see
         * http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.keystrokes)
         */
        editor.addCommand( 'h1' , new CKEDITOR.styleCommand( new CKEDITOR.style({ element: 'h1' } )) );
        editor.addCommand( 'h2' , new CKEDITOR.styleCommand( new CKEDITOR.style({ element: 'h2' } )) );
        editor.addCommand( 'h3' , new CKEDITOR.styleCommand( new CKEDITOR.style({ element: 'h3' } )) );

        /* Then we need to add a keystroke for the headings
         *
         * The hard part is finding a viable keyboard combination.  In my
         * tests I wasn't able to use any combination that included a number
         * (regardless of which modifier keys I choose). The letters 'H' (for
         * "heading") and 'F' (for "format") are reserved for OSX 'hide' and chrome
         * 'find' respectively. Also the function keys don't work on a mac, and the
         * 'fn' modifier key doesn't exist on a windows machine.
         *
         * I picked 'B' because h1 is _like_ bold, and gave h2 and h3 to 'V' and
         * 'C' respectively because it feels like a fairly natural progression to
         * me (even though it's kind of backwards).
         */
        editor.setKeystroke( CKEDITOR.SHIFT + CKEDITOR.CTRL + 66 /* B */, 'h1');
        editor.setKeystroke( CKEDITOR.SHIFT + CKEDITOR.CTRL + 86 /* V */, 'h2');
        editor.setKeystroke( CKEDITOR.SHIFT + CKEDITOR.CTRL + 67 /* C */, 'h3');

    }
});

And thanks to @Wizard for getting me onto the right track. As he mentioned in his post, you can add JS to the page that ckeditor is located on also. I didn't want to muck up our view files with ckeditor js inserts, so that didn't work for me, but it might work for you.

doub1ejack
  • 10,627
  • 20
  • 66
  • 125