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 * Defines the FCK.ContextMenu object that is responsible for all 22 * Context Menu operations in the editing area. 23 */ 24 25FCK.ContextMenu = new Object() ; 26FCK.ContextMenu.Listeners = new Array() ; 27 28FCK.ContextMenu.RegisterListener = function( listener ) 29{ 30 if ( listener ) 31 this.Listeners.push( listener ) ; 32} 33 34function FCK_ContextMenu_Init() 35{ 36 var oInnerContextMenu = FCK.ContextMenu._InnerContextMenu = new FCKContextMenu( FCKBrowserInfo.IsIE ? window : window.parent, FCKLang.Dir ) ; 37 oInnerContextMenu.CtrlDisable = FCKConfig.BrowserContextMenuOnCtrl ; 38 oInnerContextMenu.OnBeforeOpen = FCK_ContextMenu_OnBeforeOpen ; 39 oInnerContextMenu.OnItemClick = FCK_ContextMenu_OnItemClick ; 40 41 // Get the registering function. 42 var oMenu = FCK.ContextMenu ; 43 44 // Register all configured context menu listeners. 45 for ( var i = 0 ; i < FCKConfig.ContextMenu.length ; i++ ) 46 oMenu.RegisterListener( FCK_ContextMenu_GetListener( FCKConfig.ContextMenu[i] ) ) ; 47} 48 49function FCK_ContextMenu_GetListener( listenerName ) 50{ 51 switch ( listenerName ) 52 { 53 case 'Generic' : 54 return { 55 AddItems : function( menu, tag, tagName ) 56 { 57 menu.AddItem( 'Cut' , FCKLang.Cut , 7, FCKCommands.GetCommand( 'Cut' ).GetState() == FCK_TRISTATE_DISABLED ) ; 58 menu.AddItem( 'Copy' , FCKLang.Copy , 8, FCKCommands.GetCommand( 'Copy' ).GetState() == FCK_TRISTATE_DISABLED ) ; 59 menu.AddItem( 'Paste' , FCKLang.Paste , 9, FCKCommands.GetCommand( 'Paste' ).GetState() == FCK_TRISTATE_DISABLED ) ; 60 }} ; 61 62 case 'Table' : 63 return { 64 AddItems : function( menu, tag, tagName ) 65 { 66 var bIsTable = ( tagName == 'TABLE' ) ; 67 var bIsCell = ( !bIsTable && FCKSelection.HasAncestorNode( 'TABLE' ) ) ; 68 69 if ( bIsCell ) 70 { 71 menu.AddSeparator() ; 72 var oItem = menu.AddItem( 'Cell' , FCKLang.CellCM ) ; 73 oItem.AddItem( 'TableInsertCellBefore' , FCKLang.InsertCellBefore, 69 ) ; 74 oItem.AddItem( 'TableInsertCellAfter' , FCKLang.InsertCellAfter, 58 ) ; 75 oItem.AddItem( 'TableDeleteCells' , FCKLang.DeleteCells, 59 ) ; 76 if ( FCKBrowserInfo.IsGecko ) 77 oItem.AddItem( 'TableMergeCells' , FCKLang.MergeCells, 60, 78 FCKCommands.GetCommand( 'TableMergeCells' ).GetState() == FCK_TRISTATE_DISABLED ) ; 79 else 80 { 81 oItem.AddItem( 'TableMergeRight' , FCKLang.MergeRight, 60, 82 FCKCommands.GetCommand( 'TableMergeRight' ).GetState() == FCK_TRISTATE_DISABLED ) ; 83 oItem.AddItem( 'TableMergeDown' , FCKLang.MergeDown, 60, 84 FCKCommands.GetCommand( 'TableMergeDown' ).GetState() == FCK_TRISTATE_DISABLED ) ; 85 } 86 oItem.AddItem( 'TableHorizontalSplitCell' , FCKLang.HorizontalSplitCell, 61, 87 FCKCommands.GetCommand( 'TableHorizontalSplitCell' ).GetState() == FCK_TRISTATE_DISABLED ) ; 88 oItem.AddItem( 'TableVerticalSplitCell' , FCKLang.VerticalSplitCell, 61, 89 FCKCommands.GetCommand( 'TableVerticalSplitCell' ).GetState() == FCK_TRISTATE_DISABLED ) ; 90 oItem.AddSeparator() ; 91 oItem.AddItem( 'TableCellProp' , FCKLang.CellProperties, 57, 92 FCKCommands.GetCommand( 'TableCellProp' ).GetState() == FCK_TRISTATE_DISABLED ) ; 93 94 menu.AddSeparator() ; 95 oItem = menu.AddItem( 'Row' , FCKLang.RowCM ) ; 96 oItem.AddItem( 'TableInsertRowBefore' , FCKLang.InsertRowBefore, 70 ) ; 97 oItem.AddItem( 'TableInsertRowAfter' , FCKLang.InsertRowAfter, 62 ) ; 98 oItem.AddItem( 'TableDeleteRows' , FCKLang.DeleteRows, 63 ) ; 99 100 menu.AddSeparator() ; 101 oItem = menu.AddItem( 'Column' , FCKLang.ColumnCM ) ; 102 oItem.AddItem( 'TableInsertColumnBefore', FCKLang.InsertColumnBefore, 71 ) ; 103 oItem.AddItem( 'TableInsertColumnAfter' , FCKLang.InsertColumnAfter, 64 ) ; 104 oItem.AddItem( 'TableDeleteColumns' , FCKLang.DeleteColumns, 65 ) ; 105 } 106 107 if ( bIsTable || bIsCell ) 108 { 109 menu.AddSeparator() ; 110 menu.AddItem( 'TableDelete' , FCKLang.TableDelete ) ; 111 menu.AddItem( 'TableProp' , FCKLang.TableProperties, 39 ) ; 112 } 113 }} ; 114 115 case 'Link' : 116 return { 117 AddItems : function( menu, tag, tagName ) 118 { 119 var bInsideLink = ( tagName == 'A' || FCKSelection.HasAncestorNode( 'A' ) ) ; 120 121 if ( bInsideLink || FCK.GetNamedCommandState( 'Unlink' ) != FCK_TRISTATE_DISABLED ) 122 { 123 // Go up to the anchor to test its properties 124 var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ; 125 var bIsAnchor = ( oLink && oLink.name.length > 0 && oLink.href.length == 0 ) ; 126 // If it isn't a link then don't add the Link context menu 127 if ( bIsAnchor ) 128 return ; 129 130 menu.AddSeparator() ; 131 if ( bInsideLink ) 132 menu.AddItem( 'Link', FCKLang.EditLink , 34 ) ; 133 menu.AddItem( 'Unlink' , FCKLang.RemoveLink , 35 ) ; 134 } 135 }} ; 136 137 case 'Image' : 138 return { 139 AddItems : function( menu, tag, tagName ) 140 { 141 if ( tagName == 'IMG' && !tag.getAttribute( '_fckfakelement' ) ) 142 { 143 menu.AddSeparator() ; 144 menu.AddItem( 'Image', FCKLang.ImageProperties, 37 ) ; 145 } 146 }} ; 147 148 case 'Anchor' : 149 return { 150 AddItems : function( menu, tag, tagName ) 151 { 152 // Go up to the anchor to test its properties 153 var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ; 154 var bIsAnchor = ( oLink && oLink.name.length > 0 ) ; 155 156 if ( bIsAnchor || ( tagName == 'IMG' && tag.getAttribute( '_fckanchor' ) ) ) 157 { 158 menu.AddSeparator() ; 159 menu.AddItem( 'Anchor', FCKLang.AnchorProp, 36 ) ; 160 menu.AddItem( 'AnchorDelete', FCKLang.AnchorDelete ) ; 161 } 162 }} ; 163 164 case 'Flash' : 165 return { 166 AddItems : function( menu, tag, tagName ) 167 { 168 if ( tagName == 'IMG' && tag.getAttribute( '_fckflash' ) ) 169 { 170 menu.AddSeparator() ; 171 menu.AddItem( 'Flash', FCKLang.FlashProperties, 38 ) ; 172 } 173 }} ; 174 175 case 'Form' : 176 return { 177 AddItems : function( menu, tag, tagName ) 178 { 179 if ( FCKSelection.HasAncestorNode('FORM') ) 180 { 181 menu.AddSeparator() ; 182 menu.AddItem( 'Form', FCKLang.FormProp, 48 ) ; 183 } 184 }} ; 185 186 case 'Checkbox' : 187 return { 188 AddItems : function( menu, tag, tagName ) 189 { 190 if ( tagName == 'INPUT' && tag.type == 'checkbox' ) 191 { 192 menu.AddSeparator() ; 193 menu.AddItem( 'Checkbox', FCKLang.CheckboxProp, 49 ) ; 194 } 195 }} ; 196 197 case 'Radio' : 198 return { 199 AddItems : function( menu, tag, tagName ) 200 { 201 if ( tagName == 'INPUT' && tag.type == 'radio' ) 202 { 203 menu.AddSeparator() ; 204 menu.AddItem( 'Radio', FCKLang.RadioButtonProp, 50 ) ; 205 } 206 }} ; 207 208 case 'TextField' : 209 return { 210 AddItems : function( menu, tag, tagName ) 211 { 212 if ( tagName == 'INPUT' && ( tag.type == 'text' || tag.type == 'password' ) ) 213 { 214 menu.AddSeparator() ; 215 menu.AddItem( 'TextField', FCKLang.TextFieldProp, 51 ) ; 216 } 217 }} ; 218 219 case 'HiddenField' : 220 return { 221 AddItems : function( menu, tag, tagName ) 222 { 223 if ( tagName == 'IMG' && tag.getAttribute( '_fckinputhidden' ) ) 224 { 225 menu.AddSeparator() ; 226 menu.AddItem( 'HiddenField', FCKLang.HiddenFieldProp, 56 ) ; 227 } 228 }} ; 229 230 case 'ImageButton' : 231 return { 232 AddItems : function( menu, tag, tagName ) 233 { 234 if ( tagName == 'INPUT' && tag.type == 'image' ) 235 { 236 menu.AddSeparator() ; 237 menu.AddItem( 'ImageButton', FCKLang.ImageButtonProp, 55 ) ; 238 } 239 }} ; 240 241 case 'Button' : 242 return { 243 AddItems : function( menu, tag, tagName ) 244 { 245 if ( tagName == 'INPUT' && ( tag.type == 'button' || tag.type == 'submit' || tag.type == 'reset' ) ) 246 { 247 menu.AddSeparator() ; 248 menu.AddItem( 'Button', FCKLang.ButtonProp, 54 ) ; 249 } 250 }} ; 251 252 case 'Select' : 253 return { 254 AddItems : function( menu, tag, tagName ) 255 { 256 if ( tagName == 'SELECT' ) 257 { 258 menu.AddSeparator() ; 259 menu.AddItem( 'Select', FCKLang.SelectionFieldProp, 53 ) ; 260 } 261 }} ; 262 263 case 'Textarea' : 264 return { 265 AddItems : function( menu, tag, tagName ) 266 { 267 if ( tagName == 'TEXTAREA' ) 268 { 269 menu.AddSeparator() ; 270 menu.AddItem( 'Textarea', FCKLang.TextareaProp, 52 ) ; 271 } 272 }} ; 273 274 case 'BulletedList' : 275 return { 276 AddItems : function( menu, tag, tagName ) 277 { 278 if ( FCKSelection.HasAncestorNode('UL') ) 279 { 280 menu.AddSeparator() ; 281 menu.AddItem( 'BulletedList', FCKLang.BulletedListProp, 27 ) ; 282 } 283 }} ; 284 285 case 'NumberedList' : 286 return { 287 AddItems : function( menu, tag, tagName ) 288 { 289 if ( FCKSelection.HasAncestorNode('OL') ) 290 { 291 menu.AddSeparator() ; 292 menu.AddItem( 'NumberedList', FCKLang.NumberedListProp, 26 ) ; 293 } 294 }} ; 295 } 296 return null ; 297} 298 299function FCK_ContextMenu_OnBeforeOpen() 300{ 301 // Update the UI. 302 FCK.Events.FireEvent( 'OnSelectionChange' ) ; 303 304 // Get the actual selected tag (if any). 305 var oTag, sTagName ; 306 307 // The extra () is to avoid a warning with strict error checking. This is ok. 308 if ( (oTag = FCKSelection.GetSelectedElement()) ) 309 sTagName = oTag.tagName ; 310 311 // Cleanup the current menu items. 312 var oMenu = FCK.ContextMenu._InnerContextMenu ; 313 oMenu.RemoveAllItems() ; 314 315 // Loop through the listeners. 316 var aListeners = FCK.ContextMenu.Listeners ; 317 for ( var i = 0 ; i < aListeners.length ; i++ ) 318 aListeners[i].AddItems( oMenu, oTag, sTagName ) ; 319} 320 321function FCK_ContextMenu_OnItemClick( item ) 322{ 323 FCK.Focus() ; 324 FCKCommands.GetCommand( item.Name ).Execute() ; 325} 326