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