arabica/include/DOM/Simple/EventTargetImpl.hpp
Ben Key a5a4d4613e Resolved warnings.
Resolved occurrences of warnings C4456 and C4457.

warning C4456: declaration of 'identifier' hides previous local
declaration
warning C4457: declaration of 'identifier' hides function parameter
2018-01-29 19:30:14 -06:00

164 lines
6.3 KiB
C++

#ifndef JEZUK_DOM_SimpleDOM_EVENTTARGET_IMPL_H
#define JEZUK_DOM_SimpleDOM_EVENTTARGET_IMPL_H
////////////////////////////
// C++ EventTarget implementation
////////////////////////////
#include <DOM/Node.hpp>
#include <DOM/Events/EventTarget.hpp>
#include <DOM/DOMException.hpp>
#include <XML/XMLCharacterClasses.hpp>
#include <DOM/Simple/EventImpl.hpp>
#include <deque>
#include <algorithm>
#include <map>
#include <list>
namespace Arabica
{
namespace SimpleDOM
{
////////////////////////////////////////////////////////////////////
template<class stringT, class string_adaptorT>
class EventTargetImpl : virtual public Arabica::DOM::Events::EventTarget_impl<stringT, string_adaptorT>
{
public:
typedef Arabica::DOM::Node<stringT, string_adaptorT> DOMNodeT;
typedef Arabica::DOM::Node_impl<stringT, string_adaptorT> DOMNode_implT;
typedef Arabica::DOM::Text_impl<stringT, string_adaptorT> DOMText_implT;
typedef Arabica::DOM::Document_impl<stringT, string_adaptorT> DOMDocument_implT;
typedef Arabica::DOM::Events::Event<stringT, string_adaptorT> EventT;
typedef Arabica::DOM::Events::Event_impl<stringT, string_adaptorT> Event_implT;
typedef EventImpl<stringT, string_adaptorT> EventImplT;
typedef Arabica::DOM::Events::EventTarget<stringT, string_adaptorT> EventTargetT;
typedef EventTargetImpl<stringT, string_adaptorT> EventTargetImplT;
typedef Arabica::DOM::Events::EventTarget_impl<stringT, string_adaptorT> EventTarget_implT;
typedef Arabica::DOM::Events::EventListener<stringT, string_adaptorT> EventListenerT;
EventTargetImpl()
{
//std::cout << std::endl << "born " << this << std::endl;
} // EventTargetImpl
virtual ~EventTargetImpl()
{
//std::cout << std::endl << "die " << this << std::endl;
}
///////////////////////////////////////////////////////
// EventTarget methods
virtual void addEventListener(const stringT type,
EventListenerT& listener,
bool useCapture)
{
typedef typename std::multimap<stringT, EventListenerT*>::iterator iterator;
if (useCapture) {
std::pair<iterator, iterator> range = eventCapturers_.equal_range(type);
for (iterator it = range.first; it != range.second; ++it) {
if (it->second == &listener)
return;
}
eventCapturers_.insert(std::make_pair(type, &listener));
} else {
std::pair<iterator, iterator> range = eventListeners_.equal_range(type);
for (iterator it = range.first; it != range.second; ++it) {
if (it->second == &listener)
return;
}
eventListeners_.insert(std::make_pair(type, &listener));
}
}
virtual void removeEventListener(const stringT type,
EventListenerT& listener,
bool useCapture)
{
typedef typename std::multimap<stringT, EventListenerT*>::iterator iterator;
if (useCapture) {
std::pair<iterator, iterator> range = eventCapturers_.equal_range(type);
for (iterator it = range.first; it != range.second; ++it) {
if (it->second == &listener)
eventCapturers_.erase(it);
return;
}
} else {
std::pair<iterator, iterator> range = eventListeners_.equal_range(type);
for (iterator it = range.first; it != range.second; ++it) {
if (it->second == &listener)
eventListeners_.erase(it);
return;
}
}
}
virtual bool dispatchEvent(EventT& event)
{
typedef typename std::multimap<stringT, EventListenerT*>::iterator eventListenerIterator;
EventImplT* eventImpl = dynamic_cast<EventImplT*>(*event);
eventImpl->target_ = EventTargetT(this);
std::list<EventTargetT> eventAncestorChain;
DOMNode_implT* curr = dynamic_cast<DOMNode_implT*>(this);
while((curr = curr->getParentNode())) {
eventAncestorChain.push_front(EventTargetT(curr));
}
// capturing
eventImpl->phase_ = EventT::CAPTURING_PHASE;
typename std::list<EventTargetT>::iterator it = eventAncestorChain.begin();
while(it != eventAncestorChain.end()) {
EventTargetImplT* nodeImpl = dynamic_cast<EventTargetImplT*>(it->Impl());
if (nodeImpl != NULL) {
std::pair<eventListenerIterator, eventListenerIterator> range = nodeImpl->eventCapturers_.equal_range(event.getType());
for (eventListenerIterator itListener = range.first; itListener != range.second; ++itListener) {
itListener->second->handleEvent(event);
}
// stopPropagation was called on the event
if (eventImpl->stopped_)
return false;
}
++it;
}
// at target
eventImpl->phase_ = EventT::AT_TARGET;
std::pair<eventListenerIterator, eventListenerIterator> range = eventListeners_.equal_range(event.getType());
for (eventListenerIterator rit = range.first; rit != range.second; ++rit) {
rit->second->handleEvent(event);
}
// bubbling
if (eventImpl->getBubbles()) {
eventImpl->phase_ = EventT::BUBBLING_PHASE;
typename std::list<EventTargetT>::reverse_iterator rit = eventAncestorChain.rbegin();
while(rit != eventAncestorChain.rend()) {
EventTargetImplT* nodeImpl = dynamic_cast<EventTargetImplT*>(rit->Impl());
if (nodeImpl != NULL) {
std::pair<eventListenerIterator, eventListenerIterator> range1 = nodeImpl->eventListeners_.equal_range(event.getType());
for (eventListenerIterator ritListener = range1.first; ritListener != range1.second; ++ritListener) {
ritListener->second->handleEvent(event);
}
// stopPropagation was called on the event
if (eventImpl->stopped_)
return false;
}
++rit;
}
}
return true;
}
protected:
std::multimap<stringT, EventListenerT*> eventListeners_;
std::multimap<stringT, EventListenerT*> eventCapturers_;
}; // class EventTargetImpl
} // namespace SimpleDOM
} // namespace Arabica
#endif // JEZUK_DOM_SimpleDOM_EVENTTARGET_H
// end of file