Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Bypass click/mouse handlers for any contenteditable elements #9491

Closed
wants to merge 10 commits into from

Conversation

hanthomas
Copy link

@hanthomas hanthomas commented Sep 1, 2016

Fixes issues #9414 and #5937. I can't see any reason why ngMaterial would need to hijack clicks for elements that have contenteditable attribute set.

Fixes issues 9414 and 5937.  I can't see any reason why ngMaterial would need to hijack clicks for elements that have contenteditable attribute set.
@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

1 similar comment
@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

@hanthomas
Copy link
Author

I signed it!

@hanthomas hanthomas closed this Sep 1, 2016
@hanthomas hanthomas reopened this Sep 1, 2016
@hanthomas
Copy link
Author

I signed it!

@googlebot
Copy link

CLAs look good, thanks!

1 similar comment
@googlebot
Copy link

CLAs look good, thanks!

@ThomasBurleson
Copy link
Contributor

Pending/related to HammerJS efforts.

@ThomasBurleson
Copy link
Contributor

@hanthomas - please add 1 or more unit tests.

@ThomasBurleson ThomasBurleson added the needs: unit tests This PR needs unit tests to cover the changes being proposed label Sep 7, 2016
@ThomasBurleson ThomasBurleson added this to the 1.2.0 milestone Sep 7, 2016
@hanthomas
Copy link
Author

@ThomasBurleson - Unit tests have been added to gesture.spec.js.

// Click tests should only be enabled when `$$hijackClicks == true` (for mobile)

it('should not hijack click on contenteditable element', inject(function($document, $mdGesture) {
if ( $mdGesture.$$hijackClicks ) {
Copy link
Member

Choose a reason for hiding this comment

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

Where does this property exist? Never saw this one in our gesture service.

Also the tests should enable hijacking by default.

Copy link
Author

Choose a reason for hiding this comment

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

Hmm... you're right. I used one of the existing tests as a template, but apparently that property no longer exists. I'll make the correction.

}));

it('should not hijack mousedown/mouseup on contenteditable element', inject(function($document, $mdGesture) {
if ( $mdGesture.$$hijackClicks ) {
Copy link
Member

Choose a reason for hiding this comment

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

Same for here

Copy link
Author

Choose a reason for hiding this comment

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

See reply to previous comment

var spy2 = jasmine.createSpy('mouseup');
var el = angular.element('<div contenteditable>');

el.on('mousedown', spy1);
Copy link
Member

Choose a reason for hiding this comment

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

Where do you actually trigger the event? The tests seem to pass because you created that $$hijackClicks check, which always doesn't pass

Copy link
Author

Choose a reason for hiding this comment

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

True. So, once I take that condition out, it should pass if the mousedown and mouseup handlers are triggered.

Copy link
Member

Choose a reason for hiding this comment

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

I think it gets more difficult for this tests.

You need the element you want to trigger the mouse event on to the document.body to be able to test it with $mdGesture.

Then you need to dispatch a fake mouse event and determine if the triggered event from the event handlers is the same as the fake mouse event.

Copy link
Author

Choose a reason for hiding this comment

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

You're right... plus, now the tests fail. So, it looks like I have some work to do on this. Thanks for the explanation.

@ThomasBurleson ThomasBurleson added the in progress Mainly for in progress PRs, but may be used for issues that require multiple PRs label Sep 15, 2016
@hanthomas
Copy link
Author

@devversion - It took a few tries, but I think the unit tests are correct now. My basic approach was to make sure that ngMaterial allows the mouse events to be processed by the handler attached to the element instead of the click hijacker.

var el;

beforeEach(function() {
inject(function($mdGesture) {
Copy link
Member

Choose a reason for hiding this comment

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

You can simplify this

beforeEach(inject(function($mdGesture) {
}));

});

it('should not hijack click on contenteditable element', inject(function($document, $mdGesture) {
$document.triggerHandler('$$mdGestureReset');
Copy link
Member

Choose a reason for hiding this comment

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

Move this to the beforeEach, since you are repeating it for each test


el.triggerHandler('click');

expect(spyClick).toHaveBeenCalled();
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't those checks also check for the event to not being prevented.

// Something like this
var event = spyClick.calls.mostRecent().args[0];
bool = event.defaultPrevented

@devversion devversion removed the needs: unit tests This PR needs unit tests to cover the changes being proposed label Oct 1, 2016
@devversion
Copy link
Member

I will close that PR for now, because this is not a high priority on our queue right now, because it is planned to get rid of the $mdGesture service in the future (See #9362).

Anyways, Thanks for the PR!

@devversion devversion closed this Oct 10, 2016
@kmturley
Copy link

kmturley commented Apr 28, 2017

This issue also affects regular elements when using angular-material for other elements on the same page. Using this code fixes it: function mouseInputHijacker(ev) { var isKeyClick = !ev.clientX && !ev.clientY; if (!isKeyClick && !ev.$material && !ev.isIonicTap && !isInputEventFromLabelClick(ev) && !ev.target.nodeName === 'SELECT') { ev.preventDefault(); ev.stopPropagation(); } } Would be good to have a directive to disable click hijacking on specific elements

@Splaktar Splaktar modified the milestones: 1.2.0, 1.1.6 Nov 18, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
in progress Mainly for in progress PRs, but may be used for issues that require multiple PRs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants