diff options
Diffstat (limited to 'sources/plugins/contextmenu/plugin.js')
-rw-r--r-- | sources/plugins/contextmenu/plugin.js | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/sources/plugins/contextmenu/plugin.js b/sources/plugins/contextmenu/plugin.js new file mode 100644 index 0000000..6cd3935 --- /dev/null +++ b/sources/plugins/contextmenu/plugin.js | |||
@@ -0,0 +1,159 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | CKEDITOR.plugins.add( 'contextmenu', { | ||
7 | requires: 'menu', | ||
8 | |||
9 | // jscs:disable maximumLineLength | ||
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,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% | ||
11 | // jscs:enable maximumLineLength | ||
12 | |||
13 | // Make sure the base class (CKEDITOR.menu) is loaded before it (#3318). | ||
14 | onLoad: function() { | ||
15 | /** | ||
16 | * Class replacing the non-configurable native context menu with a configurable CKEditor's equivalent. | ||
17 | * | ||
18 | * @class | ||
19 | * @extends CKEDITOR.menu | ||
20 | */ | ||
21 | CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass( { | ||
22 | base: CKEDITOR.menu, | ||
23 | |||
24 | /** | ||
25 | * Creates the CKEDITOR.plugins.contextMenu class instance. | ||
26 | * | ||
27 | * @constructor | ||
28 | * @param {CKEDITOR.editor} editor | ||
29 | */ | ||
30 | $: function( editor ) { | ||
31 | this.base.call( this, editor, { | ||
32 | panel: { | ||
33 | className: 'cke_menu_panel', | ||
34 | attributes: { | ||
35 | 'aria-label': editor.lang.contextmenu.options | ||
36 | } | ||
37 | } | ||
38 | } ); | ||
39 | }, | ||
40 | |||
41 | proto: { | ||
42 | /** | ||
43 | * Starts watching on native context menu triggers (<kbd>Option</kbd> key, right click) on the given element. | ||
44 | * | ||
45 | * @param {CKEDITOR.dom.element} element | ||
46 | * @param {Boolean} [nativeContextMenuOnCtrl] Whether to open native context menu if the | ||
47 | * <kbd>Ctrl</kbd> key is held on opening the context menu. See {@link CKEDITOR.config#browserContextMenuOnCtrl}. | ||
48 | */ | ||
49 | addTarget: function( element, nativeContextMenuOnCtrl ) { | ||
50 | element.on( 'contextmenu', function( event ) { | ||
51 | var domEvent = event.data, | ||
52 | isCtrlKeyDown = | ||
53 | // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event, | ||
54 | // which make this property unreliable. (#4826) | ||
55 | ( CKEDITOR.env.webkit ? holdCtrlKey : ( CKEDITOR.env.mac ? domEvent.$.metaKey : domEvent.$.ctrlKey ) ); | ||
56 | |||
57 | if ( nativeContextMenuOnCtrl && isCtrlKeyDown ) | ||
58 | return; | ||
59 | |||
60 | // Cancel the browser context menu. | ||
61 | domEvent.preventDefault(); | ||
62 | |||
63 | // Fix selection when non-editable element in Webkit/Blink (Mac) (#11306). | ||
64 | if ( CKEDITOR.env.mac && CKEDITOR.env.webkit ) { | ||
65 | var editor = this.editor, | ||
66 | contentEditableParent = new CKEDITOR.dom.elementPath( domEvent.getTarget(), editor.editable() ).contains( function( el ) { | ||
67 | // Return when non-editable or nested editable element is found. | ||
68 | return el.hasAttribute( 'contenteditable' ); | ||
69 | }, true ); // Exclude editor's editable. | ||
70 | |||
71 | // Fake selection for non-editables only (to exclude nested editables). | ||
72 | if ( contentEditableParent && contentEditableParent.getAttribute( 'contenteditable' ) == 'false' ) | ||
73 | editor.getSelection().fake( contentEditableParent ); | ||
74 | } | ||
75 | |||
76 | var doc = domEvent.getTarget().getDocument(), | ||
77 | offsetParent = domEvent.getTarget().getDocument().getDocumentElement(), | ||
78 | fromFrame = !doc.equals( CKEDITOR.document ), | ||
79 | scroll = doc.getWindow().getScrollPosition(), | ||
80 | offsetX = fromFrame ? domEvent.$.clientX : domEvent.$.pageX || scroll.x + domEvent.$.clientX, | ||
81 | offsetY = fromFrame ? domEvent.$.clientY : domEvent.$.pageY || scroll.y + domEvent.$.clientY; | ||
82 | |||
83 | CKEDITOR.tools.setTimeout( function() { | ||
84 | this.open( offsetParent, null, offsetX, offsetY ); | ||
85 | |||
86 | // IE needs a short while to allow selection change before opening menu. (#7908) | ||
87 | }, CKEDITOR.env.ie ? 200 : 0, this ); | ||
88 | }, this ); | ||
89 | |||
90 | if ( CKEDITOR.env.webkit ) { | ||
91 | var holdCtrlKey, | ||
92 | onKeyDown = function( event ) { | ||
93 | holdCtrlKey = CKEDITOR.env.mac ? event.data.$.metaKey : event.data.$.ctrlKey; | ||
94 | }, | ||
95 | resetOnKeyUp = function() { | ||
96 | holdCtrlKey = 0; | ||
97 | }; | ||
98 | |||
99 | element.on( 'keydown', onKeyDown ); | ||
100 | element.on( 'keyup', resetOnKeyUp ); | ||
101 | element.on( 'contextmenu', resetOnKeyUp ); | ||
102 | } | ||
103 | }, | ||
104 | |||
105 | /** | ||
106 | * Opens the context menu in the given location. See the {@link CKEDITOR.menu#show} method. | ||
107 | * | ||
108 | * @param {CKEDITOR.dom.element} offsetParent | ||
109 | * @param {Number} [corner] | ||
110 | * @param {Number} [offsetX] | ||
111 | * @param {Number} [offsetY] | ||
112 | */ | ||
113 | open: function( offsetParent, corner, offsetX, offsetY ) { | ||
114 | this.editor.focus(); | ||
115 | offsetParent = offsetParent || CKEDITOR.document.getDocumentElement(); | ||
116 | |||
117 | // #9362: Force selection check to update commands' states in the new context. | ||
118 | this.editor.selectionChange( 1 ); | ||
119 | |||
120 | this.show( offsetParent, corner, offsetX, offsetY ); | ||
121 | } | ||
122 | } | ||
123 | } ); | ||
124 | }, | ||
125 | |||
126 | beforeInit: function( editor ) { | ||
127 | /** | ||
128 | * @readonly | ||
129 | * @property {CKEDITOR.plugins.contextMenu} contextMenu | ||
130 | * @member CKEDITOR.editor | ||
131 | */ | ||
132 | var contextMenu = editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor ); | ||
133 | |||
134 | editor.on( 'contentDom', function() { | ||
135 | contextMenu.addTarget( editor.editable(), editor.config.browserContextMenuOnCtrl !== false ); | ||
136 | } ); | ||
137 | |||
138 | editor.addCommand( 'contextMenu', { | ||
139 | exec: function() { | ||
140 | editor.contextMenu.open( editor.document.getBody() ); | ||
141 | } | ||
142 | } ); | ||
143 | |||
144 | editor.setKeystroke( CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ); | ||
145 | editor.setKeystroke( CKEDITOR.CTRL + CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' ); | ||
146 | } | ||
147 | } ); | ||
148 | |||
149 | /** | ||
150 | * Whether to show the browser native context menu when the <kbd>Ctrl</kbd> or | ||
151 | * <kbd>Meta</kbd> (Mac) key is pressed on opening the context menu with the | ||
152 | * right mouse button click or the <kbd>Menu</kbd> key. | ||
153 | * | ||
154 | * config.browserContextMenuOnCtrl = false; | ||
155 | * | ||
156 | * @since 3.0.2 | ||
157 | * @cfg {Boolean} [browserContextMenuOnCtrl=true] | ||
158 | * @member CKEDITOR.config | ||
159 | */ | ||