plugin.js 5.7 KB

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