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

Fixed: Context menu is incorrectly positioned when opened with Shift-F10 #1627

Merged
merged 28 commits into from
Sep 4, 2018

Conversation

engineering-this
Copy link
Contributor

@engineering-this engineering-this commented Feb 8, 2018

What is the purpose of this pull request?

Bug fix

Does your PR contain necessary tests?

All patches which change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.

This PR contains

  • Unit tests
  • Manual tests

What changes did you make?

This fix branches from t/1498: pull request.

Whenever there is no offsetX or offsetY toolbar will appear next to selection.

Closes #1451

CHANGES.md Outdated
@@ -10,6 +10,7 @@ New Features:
* [#1365](https://github.com/ckeditor/ckeditor-dev/issues/1365): [File Browser](https://ckeditor.com/cke4/addon/filebrowser) plugin uses XHR requests by default.
* [#1399](https://github.com/ckeditor/ckeditor-dev/issues/1399): Added possibility to set [`CKEDITOR.config.startupFocus`](https://docs.ckeditor.com/ckeditor4/docs/#!/api/CKEDITOR.config-cfg-startupFocus) as `start` or `end` to specify where editor focus should be after initialization.
* [#1441](https://github.com/ckeditor/ckeditor-dev/issues/1441): [Magic Line](https://ckeditor.com/cke4/addon/magicline) line element can now be identified by `data-cke-magic-line="1"` attribute.
* [#1498](https://github.com/ckeditor/ckeditor-dev/issues/1498) : Added new method 'getClientRects()' to CKEDITOR.dom.range, which returns list of rects for each selected element.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's more API change than new feature.

/**
* Returns array with rectangles of areas covered by ranges. For each DOM element within range there is one rectangle, but it represents only part of element which is within range, not whole element.
*
* @since 4.9.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update version tag.

* Returns array with rectangles of areas covered by ranges. For each DOM element within range there is one rectangle, but it represents only part of element which is within range, not whole element.
*
* @since 4.9.0
* @returns {Array}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could introduce DOMRect abstract class to nicely describe, what is returned from this function or CKEDITOR.dom.element.getClientRect. Then we would have DOMRect[] instead of Array.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted this task to #1866.

return rect;
}

if ( this.document.$.getSelection !== undefined ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if more readable feature detection won't be better (e.g. range.getClientRects).


#### Right to left editors:
- The panel shows itself on the left side of selection.
g
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it shouldn't be here.

rect,
rtl = this._.dir == 'rtl';
if ( offsetX === undefined || offsetY === undefined ) {
rectList = this._.editor.getSelection().getRanges()[ 0 ].getClientRects( );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary space inside parentheses.

}

// Fallback helper for browsers that don't support native getClientRects()
function getRect( context ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This polyfill is not correct. It always return one range, but other browsers often return more, eg when selection is multiline.

@@ -0,0 +1,16 @@
@bender-tags: bug, 4.9.1, 1451
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update version tag.

@Comandeer
Copy link
Member

It seems that this issue is blocked on #1498.

@mlewand
Copy link
Contributor

mlewand commented Apr 17, 2018

Issue #1498 was merged to the 4.10.0 release, so this issue is no longer blocked.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd think of adding some unit tests, e.g. selecting several places in the editor and checking if position of the menu changes. Tests should also cover case, when there are no valid client rects for selection.

rect,
rtl = this._.dir == 'rtl';
if ( offsetX === undefined || offsetY === undefined ) {
rectList = this._.editor.getSelection().getRanges()[ 0 ].getClientRects();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to have also fallback for case when getClientRects return empty array (e.g. due to w3c/csswg-drafts#2514). Because now this code fails for programatically opened context menus:

var editor = CKEDITOR.instances.editor,
  range = editor.createRange(),
  element = editor.editable().getFirst();

range.setStart( element, CKEDITOR.POSITION_AFTER_START );
range.select();
editor.execCommand( 'contextMenu' );

When getting position of the selection is not possible, falling back to opening menu in position (0,0) seems reasonable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After recent changes to getClientRects it's highly unlikely to get empty array as rect list, however I will add this fallback in case of future changes to our or native getClientRects.

rectList,
rect,
rtl = this._.dir == 'rtl';
if ( offsetX === undefined || offsetY === undefined ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment referencing the issue.

@engineering-this
Copy link
Contributor Author

I've moved logic from floatpanel plugin to contextmenu.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Menu covers selected content:
screen shot 2018-05-28 at 12 33 31
IMO it should be located below it. It's easy to do after obtaining rect.

There is also missing unit test. It's easy to write it as it'd be basically calling a command.

offsetY = 0,
rect;

// #1451 when opening context menu via keystroke there is no offsetX and Y passed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format for such comments is different:

// Comment (#1451).

rect;

// #1451 when opening context menu via keystroke there is no offsetX and Y passed.
if ( data.from === 'keystrokeHandler' ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this command used in non-keyboard situations? If not, then this conditional seems unnecessary.

Probably it could be used also in programmatic way, but the question is: what are drawbacks of disabling positioning menu in such situation?

@mlewand mlewand added the review:easy Pull requests that can be reviewed by a Junior Developer before being reviewed by the Reviewer. label Jul 10, 2018
@Comandeer Comandeer changed the base branch from major to master July 20, 2018 12:32
@Comandeer
Copy link
Member

Rebased onto latest master.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behaviour of LTR editors is inconsistent with behaviour of RTL editors. In LTR case context menu is pinned to the right edge of the selection. In RTL context menu is also pinned to the right edge of the selection. The only difference is the direction in which menu opens:

Opened menu in LTR editor

Opened menu in RTL editor

IMO in RTL editor context menu should be pinned to the left edge of the selection.

I'm also wondering about behaviour of context menu with multirange selections, e.g. in table selection:

Opened menu inside selected table


editor.once( 'panelShow', function( evt ) {
setTimeout( function() {
resume();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All assertions should be inside resume callback. Otherwise tests will pass even if assertions themselves fail:

Tests passing even if assertions failed

};

var tests = {
'Opening context menu with keystroke': function( editor ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests' names should begin with "test".

@@ -0,0 +1,15 @@
@bender-tags: bug, 4.10, 1451
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update version tags.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Context menu is not correctly positioned for inline editors.

Additionally unit tests are failing when they are launched via Bender Dashboard.

@engineering-this
Copy link
Contributor Author

Context menu is not correctly positioned for inline editors.

It looks correct for me, except for the missing dir="rtl" attribute in second inline editor element.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@Comandeer Comandeer merged commit 317b819 into next Sep 4, 2018
@Comandeer Comandeer deleted the t/1451 branch September 4, 2018 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review:easy Pull requests that can be reviewed by a Junior Developer before being reviewed by the Reviewer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants