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, 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 menu.hide(); 58 editor.focus(); 59 60 if ( item.onClick ) 61 item.onClick(); 62 else if ( item.command ) 63 { 64 if ( CKEDITOR.env.ie ) 65 this.restoreSelection(); 66 67 editor.execCommand( item.command ); 68 } 69 }, this ); 70 71 menu.onEscape = function() 72 { 73 editor.focus(); 74 }; 75 } 76 77 var listeners = this._.listeners, 78 includedItems = []; 79 80 var selection = this.editor.getSelection(), 81 element = selection && selection.getStartElement(); 82 83 // Call all listeners, filling the list of items to be displayed. 84 for ( var i = 0 ; i < listeners.length ; i++ ) 85 { 86 var listenerItems = listeners[ i ]( element, selection ); 87 88 if ( listenerItems ) 89 { 90 for ( var itemName in listenerItems ) 91 { 92 var item = this.editor.getMenuItem( itemName ); 93 94 if ( item ) 95 { 96 item.state = listenerItems[ itemName ]; 97 menu.add( item ); 98 } 99 } 100 } 101 } 102 103 if ( CKEDITOR.env.ie ) 104 this.saveSelection(); 105 106 menu.show( offsetParent, 1, offsetX, offsetY ); 107 } 108 }, 109 110 proto : 111 { 112 addTarget : function( element ) 113 { 114 element.on( 'contextmenu', function( event ) 115 { 116 var domEvent = event.data; 117 118 // Cancel the browser context menu. 119 domEvent.preventDefault(); 120 121 var offsetParent = domEvent.getTarget().getDocument().getDocumentElement(); 122 offsetX = domEvent.$.clientX, 123 offsetY = domEvent.$.clientY; 124 125 CKEDITOR.tools.setTimeout( function() 126 { 127 this._.onMenu( offsetParent, offsetX, offsetY ); 128 }, 129 0, this ); 130 }, 131 this ); 132 }, 133 134 addListener : function( listenerFn ) 135 { 136 this._.listeners.push( listenerFn ); 137 }, 138 139 show : function() 140 { 141 this.editor.focus(); 142 this._.onMenu( CKEDITOR.document.getDocumentElement(), 0, 0 ); 143 }, 144 145 /** 146 * Saves the current selection position in the editor. 147 */ 148 saveSelection : function() 149 { 150 if ( this.editor.mode == 'wysiwyg' ) 151 { 152 this.editor.focus(); 153 154 var selection = new CKEDITOR.dom.selection( this.editor.document ); 155 this._.selectedRanges = selection.getRanges(); 156 } 157 else 158 delete this._.selectedRanges; 159 }, 160 161 /** 162 * Restores the editor's selection from the previously saved position in this 163 * dialog. 164 */ 165 restoreSelection : function() 166 { 167 if ( this.editor.mode == 'wysiwyg' && this._.selectedRanges ) 168 { 169 this.editor.focus(); 170 ( new CKEDITOR.dom.selection( this.editor.document ) ).selectRanges( this._.selectedRanges ); 171 } 172 } 173 } 174 }); 175 176 // Fix the "contextmenu" event for DOM elements. 177 // We may do this if we identify browsers that don't support the context meny 178 // event on element directly. Leaving here for reference. 179 //if ( <specific browsers> ) 180 //{ 181 // CKEDITOR.dom.element.prototype.on = CKEDITOR.tools.override( CKEDITOR.dom.element.prototype.on, function( originalOn ) 182 // { 183 // return function( eventName ) 184 // { 185 // if ( eventName != 'contextmenu' ) 186 // return originalOn.apply( this, arguments ); 187 // 188 // // TODO : Implement the fix. 189 // }; 190 // }); 191 //} 192