{\r
requires : [ 'menu' ],\r
\r
- beforeInit : function( editor )\r
+ // Make sure the base class (CKEDITOR.menu) is loaded before it (#3318).\r
+ onLoad : function()\r
{\r
- editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor );\r
-\r
- editor.addCommand( 'contextMenu',\r
- {\r
- exec : function()\r
- {\r
- editor.contextMenu.show( editor.document.getBody() );\r
- }\r
- });\r
- }\r
-});\r
-\r
-CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass(\r
-{\r
- $ : function( editor )\r
- {\r
- this.id = 'cke_' + CKEDITOR.tools.getNextNumber();\r
- this.editor = editor;\r
- this._.listeners = [];\r
- this._.functionId = CKEDITOR.tools.addFunction( function( commandName )\r
- {\r
- this._.panel.hide();\r
- editor.focus();\r
- editor.execCommand( commandName );\r
- },\r
- this);\r
- },\r
-\r
- _ :\r
- {\r
- onMenu : function( offsetParent, corner, offsetX, offsetY )\r
+ CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass(\r
{\r
- var menu = this._.menu,\r
- editor = this.editor;\r
-\r
- if ( menu )\r
- {\r
- menu.hide();\r
- menu.removeAll();\r
- }\r
- else\r
- {\r
- menu = this._.menu = new CKEDITOR.menu( editor );\r
- menu.onClick = CKEDITOR.tools.bind( function( item )\r
- {\r
- menu.hide();\r
+ base : CKEDITOR.menu,\r
\r
- if ( item.onClick )\r
- item.onClick();\r
- else if ( item.command )\r
- editor.execCommand( item.command );\r
-\r
- }, this );\r
-\r
- menu.onEscape = function()\r
- {\r
- editor.focus();\r
- };\r
- }\r
-\r
- var listeners = this._.listeners,\r
- includedItems = [];\r
-\r
- var selection = this.editor.getSelection(),\r
- element = selection && selection.getStartElement();\r
-\r
- menu.onHide = CKEDITOR.tools.bind( function()\r
- {\r
- menu.onHide = null;\r
-\r
- if ( CKEDITOR.env.ie )\r
- {\r
- var selection = editor.getSelection();\r
- selection && selection.unlock();\r
- }\r
-\r
- this.onHide && this.onHide();\r
- },\r
- this );\r
-\r
- // Call all listeners, filling the list of items to be displayed.\r
- for ( var i = 0 ; i < listeners.length ; i++ )\r
+ $ : function( editor )\r
{\r
- var listenerItems = listeners[ i ]( element, selection );\r
-\r
- if ( listenerItems )\r
+ this.base.call( this, editor,\r
{\r
- for ( var itemName in listenerItems )\r
+ panel:\r
{\r
- var item = this.editor.getMenuItem( itemName );\r
-\r
- if ( item )\r
+ className : editor.skinClass + ' cke_contextmenu',\r
+ attributes :\r
{\r
- item.state = listenerItems[ itemName ];\r
- menu.add( item );\r
+ 'aria-label' : editor.lang.contextmenu.options\r
}\r
}\r
- }\r
- }\r
-\r
- // Don't show context menu with zero items.\r
- menu.items.length && menu.show( offsetParent, corner || ( editor.lang.dir == 'rtl' ? 2 : 1 ), offsetX, offsetY );\r
- }\r
- },\r
+ });\r
+ },\r
\r
- proto :\r
- {\r
- addTarget : function( element, nativeContextMenuOnCtrl )\r
- {\r
- // Opera doesn't support 'contextmenu' event, we have duo approaches employed here:\r
- // 1. Inherit the 'button override' hack we introduced in v2 (#4530), while this require the Opera browser\r
- // option 'Allow script to detect context menu/right click events' to be always turned on.\r
- // 2. Considering the fact that ctrl/meta key is not been occupied\r
- // for multiple range selecting (like Gecko), we use this key\r
- // combination as a fallback for triggering context-menu. (#4530)\r
- if ( CKEDITOR.env.opera )\r
+ proto :\r
{\r
- var contextMenuOverrideButton;\r
- element.on( 'mousedown', function( evt )\r
+ addTarget : function( element, nativeContextMenuOnCtrl )\r
{\r
- evt = evt.data;\r
- if ( evt.$.button != 2 )\r
+ // Opera doesn't support 'contextmenu' event, we have duo approaches employed here:\r
+ // 1. Inherit the 'button override' hack we introduced in v2 (#4530), while this require the Opera browser\r
+ // option 'Allow script to detect context menu/right click events' to be always turned on.\r
+ // 2. Considering the fact that ctrl/meta key is not been occupied\r
+ // for multiple range selecting (like Gecko), we use this key\r
+ // combination as a fallback for triggering context-menu. (#4530)\r
+ if ( CKEDITOR.env.opera && !( 'oncontextmenu' in document.body ))\r
{\r
- if ( evt.getKeystroke() == CKEDITOR.CTRL + 1 )\r
- element.fire( 'contextmenu', evt );\r
- return;\r
+ var contextMenuOverrideButton;\r
+ element.on( 'mousedown', function( evt )\r
+ {\r
+ evt = evt.data;\r
+ if ( evt.$.button != 2 )\r
+ {\r
+ if ( evt.getKeystroke() == CKEDITOR.CTRL + 1 )\r
+ element.fire( 'contextmenu', evt );\r
+ return;\r
+ }\r
+\r
+ if ( nativeContextMenuOnCtrl\r
+ && ( CKEDITOR.env.mac ? evt.$.metaKey : evt.$.ctrlKey ) )\r
+ return;\r
+\r
+ var target = evt.getTarget();\r
+\r
+ if ( !contextMenuOverrideButton )\r
+ {\r
+ var ownerDoc = target.getDocument();\r
+ contextMenuOverrideButton = ownerDoc.createElement( 'input' ) ;\r
+ contextMenuOverrideButton.$.type = 'button' ;\r
+ ownerDoc.getBody().append( contextMenuOverrideButton ) ;\r
+ }\r
+\r
+ contextMenuOverrideButton.setAttribute( 'style', 'position:absolute;top:' + ( evt.$.clientY - 2 ) +\r
+ 'px;left:' + ( evt.$.clientX - 2 ) +\r
+ 'px;width:5px;height:5px;opacity:0.01' );\r
+\r
+ } );\r
+\r
+ element.on( 'mouseup', function ( evt )\r
+ {\r
+ if ( contextMenuOverrideButton )\r
+ {\r
+ contextMenuOverrideButton.remove();\r
+ contextMenuOverrideButton = undefined;\r
+ // Simulate 'contextmenu' event.\r
+ element.fire( 'contextmenu', evt.data );\r
+ }\r
+ } );\r
}\r
\r
- if ( nativeContextMenuOnCtrl\r
- && ( evt.$.ctrlKey || evt.$.metaKey ) )\r
- return;\r
+ element.on( 'contextmenu', function( event )\r
+ {\r
+ var domEvent = event.data;\r
\r
- var target = evt.getTarget();\r
+ if ( nativeContextMenuOnCtrl &&\r
+ // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event,\r
+ // which make this property unreliable. (#4826)\r
+ ( CKEDITOR.env.webkit ? holdCtrlKey : ( CKEDITOR.env.mac ? domEvent.$.metaKey : domEvent.$.ctrlKey ) ) )\r
+ return;\r
\r
- if ( !contextMenuOverrideButton )\r
- {\r
- var ownerDoc = target.getDocument();\r
- contextMenuOverrideButton = ownerDoc.createElement( 'input' ) ;\r
- contextMenuOverrideButton.$.type = 'button' ;\r
- ownerDoc.getBody().append( contextMenuOverrideButton ) ;\r
- }\r
\r
- contextMenuOverrideButton.setAttribute( 'style', 'position:absolute;top:' + ( evt.$.clientY - 2 ) +\r
- 'px;left:' + ( evt.$.clientX - 2 ) +\r
- 'px;width:5px;height:5px;opacity:0.01' );\r
+ // Cancel the browser context menu.\r
+ domEvent.preventDefault();\r
\r
- } );\r
+ var offsetParent = domEvent.getTarget().getDocument().getDocumentElement(),\r
+ offsetX = domEvent.$.clientX,\r
+ offsetY = domEvent.$.clientY;\r
\r
- element.on( 'mouseup', function ( evt )\r
- {\r
- if ( contextMenuOverrideButton )\r
- {\r
- contextMenuOverrideButton.remove();\r
- contextMenuOverrideButton = undefined;\r
- // Simulate 'contextmenu' event.\r
- element.fire( 'contextmenu', evt.data );\r
- }\r
- } );\r
- }\r
+ CKEDITOR.tools.setTimeout( function()\r
+ {\r
+ this.open( offsetParent, null, offsetX, offsetY );\r
+ },\r
+ 0, this );\r
+ },\r
+ this );\r
\r
- element.on( 'contextmenu', function( event )\r
- {\r
- var domEvent = event.data;\r
+ if ( CKEDITOR.env.opera )\r
+ {\r
+ // 'contextmenu' event triggered by Windows menu key is unpreventable,\r
+ // cancel the key event itself. (#6534)\r
+ element.on( 'keypress' , function ( evt )\r
+ {\r
+ var domEvent = evt.data;\r
\r
- if ( nativeContextMenuOnCtrl &&\r
- // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event,\r
- // which make this property unreliable. (#4826)\r
- ( CKEDITOR.env.webkit ? holdCtrlKey : domEvent.$.ctrlKey || domEvent.$.metaKey ) )\r
- return;\r
+ if ( domEvent.$.keyCode === 0 )\r
+ domEvent.preventDefault();\r
+ });\r
+ }\r
\r
- // Selection will be unavailable after context menu shows up\r
- // in IE, lock it now.\r
- if ( CKEDITOR.env.ie )\r
+ if ( CKEDITOR.env.webkit )\r
{\r
- var selection = this.editor.getSelection();\r
- selection && selection.lock();\r
+ var holdCtrlKey,\r
+ onKeyDown = function( event )\r
+ {\r
+ holdCtrlKey = CKEDITOR.env.mac ? event.data.$.metaKey : event.data.$.ctrlKey ;\r
+ },\r
+ resetOnKeyUp = function()\r
+ {\r
+ holdCtrlKey = 0;\r
+ };\r
+\r
+ element.on( 'keydown', onKeyDown );\r
+ element.on( 'keyup', resetOnKeyUp );\r
+ element.on( 'contextmenu', resetOnKeyUp );\r
}\r
-\r
- // Cancel the browser context menu.\r
- domEvent.preventDefault();\r
-\r
- var offsetParent = domEvent.getTarget().getDocument().getDocumentElement(),\r
- offsetX = domEvent.$.clientX,\r
- offsetY = domEvent.$.clientY;\r
-\r
- CKEDITOR.tools.setTimeout( function()\r
- {\r
- this._.onMenu( offsetParent, null, offsetX, offsetY );\r
- },\r
- 0, this );\r
},\r
- this );\r
\r
- if ( CKEDITOR.env.webkit )\r
- {\r
- var holdCtrlKey,\r
- onKeyDown = function( event )\r
- {\r
- holdCtrlKey = event.data.$.ctrlKey || event.data.$.metaKey;\r
- },\r
- resetOnKeyUp = function()\r
- {\r
- holdCtrlKey = 0;\r
- };\r
-\r
- element.on( 'keydown', onKeyDown );\r
- element.on( 'keyup', resetOnKeyUp );\r
- element.on( 'contextmenu', resetOnKeyUp );\r
+ open : function( offsetParent, corner, offsetX, offsetY )\r
+ {\r
+ this.editor.focus();\r
+ offsetParent = offsetParent || CKEDITOR.document.getDocumentElement();\r
+ this.show( offsetParent, corner, offsetX, offsetY );\r
+ }\r
}\r
- },\r
+ });\r
+ },\r
\r
- addListener : function( listenerFn )\r
- {\r
- this._.listeners.push( listenerFn );\r
- },\r
+ beforeInit : function( editor )\r
+ {\r
+ editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor );\r
\r
- show : function( offsetParent, corner, offsetX, offsetY )\r
- {\r
- this.editor.focus();\r
- this._.onMenu( offsetParent || CKEDITOR.document.getDocumentElement(), corner, offsetX || 0, offsetY || 0 );\r
- }\r
+ editor.addCommand( 'contextMenu',\r
+ {\r
+ exec : function()\r
+ {\r
+ editor.contextMenu.open( editor.document.getBody() );\r
+ }\r
+ });\r
}\r
});\r
\r