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

Conversation

bradrich
Copy link
Contributor

If both the clickOutsideToClose and propagateContainerEvents parameters are set to true within the panel configuration, then the panel will be closed when a click happens outside of the panel.

Fixes #9388

var found = false;
angular.forEach(elems, function(elem) {
if (elem === sourceElem) {
found = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

How about this? It quits early when it finds a match and removes the extra variable.

var findSourceEl = function(els, sourceEl) {
  for (var el, i = 0; el = els[i]; i++) {
    if (el === sourceEl) {
      return true;
    }
  });
  return false;
};


// We check if the sourceElem of the event is the panel element or one
// of it's children. If it is not, then close the panel.
var found = findSourceElem(
Copy link
Contributor

Choose a reason for hiding this comment

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

El instead of Elem. We use el throughout this file, so it's strange to switch naming conventions here.


openPanel(config);

clickOutsideOfPanel();
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be clickPanelContainer? Or can clickPanelContainer be updated so you're not duplicating logic. (The only thing that's changing is the element you're clicking on. Maybe something like this?

function clickPanelContainer(rootEl) {
  rootEl = rootEl || document.body;
  const selector = '.md-panel:not(._md-panel-backdrop)';
  angular.element(rootEl).find(selector).parent().simulate('click');
  angular.element(rootEl).find(selector).parent().simulate('mousedown');
  angular.element(rootEl).find(selector).parent().simulate('mouseup');
  flushPanel();
}

Benefits of this version is that you don't need the panelRef, which removes one of the if statements. I know this version can replace the current one and you won't need to change any tests.

or

function clickPanelContainer(container) {
    container = container || angular.element('.md-panel-outer-wrapper');

    container.triggerHandler({
      type: 'mousedown',
      target: container[0]
    });

    container.triggerHandler({
      type: 'mouseup',
      target: container[0]
    });

    flushPanel();
  }

@bradrich bradrich force-pushed the fix/clickOutsideToClose-with-propagateContainerEvents branch from 639cdaf to f0ad663 Compare October 21, 2016 20:31

// We check if the sourceEl of the event is the panel element or one
// of it's children. If it is not, then close the panel.
var found = findSourceEl(
Copy link
Member

Choose a reason for hiding this comment

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

You could simplify it and avoid the loop if you did something like this:

var found = sourceEl === self.panelEl[0] || self.panelEl[0].contains(sourceEl);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was looking for the .contains() method and didn't realize that I would have to access the element to get to it. Good catch and I appreciate you showing it to me.

clickOutsideToClose: true
};

openPanel(config);
Copy link
Member

Choose a reason for hiding this comment

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

It might make the test slightly more robust if you had a check that the PANEL_EL exists, right after opening it. This should avoid cases where the test will pass, if the openPanel function didn't open it up for some reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The open panel result is pretty well tested in the tests that proceed this one. You will also notice in the test right before this one, should close when clickOutsideToClose set to true does not expect the PANEL_EL to exist before it expects it to be closed. I went with that understanding to write this one.

Copy link
Member

Choose a reason for hiding this comment

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

While it's true that the opening logic is well tested, we should try to keep the tests as independent as possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

@crisbeto I go back and forth on this one. Because the open existence is tested earlier, we get a better test signal when opens fails because the failure is in the test that tests open. If we write it in every test, then all will fail and the messages don't point to the actual problem.

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't say it's necessary for every test, but it makes sense for this one since the test would fail if there isn't an open panel. This may be down to personal preference, though.

if (!panelRef) {
return;
}

var container = panelRef.panelContainer;
var container = container || panelRef.panelContainer;
Copy link
Member

Choose a reason for hiding this comment

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

It's a bad practise to have variables with the same name as function arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should actually read as container = container || panelRef.panelContainer. I forgot to remove the var before it.

Copy link
Member

Choose a reason for hiding this comment

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

Alright, it makes sense without the var.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ThomasBurleson I think that there was some confusion as we extended this function. Previously, the container variable was declared internally and assigned to the panelRef.panelContainer. Now, you are able to pass in a container to click on. But, if you don't pass one in, it needs to still assign it to the default panelRef.panelContainer.

@bradrich bradrich force-pushed the fix/clickOutsideToClose-with-propagateContainerEvents branch from f0ad663 to 360d631 Compare October 24, 2016 13:48
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@bradrich bradrich force-pushed the fix/clickOutsideToClose-with-propagateContainerEvents branch from 360d631 to 1f18e4c Compare October 24, 2016 14:03
Copy link
Contributor

@ErinCoughlan ErinCoughlan left a comment

Choose a reason for hiding this comment

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

LGTM

clickOutsideToClose: true
};

openPanel(config);
Copy link
Contributor

Choose a reason for hiding this comment

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

@crisbeto I go back and forth on this one. Because the open existence is tested earlier, we get a better test signal when opens fails because the failure is in the test that tests open. If we write it in every test, then all will fail and the messages don't point to the actual problem.


openPanel(config);

clickPanelContainer(angular.element(document.body));
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you move the angular.element part to the clickPanelContainer? I don't think it particularly matters for this test, so it seems to fit better in the helper method.

I'm wondering if we want something like getElement to make this more flexible.

function getElement(el) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Went ahead and added this one, as I thought that it was a more extended implementation and useful.

…Events

If both the `clickOutsideToClose` and `propagateContainerEvents`
parameters are set to true within the panel configuration, then the
panel will be closed when a click happens outside of the panel.

Fixes angular#9388
@bradrich bradrich force-pushed the fix/clickOutsideToClose-with-propagateContainerEvents branch from 1f18e4c to 76bb9b6 Compare October 24, 2016 18:34
@bradrich
Copy link
Contributor Author

@ThomasBurleson This is ready for merge.

@bradrich
Copy link
Contributor Author

bradrich commented Nov 2, 2016

@ThomasBurleson Checking on the status of this PR.

@kara kara added pr: merge ready This PR is ready for a caretaker to review and removed needs: presubmit labels Nov 17, 2016
@kara kara merged commit 61bd95e into angular:master Nov 17, 2016
@angular angular locked as resolved and limited conversation to collaborators Mar 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pr: merge ready This PR is ready for a caretaker to review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mdPanel -allow clickOutsideToClose works with propagateContainerEvents
6 participants