      1 ﻿/*
      2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
      3 For licensing, see LICENSE.html or http://ckeditor.com/license
      4 */
      5
      6 // Register a plugin named "sample".
      7 CKEDITOR.plugins.add( 'keystrokes',
      8 {
      9 	beforeInit : function( editor )
     10 	{
     11 		/**
     12 		 * Controls keystrokes typing in this editor instance.
     13 		 * @name CKEDITOR.editor.prototype.keystrokeHandler
     14 		 * @type CKEDITOR.keystrokeHandler
     15 		 * @example
     16 		 */
     17 		editor.keystrokeHandler = new CKEDITOR.keystrokeHandler( editor );
     18
     19 		editor.specialKeys = {};
     20 	},
     21
     22 	init : function( editor )
     23 	{
     24 		var keystrokesConfig	= editor.config.keystrokes,
     25 			blockedConfig		= editor.config.blockedKeystrokes;
     26
     27 		var keystrokes			= editor.keystrokeHandler.keystrokes,
     28 			blockedKeystrokes	= editor.keystrokeHandler.blockedKeystrokes;
     29
     30 		for ( var i = 0 ; i < keystrokesConfig.length ; i++ )
     31 		{
     32 			keystrokes[ keystrokesConfig[i][0] ] = keystrokesConfig[i][1];
     33 		}
     34
     35 		for ( i = 0 ; i < blockedConfig.length ; i++ )
     36 		{
     37 			blockedKeystrokes[ blockedConfig[i] ] = 1;
     38 		}
     39 	}
     40 });
     41
     42 /**
     43  * Controls keystrokes typing in an editor instance.
     44  * @constructor
     45  * @param {CKEDITOR.editor} editor The editor instance.
     46  * @example
     47  */
     48 CKEDITOR.keystrokeHandler = function( editor )
     49 {
     50 	if ( editor.keystrokeHandler )
     51 		return editor.keystrokeHandler;
     52
     53 	/**
     54 	 * List of keystrokes associated to commands. Each entry points to the
     55 	 * command to be executed.
     56 	 * @type Object
     57 	 * @example
     58 	 */
     59 	this.keystrokes = {};
     60
     61 	/**
     62 	 * List of keystrokes that should be blocked if not defined at
     63 	 * {@link keystrokes}. In this way it is possible to block the default
     64 	 * browser behavior for those keystrokes.
     65 	 * @type Object
     66 	 * @example
     67 	 */
     68 	this.blockedKeystrokes = {};
     69
     70 	this._ =
     71 	{
     72 		editor : editor
     73 	};
     74
     75 	return this;
     76 };
     77
     78 (function()
     79 {
     80 	var cancel;
     81
     82 	var onKeyDown = function( event )
     83 	{
     84 		// The DOM event object is passed by the "data" property.
     85 		event = event.data;
     86
     87 		var keyCombination = event.getKeystroke();
     88 		var command = this.keystrokes[ keyCombination ];
     89 		var editor = this._.editor;
     90
     91 		cancel = ( editor.fire( 'key', { keyCode : keyCombination } ) === true );
     92
     93 		if ( !cancel )
     94 		{
     95 			if ( command )
     96 			{
     97 				var data = { from : 'keystrokeHandler' };
     98 				cancel = ( editor.execCommand( command, data ) !== false );
     99 			}
    100
    101 			if  ( !cancel )
    102 			{
    103 				var handler = editor.specialKeys[ keyCombination ];
    104 				cancel = ( handler && handler( editor ) === true );
    105
    106 				if ( !cancel )
    107 					cancel = !!this.blockedKeystrokes[ keyCombination ];
    108 			}
    109 		}
    110
    111 		if ( cancel )
    112 			event.preventDefault( true );
    113
    114 		return !cancel;
    115 	};
    116
    117 	var onKeyPress = function( event )
    118 	{
    119 		if ( cancel )
    120 		{
    121 			cancel = false;
    122 			event.data.preventDefault( true );
    123 		}
    124 	};
    125
    126 	CKEDITOR.keystrokeHandler.prototype =
    127 	{
    128 		/**
    129 		 * Attaches this keystroke handle to a DOM object. Keystrokes typed
    130 		 ** over this object will get handled by this keystrokeHandler.
    131 		 * @param {CKEDITOR.dom.domObject} domObject The DOM object to attach
    132 		 *		to.
    133 		 * @example
    134 		 */
    135 		attach : function( domObject )
    136 		{
    137 			// For most browsers, it is enough to listen to the keydown event
    138 			// only.
    139 			domObject.on( 'keydown', onKeyDown, this );
    140
    141 			// Some browsers instead, don't cancel key events in the keydown, but in the
    142 			// keypress. So we must do a longer trip in those cases.
    143 			if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )
    144 				domObject.on( 'keypress', onKeyPress, this );
    145 		}
    146 	};
    147 })();
    148
    149 /**
    150  * A list of keystrokes to be blocked if not defined in the {@link #keystrokes}
    151  * setting. In this way it is possible to block the default browser behavior
    152  * for those keystrokes.
    153  * @type Array
    154  * @example
    155  */
    156 CKEDITOR.config.blockedKeystrokes =
    157 [
    158 	CKEDITOR.CTRL + 66 /*B*/,
    159 	CKEDITOR.CTRL + 73 /*I*/,
    160 	CKEDITOR.CTRL + 85 /*U*/
    161 ];
    162
    163 /**
    164  * A list associating keystrokes to editor commands. Each element in the list
    165  * is an array where the first item is the keystroke, and the second is the
    166  * command to be executed.
    167  * @type Array
    168  * @example
    169  */
    170 CKEDITOR.config.keystrokes =
    171 [
    172 	[ CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' ],
    173 	[ CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' ],
    174
    175 	[ CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ],
    176
    177 	[ CKEDITOR.CTRL + 90 /*Z*/, 'undo' ],
    178 	[ CKEDITOR.CTRL + 89 /*Y*/, 'redo' ],
    179 	[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'redo' ],
    180
    181 	[ CKEDITOR.CTRL + 76 /*L*/, 'link' ],
    182
    183 	[ CKEDITOR.CTRL + 66 /*B*/, 'bold' ],
    184 	[ CKEDITOR.CTRL + 73 /*I*/, 'italic' ],
    185 	[ CKEDITOR.CTRL + 85 /*U*/, 'underline' ],
    186
    187 	[ CKEDITOR.ALT + 109 /*-*/, 'toolbarCollapse' ]
    188 ];
    189