1/* 2 * FCKeditor - The text editor for Internet - http://www.fckeditor.net 3 * Copyright (C) 2003-2007 Frederico Caldeira Knabben 4 * 5 * == BEGIN LICENSE == 6 * 7 * Licensed under the terms of any of the following licenses at your 8 * choice: 9 * 10 * - GNU General Public License Version 2 or later (the "GPL") 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 14 * http://www.gnu.org/licenses/lgpl.html 15 * 16 * - Mozilla Public License Version 1.1 or later (the "MPL") 17 * http://www.mozilla.org/MPL/MPL-1.1.html 18 * 19 * == END LICENSE == 20 * 21 * FCKContextMenu Class: renders an control a context menu. 22 */ 23 24var FCKContextMenu = function( parentWindow, langDir ) 25{ 26 this.CtrlDisable = false ; 27 28 var oPanel = this._Panel = new FCKPanel( parentWindow ) ; 29 oPanel.AppendStyleSheet( FCKConfig.SkinPath + 'fck_editor.css' ) ; 30 oPanel.IsContextMenu = true ; 31 32 // The FCKTools.DisableSelection doesn't seems to work to avoid dragging of the icons in Mozilla 33 // so we stop the start of the dragging 34 if ( FCKBrowserInfo.IsGecko ) 35 oPanel.Document.addEventListener( 'draggesture', function(e) {e.preventDefault(); return false;}, true ) ; 36 37 var oMenuBlock = this._MenuBlock = new FCKMenuBlock() ; 38 oMenuBlock.Panel = oPanel ; 39 oMenuBlock.OnClick = FCKTools.CreateEventListener( FCKContextMenu_MenuBlock_OnClick, this ) ; 40 41 this._Redraw = true ; 42} 43 44 45FCKContextMenu.prototype.SetMouseClickWindow = function( mouseClickWindow ) 46{ 47 if ( !FCKBrowserInfo.IsIE ) 48 { 49 this._Document = mouseClickWindow.document ; 50 if ( FCKBrowserInfo.IsOpera && !( 'oncontextmenu' in document.createElement('foo') ) ) 51 { 52 this._Document.addEventListener( 'mousedown', FCKContextMenu_Document_OnMouseDown, false ) ; 53 this._Document.addEventListener( 'mouseup', FCKContextMenu_Document_OnMouseUp, false ) ; 54 } 55 this._Document.addEventListener( 'contextmenu', FCKContextMenu_Document_OnContextMenu, false ) ; 56 } 57} 58 59FCKContextMenu.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled ) 60{ 61 var oItem = this._MenuBlock.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled) ; 62 this._Redraw = true ; 63 return oItem ; 64} 65 66FCKContextMenu.prototype.AddSeparator = function() 67{ 68 this._MenuBlock.AddSeparator() ; 69 this._Redraw = true ; 70} 71 72FCKContextMenu.prototype.RemoveAllItems = function() 73{ 74 this._MenuBlock.RemoveAllItems() ; 75 this._Redraw = true ; 76} 77 78FCKContextMenu.prototype.AttachToElement = function( element ) 79{ 80 if ( FCKBrowserInfo.IsIE ) 81 FCKTools.AddEventListenerEx( element, 'contextmenu', FCKContextMenu_AttachedElement_OnContextMenu, this ) ; 82 else 83 element._FCKContextMenu = this ; 84} 85 86function FCKContextMenu_Document_OnContextMenu( e ) 87{ 88 var el = e.target ; 89 90 while ( el ) 91 { 92 if ( el._FCKContextMenu ) 93 { 94 if ( el._FCKContextMenu.CtrlDisable && ( e.ctrlKey || e.metaKey ) ) 95 return true ; 96 97 FCKTools.CancelEvent( e ) ; 98 FCKContextMenu_AttachedElement_OnContextMenu( e, el._FCKContextMenu, el ) ; 99 return false ; 100 } 101 el = el.parentNode ; 102 } 103 return true ; 104} 105 106var FCKContextMenu_OverrideButton ; 107 108function FCKContextMenu_Document_OnMouseDown( e ) 109{ 110 if( !e || e.button != 2 ) 111 return false ; 112 113 var el = e.target ; 114 115 while ( el ) 116 { 117 if ( el._FCKContextMenu ) 118 { 119 if ( el._FCKContextMenu.CtrlDisable && ( e.ctrlKey || e.metaKey ) ) 120 return true ; 121 122 var overrideButton = FCKContextMenu_OverrideButton ; 123 if( !overrideButton ) 124 { 125 var doc = e.target.ownerDocument ; 126 overrideButton = FCKContextMenu_OverrideButton = doc.createElement('input') ; 127 overrideButton.type = 'button' ; 128 var buttonHolder = doc.createElement('p') ; 129 doc.body.appendChild( buttonHolder ) ; 130 buttonHolder.appendChild( overrideButton ) ; 131 } 132 133 overrideButton.style.cssText = 'position:absolute;top:' + ( e.clientY - 2 ) + 134 'px;left:' + ( e.clientX - 2 ) + 135 'px;width:5px;height:5px;opacity:0.01' ; 136 } 137 el = el.parentNode ; 138 } 139 return false ; 140} 141 142function FCKContextMenu_Document_OnMouseUp( e ) 143{ 144 var overrideButton = FCKContextMenu_OverrideButton ; 145 146 if ( overrideButton ) 147 { 148 var parent = overrideButton.parentNode ; 149 parent.parentNode.removeChild( parent ) ; 150 FCKContextMenu_OverrideButton = undefined ; 151 152 if( e && e.button == 2 ) 153 { 154 FCKContextMenu_Document_OnContextMenu( e ) ; 155 return false ; 156 } 157 } 158} 159 160function FCKContextMenu_AttachedElement_OnContextMenu( ev, fckContextMenu, el ) 161{ 162 if ( fckContextMenu.CtrlDisable && ( ev.ctrlKey || ev.metaKey ) ) 163 return true ; 164 165 var eTarget = el || this ; 166 167 if ( fckContextMenu.OnBeforeOpen ) 168 fckContextMenu.OnBeforeOpen.call( fckContextMenu, eTarget ) ; 169 170 if ( fckContextMenu._MenuBlock.Count() == 0 ) 171 return false ; 172 173 if ( fckContextMenu._Redraw ) 174 { 175 fckContextMenu._MenuBlock.Create( fckContextMenu._Panel.MainNode ) ; 176 fckContextMenu._Redraw = false ; 177 } 178 179 // This will avoid that the content of the context menu can be dragged in IE 180 // as the content of the panel is recreated we need to do it every time 181 FCKTools.DisableSelection( fckContextMenu._Panel.Document.body ) ; 182 183 var x = 0 ; 184 var y = 0 ; 185 if ( FCKBrowserInfo.IsIE ) 186 { 187 x = ev.screenX ; 188 y = ev.screenY ; 189 } 190 else if ( FCKBrowserInfo.IsSafari ) 191 { 192 x = ev.clientX ; 193 y = ev.clientY ; 194 } 195 else 196 { 197 x = ev.pageX ; 198 y = ev.pageY ; 199 } 200 fckContextMenu._Panel.Show( x, y, ev.currentTarget || null ) ; 201 202 return false ; 203} 204 205function FCKContextMenu_MenuBlock_OnClick( menuItem, contextMenu ) 206{ 207 contextMenu._Panel.Hide() ; 208 FCKTools.RunFunction( contextMenu.OnItemClick, contextMenu, menuItem ) ; 209} 210