2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
6 CKEDITOR
.plugins
.add( 'contextmenu',
10 // Make sure the base class (CKEDITOR.menu) is loaded before it (#3318).
13 CKEDITOR
.plugins
.contextMenu
= CKEDITOR
.tools
.createClass(
17 $ : function( editor
)
19 this.base
.call( this, editor
,
23 className
: editor
.skinClass
+ ' cke_contextmenu',
26 'aria-label' : editor
.lang
.contextmenu
.options
34 addTarget : function( element
, nativeContextMenuOnCtrl
)
36 // Opera doesn't support 'contextmenu' event, we have duo approaches employed here:
37 // 1. Inherit the 'button override' hack we introduced in v2 (#4530), while this require the Opera browser
38 // option 'Allow script to detect context menu/right click events' to be always turned on.
39 // 2. Considering the fact that ctrl/meta key is not been occupied
40 // for multiple range selecting (like Gecko), we use this key
41 // combination as a fallback for triggering context-menu. (#4530)
42 if ( CKEDITOR
.env
.opera
&& !( 'oncontextmenu' in document
.body
))
44 var contextMenuOverrideButton
;
45 element
.on( 'mousedown', function( evt
)
48 if ( evt
.$.button
!= 2 )
50 if ( evt
.getKeystroke() == CKEDITOR
.CTRL
+ 1 )
51 element
.fire( 'contextmenu', evt
);
55 if ( nativeContextMenuOnCtrl
56 && ( CKEDITOR
.env
.mac
? evt
.$.metaKey
: evt
.$.ctrlKey
) )
59 var target
= evt
.getTarget();
61 if ( !contextMenuOverrideButton
)
63 var ownerDoc
= target
.getDocument();
64 contextMenuOverrideButton
= ownerDoc
.createElement( 'input' ) ;
65 contextMenuOverrideButton
.$.type
= 'button' ;
66 ownerDoc
.getBody().append( contextMenuOverrideButton
) ;
69 contextMenuOverrideButton
.setAttribute( 'style', 'position:absolute;top:' + ( evt
.$.clientY
- 2 ) +
70 'px;left:' + ( evt
.$.clientX
- 2 ) +
71 'px;width:5px;height:5px;opacity:0.01' );
75 element
.on( 'mouseup', function ( evt
)
77 if ( contextMenuOverrideButton
)
79 contextMenuOverrideButton
.remove();
80 contextMenuOverrideButton
= undefined;
81 // Simulate 'contextmenu' event.
82 element
.fire( 'contextmenu', evt
.data
);
87 element
.on( 'contextmenu', function( event
)
89 var domEvent
= event
.data
;
91 if ( nativeContextMenuOnCtrl
&&
92 // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event,
93 // which make this property unreliable. (#4826)
94 ( CKEDITOR
.env
.webkit
? holdCtrlKey
: ( CKEDITOR
.env
.mac
? domEvent
.$.metaKey
: domEvent
.$.ctrlKey
) ) )
98 // Cancel the browser context menu.
99 domEvent
.preventDefault();
101 var offsetParent
= domEvent
.getTarget().getDocument().getDocumentElement(),
102 offsetX
= domEvent
.$.clientX
,
103 offsetY
= domEvent
.$.clientY
;
105 CKEDITOR
.tools
.setTimeout( function()
107 this.open( offsetParent
, null, offsetX
, offsetY
);
113 if ( CKEDITOR
.env
.opera
)
115 // 'contextmenu' event triggered by Windows menu key is unpreventable,
116 // cancel the key event itself. (#6534)
117 element
.on( 'keypress' , function ( evt
)
119 var domEvent
= evt
.data
;
121 if ( domEvent
.$.keyCode
=== 0 )
122 domEvent
.preventDefault();
126 if ( CKEDITOR
.env
.webkit
)
129 onKeyDown = function( event
)
131 holdCtrlKey
= CKEDITOR
.env
.mac
? event
.data
.$.metaKey
: event
.data
.$.ctrlKey
;
133 resetOnKeyUp = function()
138 element
.on( 'keydown', onKeyDown
);
139 element
.on( 'keyup', resetOnKeyUp
);
140 element
.on( 'contextmenu', resetOnKeyUp
);
144 open : function( offsetParent
, corner
, offsetX
, offsetY
)
147 offsetParent
= offsetParent
|| CKEDITOR
.document
.getDocumentElement();
148 this.show( offsetParent
, corner
, offsetX
, offsetY
);
154 beforeInit : function( editor
)
156 editor
.contextMenu
= new CKEDITOR
.plugins
.contextMenu( editor
);
158 editor
.addCommand( 'contextMenu',
162 editor
.contextMenu
.open( editor
.document
.getBody() );
169 * Whether to show the browser native context menu when the CTRL or the
170 * META (Mac) key is pressed while opening the context menu.
171 * @name CKEDITOR.config.browserContextMenuOnCtrl
176 * config.browserContextMenuOnCtrl = false;