CloudMade/Leaflet — pull request #373 by chosak (2011-11-22 16:12:13+00:00)
Title: Add map events for popup open/close

I'm building an application where there are numerous markers on a map. When each marker is clicked, I want a popup to open, but I also want other things to happen. For example, I'd like all of the other markers to fade out, and have a sidebar in my page that gives details about the selected marker. When the popup is closed, I want for the map to revert to its normal state.

In order to accomplish this, I need to be able to hook into the popup open/close events. This is trickier than it initially seems, because there are multiple ways that a popup may be closed:

1. User clicks on the map

Here, closing the popup happens because the ```Popup.onAdd``` method has hooked up an event handler to ```Map.preclick```. This event handler calls ```Popup._close``` which in turn calls ```Map.removeLayer``` to actually remove the popup layer from the map.

2. User clicks on another popup

Here, closing the popup happens because the ```Map.openPopup``` method automatically calls ```Map.closePopup``` first, which in turn calls ```Map.removeLayer``` to actually remove the layer.

3. User clicks on the popup's 'X' close button

Here, closing the popup happens by a direct call to ```Popup._close```, which in turn calls ```Map.removeLayer``` to actually remove the layer.

I tried to figure out the best way to hook into the popup open/close events. There are a couple of considerations. First, there's currently no way for a map user who adds a layer to actually get a handle to the popup object itself, especially if they just call ```Marker.bindPopup```, which creates the object internally. This means that it's not possible to create some kind of "popupclose" event on the Popup class. It makes more sense to add these events to the Map class, letting users listen for when popups open and close.

To that end, I've added "popupopen" and "popupclose" events to the Map class. These are called with a single argument which is the popup itself. I've also modified the Popup class so that it can take an optional "source" argument which can be used to tag the layer that it is attached to. This lets listeners to the events know which popup is being invoked.

What do you think? Is there a better way to implement this? I'm happy to augment the docs if you think this is worthy of inclusion.