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 CKEDITOR.plugins.add( 'contextmenu', 7 { 8 requires : [ 'menu' ], 9 10 beforeInit : function( editor ) 11 { 12 editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor ); 13 14 editor.addCommand( 'contextMenu', 15 { 16 exec : function() 17 { 18 editor.contextMenu.show(); 19 } 20 }); 21 } 22 }); 23 24 CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass( 25 { 26 $ : function( editor ) 27 { 28 this.id = 'cke_' + CKEDITOR.tools.getNextNumber(); 29 this.editor = editor; 30 this._.listeners = []; 31 this._.functionId = CKEDITOR.tools.addFunction( function( commandName ) 32 { 33 this._.panel.hide(); 34 editor.focus(); 35 editor.execCommand( commandName ); 36 }, 37 this); 38 }, 39 40 _ : 41 { 42 onMenu : function( offsetParent, corner, offsetX, offsetY ) 43 { 44 var menu = this._.menu, 45 editor = this.editor; 46 47 if ( menu ) 48 { 49 menu.hide(); 50 menu.removeAll(); 51 } 52 else 53 { 54 menu = this._.menu = new CKEDITOR.menu( editor ); 55 menu.onClick = CKEDITOR.tools.bind( function( item ) 56 { 57 var noUnlock = true; 58 menu.hide(); 59 60 if ( CKEDITOR.env.ie ) 61 menu.onEscape(); 62 63 if ( item.onClick ) 64 item.onClick(); 65 else if ( item.command ) 66 editor.execCommand( item.command ); 67 68 noUnlock = false; 69 }, this ); 70 71 menu.onEscape = function() 72 { 73 editor.focus(); 74 75 if ( CKEDITOR.env.ie ) 76 editor.getSelection().unlock( true ); 77 }; 78 } 79 80 var listeners = this._.listeners, 81 includedItems = []; 82 83 var selection = this.editor.getSelection(), 84 element = selection && selection.getStartElement(); 85 86 // Lock the selection in IE, so it can be restored when closing the 87 // menu. 88 if ( CKEDITOR.env.ie ) 89 selection.lock(); 90 91 menu.onHide = CKEDITOR.tools.bind( function() 92 { 93 menu.onHide = null; 94 95 if ( CKEDITOR.env.ie ) 96 editor.getSelection().unlock(); 97 98 this.onHide && this.onHide(); 99 }, 100 this ); 101 102 // Call all listeners, filling the list of items to be displayed. 103 for ( var i = 0 ; i < listeners.length ; i++ ) 104 { 105 var listenerItems = listeners[ i ]( element, selection ); 106 107 if ( listenerItems ) 108 { 109 for ( var itemName in listenerItems ) 110 { 111 var item = this.editor.getMenuItem( itemName ); 112 113 if ( item ) 114 { 115 item.state = listenerItems[ itemName ]; 116 menu.add( item ); 117 } 118 } 119 } 120 } 121 122 menu.show( offsetParent, corner || ( editor.lang.dir == 'rtl' ? 2 : 1 ), offsetX, offsetY ); 123 } 124 }, 125 126 proto : 127 { 128 addTarget : function( element ) 129 { 130 element.on( 'contextmenu', function( event ) 131 { 132 var domEvent = event.data; 133 134 // Cancel the browser context menu. 135 domEvent.preventDefault(); 136 137 var offsetParent = domEvent.getTarget().getDocument().getDocumentElement(), 138 offsetX = domEvent.$.clientX, 139 offsetY = domEvent.$.clientY; 140 141 CKEDITOR.tools.setTimeout( function() 142 { 143 this._.onMenu( offsetParent, null, offsetX, offsetY ); 144 }, 145 0, this ); 146 }, 147 this ); 148 }, 149 150 addListener : function( listenerFn ) 151 { 152 this._.listeners.push( listenerFn ); 153 }, 154 155 show : function( offsetParent, corner, offsetX, offsetY ) 156 { 157 this.editor.focus(); 158 this._.onMenu( offsetParent || CKEDITOR.document.getDocumentElement(), corner, offsetX || 0, offsetY || 0 ); 159 } 160 } 161 }); 162 163 // Fix the "contextmenu" event for DOM elements. 164 // We may do this if we identify browsers that don't support the context meny 165 // event on element directly. Leaving here for reference. 166 //if ( <specific browsers> ) 167 //{ 168 // CKEDITOR.dom.element.prototype.on = CKEDITOR.tools.override( CKEDITOR.dom.element.prototype.on, function( originalOn ) 169 // { 170 // return function( eventName ) 171 // { 172 // if ( eventName != 'contextmenu' ) 173 // return originalOn.apply( this, arguments ); 174 // 175 // // TODO : Implement the fix. 176 // }; 177 // }); 178 //} 179