mirror of
https://github.com/jezhiggins/arabica
synced 2024-12-26 21:58:39 +01:00
a5a4d4613e
Resolved occurrences of warnings C4456 and C4457. warning C4456: declaration of 'identifier' hides previous local declaration warning C4457: declaration of 'identifier' hides function parameter
164 lines
6.3 KiB
C++
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
|