2018-06-17 16:07:19 +00:00
|
|
|
/**
|
|
|
|
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
|
|
|
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
2014-04-11 20:05:45 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used
|
2018-06-17 16:07:19 +00:00
|
|
|
* to handle the focus in editor instances.
|
2014-04-11 20:05:45 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
( function() {
|
|
|
|
/**
|
|
|
|
* Manages the focus activity in an editor instance. This class is to be
|
2018-06-17 16:07:19 +00:00
|
|
|
* used mainly by UI element coders when adding interface elements that need
|
2014-04-11 20:05:45 +00:00
|
|
|
* to set the focus state of the editor.
|
|
|
|
*
|
|
|
|
* var focusManager = new CKEDITOR.focusManager( editor );
|
|
|
|
* focusManager.focus();
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @constructor Creates a focusManager class instance.
|
|
|
|
* @param {CKEDITOR.editor} editor The editor instance.
|
|
|
|
*/
|
|
|
|
CKEDITOR.focusManager = function( editor ) {
|
|
|
|
if ( editor.focusManager )
|
|
|
|
return editor.focusManager;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates that the editor instance has focus.
|
|
|
|
*
|
|
|
|
* alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g. true
|
|
|
|
*/
|
|
|
|
this.hasFocus = false;
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Indicates the currently focused DOM element that makes the editor activated.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* @property {CKEDITOR.dom.domObject}
|
|
|
|
*/
|
|
|
|
this.currentActive = null;
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Object used to store private stuff.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._ = {
|
|
|
|
editor: editor
|
|
|
|
};
|
|
|
|
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
var SLOT_NAME = 'focusmanager',
|
|
|
|
SLOT_NAME_LISTENERS = 'focusmanager_handlers';
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Object used to store private stuff.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @class
|
|
|
|
* @singleton
|
|
|
|
*/
|
|
|
|
CKEDITOR.focusManager._ = {
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* The delay (in milliseconds) to deactivate the editor when a UI DOM element has lost focus.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @property {Number} [blurDelay=200]
|
|
|
|
* @member CKEDITOR.focusManager._
|
|
|
|
*/
|
|
|
|
blurDelay: 200
|
|
|
|
};
|
|
|
|
|
|
|
|
CKEDITOR.focusManager.prototype = {
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Indicates that this editor instance is activated (due to a DOM focus change).
|
|
|
|
* The `activated` state is a symbolic indicator of an active user
|
2014-04-11 20:05:45 +00:00
|
|
|
* interaction session.
|
|
|
|
*
|
|
|
|
* **Note:** This method will not introduce UI focus
|
2018-06-17 16:07:19 +00:00
|
|
|
* impact on DOM, it is here to record the editor UI focus state internally.
|
|
|
|
* If you want to make the cursor blink inside the editable, use
|
2014-04-11 20:05:45 +00:00
|
|
|
* {@link CKEDITOR.editor#method-focus} instead.
|
|
|
|
*
|
|
|
|
* var editor = CKEDITOR.instances.editor1;
|
2018-06-17 16:07:19 +00:00
|
|
|
* editor.focusManager.focus( editor.editable() );
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {CKEDITOR.dom.element} [currentActive] The new value of the {@link #currentActive} property.
|
2014-04-11 20:05:45 +00:00
|
|
|
* @member CKEDITOR.focusManager
|
|
|
|
*/
|
|
|
|
focus: function( currentActive ) {
|
|
|
|
if ( this._.timer )
|
|
|
|
clearTimeout( this._.timer );
|
|
|
|
|
|
|
|
if ( currentActive )
|
|
|
|
this.currentActive = currentActive;
|
|
|
|
|
|
|
|
if ( !( this.hasFocus || this._.locked ) ) {
|
|
|
|
// If another editor has the current focus, we first "blur" it. In
|
|
|
|
// this way the events happen in a more logical sequence, like:
|
|
|
|
// "focus 1" > "blur 1" > "focus 2"
|
|
|
|
// ... instead of:
|
|
|
|
// "focus 1" > "focus 2" > "blur 1"
|
|
|
|
var current = CKEDITOR.currentInstance;
|
|
|
|
current && current.focusManager.blur( 1 );
|
|
|
|
|
|
|
|
this.hasFocus = true;
|
|
|
|
|
|
|
|
var ct = this._.editor.container;
|
|
|
|
ct && ct.addClass( 'cke_focus' );
|
|
|
|
this._.editor.fire( 'focus' );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Prevents from changing the focus manager state until the next {@link #unlock} is called.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* @member CKEDITOR.focusManager
|
|
|
|
*/
|
|
|
|
lock: function() {
|
|
|
|
this._.locked = 1;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Restores the automatic focus management if {@link #lock} is called.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* @member CKEDITOR.focusManager
|
|
|
|
*/
|
|
|
|
unlock: function() {
|
|
|
|
delete this._.locked;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to indicate that the editor instance has been deactivated by the specified
|
|
|
|
* element which has just lost focus.
|
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* **Note:** This function acts asynchronously with a delay of 100ms to
|
|
|
|
* avoid temporary deactivation. Use the `noDelay` parameter instead
|
2014-04-11 20:05:45 +00:00
|
|
|
* to deactivate immediately.
|
|
|
|
*
|
|
|
|
* var editor = CKEDITOR.instances.editor1;
|
|
|
|
* editor.focusManager.blur();
|
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {Boolean} [noDelay=false] Immediately deactivate the editor instance synchronously.
|
2014-04-11 20:05:45 +00:00
|
|
|
* @member CKEDITOR.focusManager
|
|
|
|
*/
|
|
|
|
blur: function( noDelay ) {
|
2018-06-17 16:07:19 +00:00
|
|
|
if ( this._.locked ) {
|
2014-04-11 20:05:45 +00:00
|
|
|
return;
|
2018-06-17 16:07:19 +00:00
|
|
|
}
|
2014-04-11 20:05:45 +00:00
|
|
|
|
|
|
|
function doBlur() {
|
|
|
|
if ( this.hasFocus ) {
|
|
|
|
this.hasFocus = false;
|
|
|
|
|
|
|
|
var ct = this._.editor.container;
|
|
|
|
ct && ct.removeClass( 'cke_focus' );
|
|
|
|
this._.editor.fire( 'blur' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-17 16:07:19 +00:00
|
|
|
if ( this._.timer ) {
|
2014-04-11 20:05:45 +00:00
|
|
|
clearTimeout( this._.timer );
|
2018-06-17 16:07:19 +00:00
|
|
|
}
|
2014-04-11 20:05:45 +00:00
|
|
|
|
|
|
|
var delay = CKEDITOR.focusManager._.blurDelay;
|
2018-06-17 16:07:19 +00:00
|
|
|
if ( noDelay || !delay ) {
|
2014-04-11 20:05:45 +00:00
|
|
|
doBlur.call( this );
|
2018-06-17 16:07:19 +00:00
|
|
|
} else {
|
2014-04-11 20:05:45 +00:00
|
|
|
this._.timer = CKEDITOR.tools.setTimeout( function() {
|
|
|
|
delete this._.timer;
|
|
|
|
doBlur.call( this );
|
|
|
|
}, delay, this );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Registers a UI DOM element to the focus manager, which will make the focus manager "hasFocus"
|
|
|
|
* once the input focus is relieved on the element.
|
|
|
|
* This method is designed to be used by plugins to expand the jurisdiction of the editor focus.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {CKEDITOR.dom.element} element The container (topmost) element of one UI part.
|
|
|
|
* @param {Boolean} isCapture If specified, {@link CKEDITOR.event#useCapture} will be used when listening to the focus event.
|
2014-04-11 20:05:45 +00:00
|
|
|
* @member CKEDITOR.focusManager
|
|
|
|
*/
|
|
|
|
add: function( element, isCapture ) {
|
|
|
|
var fm = element.getCustomData( SLOT_NAME );
|
|
|
|
if ( !fm || fm != this ) {
|
|
|
|
// If this element is already taken by another instance, dismiss it first.
|
|
|
|
fm && fm.remove( element );
|
|
|
|
|
|
|
|
var focusEvent = 'focus',
|
|
|
|
blurEvent = 'blur';
|
|
|
|
|
|
|
|
// Bypass the element's internal DOM focus change.
|
|
|
|
if ( isCapture ) {
|
|
|
|
|
|
|
|
// Use "focusin/focusout" events instead of capture phase in IEs,
|
|
|
|
// which fires synchronously.
|
|
|
|
if ( CKEDITOR.env.ie ) {
|
|
|
|
focusEvent = 'focusin';
|
|
|
|
blurEvent = 'focusout';
|
2018-06-17 16:07:19 +00:00
|
|
|
} else {
|
2014-04-11 20:05:45 +00:00
|
|
|
CKEDITOR.event.useCapture = 1;
|
2018-06-17 16:07:19 +00:00
|
|
|
}
|
2014-04-11 20:05:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var listeners = {
|
|
|
|
blur: function() {
|
|
|
|
if ( element.equals( this.currentActive ) )
|
|
|
|
this.blur();
|
|
|
|
},
|
|
|
|
focus: function() {
|
|
|
|
this.focus( element );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
element.on( focusEvent, listeners.focus, this );
|
|
|
|
element.on( blurEvent, listeners.blur, this );
|
|
|
|
|
|
|
|
if ( isCapture )
|
|
|
|
CKEDITOR.event.useCapture = 0;
|
|
|
|
|
|
|
|
element.setCustomData( SLOT_NAME, this );
|
|
|
|
element.setCustomData( SLOT_NAME_LISTENERS, listeners );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-06-17 16:07:19 +00:00
|
|
|
* Dismisses an element from the focus manager delegations added by {@link #add}.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
2018-06-17 16:07:19 +00:00
|
|
|
* @param {CKEDITOR.dom.element} element The element to be removed from the focus manager.
|
2014-04-11 20:05:45 +00:00
|
|
|
* @member CKEDITOR.focusManager
|
|
|
|
*/
|
|
|
|
remove: function( element ) {
|
|
|
|
element.removeCustomData( SLOT_NAME );
|
|
|
|
var listeners = element.removeCustomData( SLOT_NAME_LISTENERS );
|
|
|
|
element.removeListener( 'blur', listeners.blur );
|
|
|
|
element.removeListener( 'focus', listeners.focus );
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
} )();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fired when the editor instance receives the input focus.
|
|
|
|
*
|
|
|
|
* editor.on( 'focus', function( e ) {
|
|
|
|
* alert( 'The editor named ' + e.editor.name + ' is now focused' );
|
|
|
|
* } );
|
|
|
|
*
|
|
|
|
* @event focus
|
|
|
|
* @member CKEDITOR.editor
|
|
|
|
* @param {CKEDITOR.editor} editor The editor instance.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fired when the editor instance loses the input focus.
|
|
|
|
*
|
|
|
|
* **Note:** This event will **NOT** be triggered when focus is moved internally, e.g. from
|
2018-06-17 16:07:19 +00:00
|
|
|
* an editable to another part of the editor UI like a dialog window.
|
|
|
|
* If you are interested only in the focus state of the editable, listen to the `focus`
|
|
|
|
* and `blur` events of the {@link CKEDITOR.editable} instead.
|
2014-04-11 20:05:45 +00:00
|
|
|
*
|
|
|
|
* editor.on( 'blur', function( e ) {
|
|
|
|
* alert( 'The editor named ' + e.editor.name + ' lost the focus' );
|
|
|
|
* } );
|
|
|
|
*
|
|
|
|
* @event blur
|
|
|
|
* @member CKEDITOR.editor
|
|
|
|
* @param {CKEDITOR.editor} editor The editor instance.
|
|
|
|
*/
|