JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.5
[ckeditor.git] / _source / plugins / contextmenu / plugin.js
index 8d7cb8d..22b8e49 100644 (file)
@@ -7,274 +7,161 @@ CKEDITOR.plugins.add( 'contextmenu',
 {\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
+               CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass(\r
+               {\r
+                       base : CKEDITOR.menu,\r
 \r
-               editor.addCommand( 'contextMenu',\r
+                       $ : function( editor )\r
                        {\r
-                               exec : function()\r
+                               this.base.call( this, editor,\r
+                               {\r
+                                       panel:\r
                                        {\r
-                                               editor.contextMenu.show( editor.document.getBody() );\r
+                                               className : editor.skinClass + ' cke_contextmenu',\r
+                                               attributes :\r
+                                               {\r
+                                                       'aria-label' : editor.lang.contextmenu.options\r
+                                               }\r
                                        }\r
-                       });\r
-       }\r
-});\r
-\r
-CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass(\r
-{\r
-       $ : function( editor )\r
-       {\r
-               this.id = CKEDITOR.tools.getNextId();\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
                        },\r
-                       this);\r
-\r
-               this.definition =\r
-               {\r
-                       panel:\r
-                       {\r
-                               className : editor.skinClass + ' cke_contextmenu',\r
-                               attributes :\r
-                               {\r
-                                       'aria-label' : editor.lang.contextmenu.options\r
-                               }\r
-                       }\r
-               };\r
-       },\r
-\r
-       _ :\r
-       {\r
-               onMenu : function( offsetParent, corner, offsetX, offsetY )\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
+                       proto :\r
                        {\r
-                               menu = this._.menu = new CKEDITOR.menu( editor, this.definition );\r
-                               menu.onClick = CKEDITOR.tools.bind( function( item )\r
-                               {\r
-                                       menu.hide();\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( keystroke )\r
+                               addTarget : function( element, nativeContextMenuOnCtrl )\r
                                {\r
-                                       var parent = this.parent;\r
-                                       // 1. If it's sub-menu, restore the last focused item\r
-                                       // of upper level menu.\r
-                                       // 2. In case of a top-menu, close it.\r
-                                       if ( parent )\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
-                                               parent._.panel.hideChild();\r
-                                               // Restore parent block item focus.\r
-                                               var parentBlock = parent._.panel._.panel._.currentBlock,\r
-                                                       parentFocusIndex =  parentBlock._.focusIndex;\r
-                                               parentBlock._.markItem( parentFocusIndex );\r
-                                       }\r
-                                       else if ( keystroke == 27 )\r
-                                       {\r
-                                               this.hide();\r
-                                               editor.focus();\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
-                                       return false;\r
-                               };\r
-                       }\r
 \r
-                       var listeners = this._.listeners,\r
-                               includedItems = [];\r
+                                       element.on( 'contextmenu', function( event )\r
+                                               {\r
+                                                       var domEvent = event.data;\r
 \r
-                       var selection = this.editor.getSelection(),\r
-                               element = selection && selection.getStartElement();\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
-                       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
+                                                       // Cancel the browser context menu.\r
+                                                       domEvent.preventDefault();\r
 \r
-                                       this.onHide && this.onHide();\r
-                               },\r
-                               this );\r
+                                                       var offsetParent = domEvent.getTarget().getDocument().getDocumentElement(),\r
+                                                               offsetX = domEvent.$.clientX,\r
+                                                               offsetY = domEvent.$.clientY;\r
 \r
-                       // Call all listeners, filling the list of items to be displayed.\r
-                       for ( var i = 0 ; i < listeners.length ; i++ )\r
-                       {\r
-                               var listenerItems = listeners[ i ]( element, selection );\r
+                                                       CKEDITOR.tools.setTimeout( function()\r
+                                                               {\r
+                                                                       this.open( offsetParent, null, offsetX, offsetY );\r
+                                                               },\r
+                                                               0, this );\r
+                                               },\r
+                                               this );\r
 \r
-                               if ( listenerItems )\r
-                               {\r
-                                       for ( var itemName in listenerItems )\r
+                                       if ( CKEDITOR.env.opera )\r
                                        {\r
-                                               var item = this.editor.getMenuItem( itemName );\r
-\r
-                                               if ( item )\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
-                                                       item.state = listenerItems[ itemName ];\r
-                                                       menu.add( item );\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
+                                                       var domEvent = evt.data;\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
-       proto :\r
-       {\r
-               addTarget : function( element, nativeContextMenuOnCtrl )\r
-               {\r
-\r
-                       // For browsers (Opera <=10a) that doesn't  support 'contextmenu' event, we have duo approaches employed here:\r
-                       // 1. Inherit the 'button override' hack we introduced in v2 (#4530) (In Opera browser, this require the\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
-                               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
+                                                       if ( domEvent.$.keyCode === 0 )\r
+                                                               domEvent.preventDefault();\r
+                                               });\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
+                                       if ( CKEDITOR.env.webkit )\r
                                        {\r
-                                               var ownerDoc =  target.getDocument();\r
-                                               contextMenuOverrideButton = ownerDoc.createElement( 'input' ) ;\r
-                                               contextMenuOverrideButton.$.type = 'button' ;\r
-                                               ownerDoc.getBody().append( contextMenuOverrideButton ) ;\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
-                                       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
-                       element.on( 'contextmenu', function( event )\r
-                               {\r
-                                       var domEvent = event.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 : ( CKEDITOR.env.mac ? domEvent.$.metaKey : domEvent.$.ctrlKey ) ) )\r
-                                               return;\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.show( offsetParent, null, offsetX, offsetY );\r
-                                               },\r
-                                               0, this );\r
                                },\r
-                               this );\r
 \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
+                               open : function( offsetParent, corner, offsetX, offsetY )\r
                                {\r
-                                       var domEvent = evt.data;\r
-\r
-                                       if ( domEvent.$.keyCode === 0 )\r
-                                               domEvent.preventDefault();\r
-                               });\r
-                       }\r
-\r
-                       if ( CKEDITOR.env.webkit )\r
-                       {\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
+                                       this.editor.focus();\r
+                                       offsetParent = offsetParent || CKEDITOR.document.getDocumentElement();\r
+                                       this.show( offsetParent, corner, offsetX, offsetY );\r
+                               }\r
                        }\r
-               },\r
-\r
-               addListener : function( listenerFn )\r
-               {\r
-                       this._.listeners.push( listenerFn );\r
-               },\r
+               });\r
+       },\r
 \r
-               show : function( offsetParent, corner, offsetX, offsetY )\r
-               {\r
-                       this.editor.focus();\r
+       beforeInit : function( editor )\r
+       {\r
+               editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor );\r
 \r
-                       // Selection will be unavailable after context menu shows up\r
-                       // in IE, lock it now.\r
-                       if ( CKEDITOR.env.ie )\r
+               editor.addCommand( 'contextMenu',\r
                        {\r
-                               var selection = this.editor.getSelection();\r
-                               selection && selection.lock();\r
-                       }\r
-\r
-                       this._.onMenu( offsetParent || CKEDITOR.document.getDocumentElement(), corner, offsetX || 0, offsetY || 0 );\r
-               }\r
+                               exec : function()\r
+                                       {\r
+                                               editor.contextMenu.open( editor.document.getBody() );\r
+                                       }\r
+                       });\r
        }\r
 });\r
 \r