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