Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for activating various UI items via right click #2859

Merged
merged 56 commits into from
Jul 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
69d1f88
Add unit test for IE/Edge.
Comandeer Feb 24, 2019
64f7649
Add manual test.
Comandeer Feb 24, 2019
404c655
Add fix for IE/Edge.
Comandeer Feb 24, 2019
2567a34
Update manual test.
Comandeer Feb 24, 2019
f7bddde
Add info about clicked mouse button to bot.combo.
Comandeer Feb 24, 2019
ce65b39
Add unit test for listblock.
Comandeer Feb 24, 2019
d5df7a6
Add manual test for listblock.
Comandeer Feb 24, 2019
8af2047
Update manual test for rich combo.
Comandeer Feb 24, 2019
9c4c85f
Refactor older test.
Comandeer Feb 24, 2019
93a3b55
Add additional check for left mouse button in listblock.
Comandeer Feb 24, 2019
ba1e65a
Add unit test for fireElementEventHandler.
Comandeer Feb 24, 2019
a50d55d
Add CKEDITOR.tools.fireElementEventHandler.
Comandeer Feb 24, 2019
b99dde8
Add unit test for key handling in panel.
Comandeer Feb 24, 2019
77cb30b
Force passing info about clicked button.
Comandeer Feb 24, 2019
e6d47c5
Update manual test for listblock.
Comandeer Feb 24, 2019
24ae1fa
Update unit test for listblock.
Comandeer Feb 24, 2019
5e2642b
Move dispatchMouseEvent to bender.tools.
Comandeer Feb 24, 2019
6c34155
Move fireElementEventHandler to CKEDITOR.tools.
Comandeer Feb 24, 2019
7c239a2
Add unit test for menu.
Comandeer Feb 24, 2019
d4ccc53
Add manual test for menu.
Comandeer Feb 24, 2019
73d4258
Add fix for menu.
Comandeer Feb 24, 2019
5bc06ac
Update issue references in code.
Comandeer Feb 24, 2019
98df83a
Update unit test for panel.
Comandeer Feb 24, 2019
b42824e
Add test for firing events in foreign documents.
Comandeer Feb 24, 2019
74fec6c
Use element's owner document when firing event.
Comandeer Feb 24, 2019
fd710d0
Update manual test for menu.
Comandeer Feb 24, 2019
f05d8c4
Update API docs for CKEDITOR.tools.fireElementEventHandler.
Comandeer Feb 24, 2019
4a1f813
Add basic support for QM/CM.
Comandeer Feb 24, 2019
ce7e568
Remove commented, unnecessary code.
Comandeer Feb 24, 2019
2bfaccf
Move CKEDITOR.tools.fireElementEventHandler to CKEDITOR.dom.element#f…
Comandeer Mar 23, 2019
2f3f883
Add CKEDITOR.tools.normalizeMouseButton.
Comandeer Mar 23, 2019
2f82962
Update manual test for menu plugin.
Comandeer Mar 23, 2019
e93525c
Add reversed normalization of mouse button.
Comandeer Mar 23, 2019
415ba5e
Introduce normalization in tests.
Comandeer Mar 23, 2019
155d4c9
Force dispatchMouseEvent to use appropriate document.
Comandeer Mar 23, 2019
8a0b2fb
Improve API docs.
Comandeer Mar 23, 2019
20e2338
Simplify normalizeMouseButton implementation.
Comandeer Mar 23, 2019
4222fe1
Use event name if there is no handlerName property.
Comandeer Mar 25, 2019
45a7899
Fix incorrect test description.
Comandeer May 18, 2019
96b63c6
Small fixes for API docs.
Comandeer May 18, 2019
5ab8760
Update version tag.
Comandeer Jun 17, 2019
fce3190
Update API docs.
Comandeer Jun 17, 2019
c00a700
Refactoring conditions inside normalizeMouseButton.
Comandeer Jun 17, 2019
b2bd157
Update variable name.
Comandeer Jun 18, 2019
c7a00bd
Add manual test for keyboard integration in panel.
Comandeer Jun 18, 2019
a21c757
Update manual test for menu plugin.
Comandeer Jun 18, 2019
35dd0d9
Update version tags.
Comandeer Jul 11, 2019
21955d9
Removed rebase leftover.
jacekbogdanski Jul 12, 2019
12c5a2a
Reword result in manual test.
Comandeer Jul 16, 2019
fdc901b
Add info about bug in Firefox.
Comandeer Jul 16, 2019
e439b3e
Add sourcearea to menu manual test.
Comandeer Jul 16, 2019
74f814f
Update API docs for mouse button normalization.
Comandeer Jul 16, 2019
92cc8b7
Declare mappings only in IE.
Comandeer Jul 16, 2019
56701c8
Enhance spacing in onclick definitions.
Comandeer Jul 16, 2019
d80e9d1
Minor docs rewording. [skip ci]
f1ames Jul 31, 2019
428360d
Added changelog entry. [skip ci]
f1ames Jul 31, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ Fixed Issues:
* [#941](https://github.com/ckeditor/ckeditor-dev/issues/941): Fixed: Error is thrown after styling the text table cell selected using native selection when [Table Selection](https://ckeditor.com/cke4/addon/tableselection) is enabled.
* [#3261](https://github.com/ckeditor/ckeditor-dev/issues/3261): Fixed: [Widget](https://ckeditor.com/cke4/addon/widget) initialized using dialog has incorrect owner document.
* [#3198](https://github.com/ckeditor/ckeditor-dev/issues/3198): Fixed: Blurring and focusing editor when [widget](https://ckeditor.com/cke4/addon/widget) is focused creates additional undo step.
* [#2859](https://github.com/ckeditor/ckeditor-dev/pull/2859): [IE, Edge] Fixed: Various editor's UI elements react to right mouse button click:
* [#2845](https://github.com/ckeditor/ckeditor-dev/issues/2845): [Rich Combo](https://ckeditor.com/cke4/addon/richcombo).
* [#2857](https://github.com/ckeditor/ckeditor-dev/issues/2857): [List Block](https://ckeditor.com/cke4/addon/listblock).
* [#2858](https://github.com/ckeditor/ckeditor-dev/issues/2858): [Menu](https://ckeditor.com/cke4/addon/menu).

API Changes:

* [#3154](https://github.com/ckeditor/ckeditor-dev/issues/3154): Added the [`CKEDITOR.tools.array.some()`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_tools_array.html#method-some) method.
* [#3245](https://github.com/ckeditor/ckeditor-dev/issues/3245): Added the [`CKEDITOR.plugins.undo.UndoManager.addFilterRule()`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_plugins_undo_UndoManager.html#method-addFilterRule) method which allows filtering undo snapshots contents.
* [#2845](https://github.com/ckeditor/ckeditor-dev/issues/2845): Added the [`CKEDITOR.tools.normalizeMouseButton()`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_tools.html#method-normalizeMouseButton) method.
* [#2975](https://github.com/ckeditor/ckeditor-dev/issues/2975): Added the [`CKEDITOR.dom.element#fireEventHandler()`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_dom_element.html#method-fireEventHandler) method.

## CKEditor 4.12.1

Expand Down
35 changes: 35 additions & 0 deletions core/dom/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -2113,6 +2113,41 @@ CKEDITOR.dom.element.clearMarkers = function( database, element, removeFromDatab
else if ( !type || node.type == type )
callback( node );
}
},

/**
* Fires element event handler attribute e.g.
*
* ```html
* <button onkeydown="return customFn( event )">x</button>
* ```
*
* ```javascript
* buttonEl.fireEventHandler( 'keydown', {
* keyCode: 13 // Enter
* } );
* ```
*
* @since 4.13.0
* @param {CKEDITOR.dom.element/HTMLElement} element Element with attached event handler attribute.
* @param {String} eventName Event name.
* @param {Object} evt Event payload.
*/
fireEventHandler: function( eventName, evt ) {
var handlerName = 'on' + eventName,
nativeElement = this.$;

if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {
var nativeEvent = nativeElement.ownerDocument.createEventObject();

for ( var key in evt ) {
nativeEvent[ key ] = evt[ key ];
}

nativeElement.fireEvent( handlerName, nativeEvent );
} else {
nativeElement[ nativeElement[ eventName ] ? eventName : handlerName ]( evt );
}
}
} );

Expand Down
81 changes: 71 additions & 10 deletions core/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -1462,23 +1462,84 @@
* if the mouse button cannot be determined.
*/
getMouseButton: function( evt ) {
var domEvent = evt.data ? evt.data.$ : evt;
var domEvent = evt && evt.data ? evt.data.$ : evt;

if ( !domEvent ) {
return false;
}

if ( CKEDITOR.env.ie && ( CKEDITOR.env.version < 9 || CKEDITOR.env.ie6Compat ) ) {
if ( domEvent.button === 4 ) {
return CKEDITOR.MOUSE_BUTTON_MIDDLE;
} else if ( domEvent.button === 1 ) {
return CKEDITOR.MOUSE_BUTTON_LEFT;
} else {
return CKEDITOR.MOUSE_BUTTON_RIGHT;
}
return CKEDITOR.tools.normalizeMouseButton( domEvent.button );
},

/**
* Normalizes mouse buttons across browsers.
*
* Noticeably only Internet Explorer 8 and Internet Explorer 9 in Quirks Mode / Compatibility View
* have different buttons mappings than other browsers:
*
* ```
* +--------------+--------------------------+----------------+
* | Mouse button | IE 8 / IE 9 CM / IE 9 QM | Other browsers |
* +--------------+--------------------------+----------------+
* | Left | 1 | 0 |
* +--------------+--------------------------+----------------+
* | Middle | 4 | 1 |
* +--------------+--------------------------+----------------+
* | Right | 2 | 2 |
* +--------------+--------------------------+----------------+
* ```
*
* The normalization is conducted only in browsers that use non-standard button mappings,
* returning passed parameter in every other browser. Therefore values for IE < 9 are mapped
* to values used in the rest of the browsers. For example the below code in IE8 will return results as follows:
*
* ```js
* console.log( CKEDITOR.tools.normalizeMouseButton( 1 ) ); // 0
* console.log( CKEDITOR.tools.normalizeMouseButton( 4 ) ); // 1
* console.log( CKEDITOR.tools.normalizeMouseButton( 2 ) ); // 2
* ```
*
* While for the rest of the browsers it will simply return passed values.
*
* With the `reversed` parameter set to `true` values from the rest of the browsers
* are mapped to IE < 9 values in IE < 9 browsers. This means IE8 will return results as follows:
*
* ```js
* console.log( CKEDITOR.tools.normalizeMouseButton( 0, true ) ); // 1
* console.log( CKEDITOR.tools.normalizeMouseButton( 1, true ) ); // 4
* console.log( CKEDITOR.tools.normalizeMouseButton( 2, true ) ); // 2
* ```
*
* While for the rest of the browsers it will simply return passed values.
*
* @since 4.13.0
* @param {Number} button Mouse button identifier.
* @param {Boolean} [reverse=false] If set to true, the conversion is reversed: values
* returned by other browsers are converted to IE 8 values.
* @returns {Number} Normalized mouse button identifier.
f1ames marked this conversation as resolved.
Show resolved Hide resolved
*/
normalizeMouseButton: function( button, reverse ) {
if ( !CKEDITOR.env.ie || ( CKEDITOR.env.version >= 9 && !CKEDITOR.env.ie6Compat ) ) {
return button;
}

return domEvent.button;
var mappings = [
[ CKEDITOR.MOUSE_BUTTON_LEFT, 1 ],
[ CKEDITOR.MOUSE_BUTTON_MIDDLE, 4 ],
[ CKEDITOR.MOUSE_BUTTON_RIGHT, 2 ]
];

for ( var i = 0; i < mappings.length; i++ ) {
var mapping = mappings[ i ];

if ( mapping[ 0 ] === button && reverse ) {
return mapping[ 1 ];
}

if ( !reverse && mapping[ 1 ] === button ) {
return mapping[ 0 ];
}
}
},

/**
Expand Down
6 changes: 4 additions & 2 deletions plugins/listblock/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CKEDITOR.plugins.add( 'listblock', {
' draggable="false"' +
' ondragstart="return false;"' + // Draggable attribute is buggy on Firefox.
' href="javascript:void(\'{val}\')" ' +
' {onclick}="CKEDITOR.tools.callFunction({clickFn},\'{val}\'); return false;"' + // https://dev.ckeditor.com/ticket/188
' onclick="{onclick}CKEDITOR.tools.callFunction({clickFn},\'{val}\'); return false;"' + // https://dev.ckeditor.com/ticket/188
' role="option">' +
'{text}' +
'</a>' +
Expand Down Expand Up @@ -96,7 +96,9 @@ CKEDITOR.plugins.add( 'listblock', {
var data = {
id: id,
val: escapeSingleQuotes( CKEDITOR.tools.htmlEncodeAttr( value ) ),
onclick: CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick',
// Add check for left mouse button (#2857).
onclick: CKEDITOR.env.ie ?
'return false;" onmouseup="CKEDITOR.tools.getMouseButton(event)===CKEDITOR.MOUSE_BUTTON_LEFT&&' : '',
clickFn: this._.getClick(),
title: CKEDITOR.tools.htmlEncodeAttr( title || value ),
text: html || value
Expand Down
13 changes: 9 additions & 4 deletions plugins/menu/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ CKEDITOR.plugins.add( 'menu', {
' aria-haspopup="{hasPopup}"' +
' aria-disabled="{disabled}"' +
' {ariaChecked}' +
' draggable="false"';
' draggable="false"',
specialClickHandler = '';

// Some browsers don't cancel key events in the keydown but in the
// keypress.
Expand All @@ -108,11 +109,15 @@ CKEDITOR.plugins.add( 'menu', {
' ondragstart="return false;"' );
}

// We must block clicking with right mouse button (#2858).
if ( CKEDITOR.env.ie ) {
specialClickHandler = 'return false;" onmouseup="CKEDITOR.tools.getMouseButton(event)===CKEDITOR.MOUSE_BUTTON_LEFT&&';
Comandeer marked this conversation as resolved.
Show resolved Hide resolved
}

// https://dev.ckeditor.com/ticket/188
menuItemSource += ' onmouseover="CKEDITOR.tools.callFunction({hoverFn},{index});"' +
' onmouseout="CKEDITOR.tools.callFunction({moveOutFn},{index});" ' +
( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) +
'="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' +
' onmouseout="CKEDITOR.tools.callFunction({moveOutFn},{index});"' +
' onclick="' + specialClickHandler + 'CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' +
'>';
f1ames marked this conversation as resolved.
Show resolved Hide resolved

menuItemSource +=
Expand Down
8 changes: 6 additions & 2 deletions plugins/panel/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,12 @@
index = this._.focusIndex;
focusable = index >= 0 && this._.getItems().getItem( index );

if ( focusable )
focusable.$[ keyAction ] ? focusable.$[ keyAction ]() : focusable.$[ 'on' + keyAction ]();
if ( focusable ) {
// We must pass info about clicked button (#2857).
focusable.fireEventHandler( keyAction, {
button: CKEDITOR.tools.normalizeMouseButton( CKEDITOR.MOUSE_BUTTON_LEFT, true )
} );
}

return false;
}
Expand Down
13 changes: 9 additions & 4 deletions plugins/richcombo/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ CKEDITOR.plugins.add( 'richcombo', {
' hidefocus="true"' +
' role="button"' +
' aria-labelledby="{id}_label"' +
' aria-haspopup="listbox"';
' aria-haspopup="listbox"',
specialClickHandler = '';

// Some browsers don't cancel key events in the keydown but in the
// keypress.
Expand All @@ -34,11 +35,15 @@ CKEDITOR.plugins.add( 'richcombo', {
if ( CKEDITOR.env.gecko )
template += ' onblur="this.style.cssText = this.style.cssText;"';

// In IE/Edge right click opens rich combo (#2845).
if ( CKEDITOR.env.ie ) {
specialClickHandler = 'return false;" onmouseup="CKEDITOR.tools.getMouseButton(event)==CKEDITOR.MOUSE_BUTTON_LEFT&&';
}

template +=
' onkeydown="return CKEDITOR.tools.callFunction({keydownFn},event,this);"' +
' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);" ' +
( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + // https://dev.ckeditor.com/ticket/188
'="CKEDITOR.tools.callFunction({clickFn},this);return false;">' +
' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);"' +
' onclick="' + specialClickHandler + 'CKEDITOR.tools.callFunction({clickFn},this);return false;">' +
'<span id="{id}_text" class="cke_combo_text cke_combo_inlinelabel">{label}</span>' +
'<span class="cke_combo_open">' +
'<span class="cke_combo_arrow">' +
Expand Down
5 changes: 3 additions & 2 deletions tests/_benderjs/ckeditor/static/bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@

btnEl = CKEDITOR.document.getById( btn._.id );

bender.tools.fireElementEventHandler( btnEl, CKEDITOR.env.ie ? 'onmouseup' : 'onclick', { button: leftMouseButton } );
btnEl.fireEventHandler( CKEDITOR.env.ie ? 'mouseup' : 'click', { button: leftMouseButton } );

// combo panel opening is synchronous.
tc.wait();
Expand Down Expand Up @@ -227,6 +227,7 @@
var editor = this.editor,
combo = editor.ui.get( name ),
tc = this.testCase,
leftMouseButton = CKEDITOR.tools.normalizeMouseButton( CKEDITOR.MOUSE_BUTTON_LEFT, true ),
item;

editor.once( 'panelShow', function() {
Expand All @@ -242,7 +243,7 @@

item = CKEDITOR.document.getById( 'cke_' + combo.id );
item = item.getElementsByTag( 'a' ).getItem( 0 );
item.$[ CKEDITOR.env.ie ? 'onmouseup' : 'onclick' ]();
item.fireEventHandler( CKEDITOR.env.ie ? 'mouseup' : 'click', { button: leftMouseButton } );

// combo panel opening is synchronous.
tc.wait();
Expand Down
55 changes: 26 additions & 29 deletions tests/_benderjs/ckeditor/static/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -1218,34 +1218,6 @@
img.setAttribute( 'src', src + '?' + Math.random().toString( 16 ).substring( 2 ) );
},

/*
* Fires element event handler attribute e.g.
* ```html
* <button onkeydown="return customFn( event )">x</button>
* ```
*
* @param {CKEDITOR.dom.element/HTMLElement} element Element with attached event handler attribute.
* @param {String} eventName Event handler attribute name.
* @param {Object} evt Event payload.
*/
fireElementEventHandler: function( element, eventName, evt ) {
if ( element.$ ) {
element = element.$;
}

if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {
var nativeEvent = CKEDITOR.document.$.createEventObject();

for ( var key in evt ) {
nativeEvent[ key ] = evt[ key ];
}

element.fireEvent( eventName, nativeEvent );
} else {
element[ eventName ]( evt );
}
},

/**
* Creates test suite object for `bender.test` method from synchronous and asynchronous test cases.
* Asynchronous test must be a function which returns a promise and cannot poses wait-resume statements.
Expand Down Expand Up @@ -1280,8 +1252,33 @@
}

return tmp;
}
},

/**
* Fires specified mouse event on the given element.
*
* @param {CKEDITOR.dom.element/HTMLElement} element Element with attached event handler attribute.
* @param {String} eventName Event handler attribute name.
* @param {Number} button Mouse button to be used.
*/
dispatchMouseEvent: function( element, type, button ) {
var mouseEvent;
button = CKEDITOR.tools.normalizeMouseButton( button, true );
element = element.$;

// Thanks to http://help.dottoro.com/ljhlvomw.php
if ( document.createEventObject ) {
mouseEvent = element.ownerDocument.createEventObject();

mouseEvent.button = button;
element.fireEvent( 'on' + type, mouseEvent );
} else {
mouseEvent = document.createEvent( 'MouseEvent' );

mouseEvent.initMouseEvent( type, true, true, window, 0, 0, 0, 80, 20, false, false, false, false, button, null );
element.dispatchEvent( mouseEvent );
}
}
};

bender.tools.range = {
Expand Down
Loading