]>
Commit | Line | Data |
---|---|---|
3332bebe | 1 | /**\r |
317f8f8f | 2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r |
3332bebe IB |
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license\r |
4 | */\r | |
5 | \r | |
6 | CKEDITOR.plugins.add( 'contextmenu', {\r | |
7 | requires: 'menu',\r | |
8 | \r | |
9 | // jscs:disable maximumLineLength\r | |
317f8f8f | 10 | lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,es-mx,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r |
3332bebe IB |
11 | // jscs:enable maximumLineLength\r |
12 | \r | |
317f8f8f | 13 | // Make sure the base class (CKEDITOR.menu) is loaded before it (http://dev.ckeditor.com/ticket/3318).\r |
3332bebe IB |
14 | onLoad: function() {\r |
15 | /**\r | |
16 | * Class replacing the non-configurable native context menu with a configurable CKEditor's equivalent.\r | |
17 | *\r | |
18 | * @class\r | |
19 | * @extends CKEDITOR.menu\r | |
20 | */\r | |
21 | CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass( {\r | |
22 | base: CKEDITOR.menu,\r | |
23 | \r | |
24 | /**\r | |
25 | * Creates the CKEDITOR.plugins.contextMenu class instance.\r | |
26 | *\r | |
27 | * @constructor\r | |
28 | * @param {CKEDITOR.editor} editor\r | |
29 | */\r | |
30 | $: function( editor ) {\r | |
31 | this.base.call( this, editor, {\r | |
32 | panel: {\r | |
33 | className: 'cke_menu_panel',\r | |
34 | attributes: {\r | |
35 | 'aria-label': editor.lang.contextmenu.options\r | |
36 | }\r | |
37 | }\r | |
38 | } );\r | |
39 | },\r | |
40 | \r | |
41 | proto: {\r | |
42 | /**\r | |
43 | * Starts watching on native context menu triggers (<kbd>Option</kbd> key, right click) on the given element.\r | |
44 | *\r | |
45 | * @param {CKEDITOR.dom.element} element\r | |
46 | * @param {Boolean} [nativeContextMenuOnCtrl] Whether to open native context menu if the\r | |
47 | * <kbd>Ctrl</kbd> key is held on opening the context menu. See {@link CKEDITOR.config#browserContextMenuOnCtrl}.\r | |
48 | */\r | |
49 | addTarget: function( element, nativeContextMenuOnCtrl ) {\r | |
50 | element.on( 'contextmenu', function( event ) {\r | |
51 | var domEvent = event.data,\r | |
52 | isCtrlKeyDown =\r | |
53 | // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event,\r | |
317f8f8f | 54 | // which make this property unreliable. (http://dev.ckeditor.com/ticket/4826)\r |
3332bebe IB |
55 | ( CKEDITOR.env.webkit ? holdCtrlKey : ( CKEDITOR.env.mac ? domEvent.$.metaKey : domEvent.$.ctrlKey ) );\r |
56 | \r | |
57 | if ( nativeContextMenuOnCtrl && isCtrlKeyDown )\r | |
58 | return;\r | |
59 | \r | |
60 | // Cancel the browser context menu.\r | |
61 | domEvent.preventDefault();\r | |
62 | \r | |
317f8f8f | 63 | // Fix selection when non-editable element in Webkit/Blink (Mac) (http://dev.ckeditor.com/ticket/11306).\r |
3332bebe IB |
64 | if ( CKEDITOR.env.mac && CKEDITOR.env.webkit ) {\r |
65 | var editor = this.editor,\r | |
66 | contentEditableParent = new CKEDITOR.dom.elementPath( domEvent.getTarget(), editor.editable() ).contains( function( el ) {\r | |
67 | // Return when non-editable or nested editable element is found.\r | |
68 | return el.hasAttribute( 'contenteditable' );\r | |
69 | }, true ); // Exclude editor's editable.\r | |
70 | \r | |
71 | // Fake selection for non-editables only (to exclude nested editables).\r | |
72 | if ( contentEditableParent && contentEditableParent.getAttribute( 'contenteditable' ) == 'false' )\r | |
73 | editor.getSelection().fake( contentEditableParent );\r | |
74 | }\r | |
75 | \r | |
76 | var doc = domEvent.getTarget().getDocument(),\r | |
77 | offsetParent = domEvent.getTarget().getDocument().getDocumentElement(),\r | |
78 | fromFrame = !doc.equals( CKEDITOR.document ),\r | |
79 | scroll = doc.getWindow().getScrollPosition(),\r | |
80 | offsetX = fromFrame ? domEvent.$.clientX : domEvent.$.pageX || scroll.x + domEvent.$.clientX,\r | |
81 | offsetY = fromFrame ? domEvent.$.clientY : domEvent.$.pageY || scroll.y + domEvent.$.clientY;\r | |
82 | \r | |
83 | CKEDITOR.tools.setTimeout( function() {\r | |
84 | this.open( offsetParent, null, offsetX, offsetY );\r | |
85 | \r | |
317f8f8f | 86 | // IE needs a short while to allow selection change before opening menu. (http://dev.ckeditor.com/ticket/7908)\r |
3332bebe IB |
87 | }, CKEDITOR.env.ie ? 200 : 0, this );\r |
88 | }, this );\r | |
89 | \r | |
90 | if ( CKEDITOR.env.webkit ) {\r | |
91 | var holdCtrlKey,\r | |
92 | onKeyDown = function( event ) {\r | |
93 | holdCtrlKey = CKEDITOR.env.mac ? event.data.$.metaKey : event.data.$.ctrlKey;\r | |
94 | },\r | |
95 | resetOnKeyUp = function() {\r | |
96 | holdCtrlKey = 0;\r | |
97 | };\r | |
98 | \r | |
99 | element.on( 'keydown', onKeyDown );\r | |
100 | element.on( 'keyup', resetOnKeyUp );\r | |
101 | element.on( 'contextmenu', resetOnKeyUp );\r | |
102 | }\r | |
103 | },\r | |
104 | \r | |
105 | /**\r | |
106 | * Opens the context menu in the given location. See the {@link CKEDITOR.menu#show} method.\r | |
107 | *\r | |
108 | * @param {CKEDITOR.dom.element} offsetParent\r | |
109 | * @param {Number} [corner]\r | |
110 | * @param {Number} [offsetX]\r | |
111 | * @param {Number} [offsetY]\r | |
112 | */\r | |
113 | open: function( offsetParent, corner, offsetX, offsetY ) {\r | |
317f8f8f IB |
114 | if ( this.editor.config.enableContextMenu === false ) {\r |
115 | return;\r | |
116 | }\r | |
117 | \r | |
3332bebe IB |
118 | this.editor.focus();\r |
119 | offsetParent = offsetParent || CKEDITOR.document.getDocumentElement();\r | |
120 | \r | |
317f8f8f | 121 | // http://dev.ckeditor.com/ticket/9362: Force selection check to update commands' states in the new context.\r |
3332bebe IB |
122 | this.editor.selectionChange( 1 );\r |
123 | \r | |
124 | this.show( offsetParent, corner, offsetX, offsetY );\r | |
125 | }\r | |
126 | }\r | |
127 | } );\r | |
128 | },\r | |
129 | \r | |
130 | beforeInit: function( editor ) {\r | |
131 | /**\r | |
132 | * @readonly\r | |
133 | * @property {CKEDITOR.plugins.contextMenu} contextMenu\r | |
134 | * @member CKEDITOR.editor\r | |
135 | */\r | |
136 | var contextMenu = editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor );\r | |
137 | \r | |
138 | editor.on( 'contentDom', function() {\r | |
139 | contextMenu.addTarget( editor.editable(), editor.config.browserContextMenuOnCtrl !== false );\r | |
140 | } );\r | |
141 | \r | |
142 | editor.addCommand( 'contextMenu', {\r | |
143 | exec: function() {\r | |
144 | editor.contextMenu.open( editor.document.getBody() );\r | |
145 | }\r | |
146 | } );\r | |
147 | \r | |
148 | editor.setKeystroke( CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' );\r | |
149 | editor.setKeystroke( CKEDITOR.CTRL + CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' );\r | |
150 | }\r | |
151 | } );\r | |
152 | \r | |
153 | /**\r | |
154 | * Whether to show the browser native context menu when the <kbd>Ctrl</kbd> or\r | |
155 | * <kbd>Meta</kbd> (Mac) key is pressed on opening the context menu with the\r | |
156 | * right mouse button click or the <kbd>Menu</kbd> key.\r | |
157 | *\r | |
158 | * config.browserContextMenuOnCtrl = false;\r | |
159 | *\r | |
160 | * @since 3.0.2\r | |
161 | * @cfg {Boolean} [browserContextMenuOnCtrl=true]\r | |
162 | * @member CKEDITOR.config\r | |
163 | */\r | |
317f8f8f IB |
164 | \r |
165 | /**\r | |
166 | * Whether to enable the context menu. Regardless of the setting the [Context Menu](http://ckeditor.com/addon/contextmenu)\r | |
167 | * plugin is still loaded.\r | |
168 | *\r | |
169 | * config.enableContextMenu = false;\r | |
170 | *\r | |
171 | * @since 4.7.0\r | |
172 | * @cfg {Boolean} [enableContextMenu=true]\r | |
173 | * @member CKEDITOR.config\r | |
174 | */\r |