optimize unoxml for the common case of no listeners
Change-Id: I64dcf61813c9a5dfa8a82fd0b39bad2bf916b9d2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182080 Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com> Tested-by: Jenkins
This commit is contained in:
@@ -59,6 +59,8 @@ public:
|
||||
const css::uno::Reference<css::xml::dom::events::XEventListener>& aListener,
|
||||
bool bCapture);
|
||||
|
||||
bool hasListeners() const;
|
||||
|
||||
static void callListeners(
|
||||
TypeListenerMap const& rTMap,
|
||||
xmlNodePtr const pNode,
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include "characterdata.hxx"
|
||||
#include "document.hxx"
|
||||
#include <eventdispatcher.hxx>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -43,9 +45,15 @@ namespace DOM
|
||||
{
|
||||
}
|
||||
|
||||
void CCharacterData::dispatchEvent_Impl(
|
||||
void CCharacterData::dispatchEvent_Impl(::osl::ClearableMutexGuard& guard,
|
||||
OUString const& prevValue, OUString const& newValue)
|
||||
{
|
||||
CDocument& rDocument(GetOwnerDocument());
|
||||
if (!rDocument.GetEventDispatcher().hasListeners())
|
||||
return;
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMCharacterDataModified"_ustr), UNO_QUERY);
|
||||
@@ -69,9 +77,7 @@ namespace DOM
|
||||
OUString oldValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
|
||||
xmlNodeAddContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr()));
|
||||
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent_Impl(oldValue, newValue);
|
||||
dispatchEvent_Impl(guard, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,8 +109,7 @@ namespace DOM
|
||||
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr()));
|
||||
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent_Impl(oldValue, newValue);
|
||||
dispatchEvent_Impl(guard, oldValue, newValue);
|
||||
|
||||
}
|
||||
|
||||
@@ -173,8 +178,7 @@ namespace DOM
|
||||
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr()));
|
||||
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent_Impl(oldValue, newValue);
|
||||
dispatchEvent_Impl(guard, oldValue, newValue);
|
||||
|
||||
}
|
||||
|
||||
@@ -210,8 +214,7 @@ namespace DOM
|
||||
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(tmp2, RTL_TEXTENCODING_UTF8).getStr()));
|
||||
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent_Impl(oldValue, newValue);
|
||||
dispatchEvent_Impl(guard, oldValue, newValue);
|
||||
|
||||
}
|
||||
|
||||
@@ -228,8 +231,7 @@ namespace DOM
|
||||
xmlNodeSetContent(m_aNodePtr, reinterpret_cast<const xmlChar*>(OUStringToOString(data, RTL_TEXTENCODING_UTF8).getStr()));
|
||||
OUString newValue(reinterpret_cast<char*>(m_aNodePtr->content), strlen(reinterpret_cast<char*>(m_aNodePtr->content)), RTL_TEXTENCODING_UTF8);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent_Impl(oldValue, newValue);
|
||||
dispatchEvent_Impl(guard, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace DOM
|
||||
CCharacterData(CDocument const& rDocument, ::osl::Mutex const& rMutex,
|
||||
css::xml::dom::NodeType const& reNodeType, xmlNodePtr const& rpNode);
|
||||
|
||||
void dispatchEvent_Impl(
|
||||
void dispatchEvent_Impl(::osl::ClearableMutexGuard& guard,
|
||||
OUString const& prevValue, OUString const& newValue);
|
||||
|
||||
public:
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <comphelper/attributelist.hxx>
|
||||
#include <comphelper/servicehelper.hxx>
|
||||
|
||||
#include <eventdispatcher.hxx>
|
||||
#include <node.hxx>
|
||||
#include "attr.hxx"
|
||||
#include "elementlist.hxx"
|
||||
@@ -622,18 +623,22 @@ namespace DOM
|
||||
xmlSetProp(m_aNodePtr, pName, pValue);
|
||||
}
|
||||
|
||||
// dispatch DOMAttrModified event
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMAttrModified"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(u"DOMAttrModified"_ustr,
|
||||
true, false,
|
||||
getAttributeNode(name),
|
||||
oldValue, value, name, aChangeType);
|
||||
CDocument& rDocument(GetOwnerDocument());
|
||||
if (rDocument.GetEventDispatcher().hasListeners())
|
||||
{
|
||||
// dispatch DOMAttrModified event
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMAttrModified"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(u"DOMAttrModified"_ustr,
|
||||
true, false,
|
||||
getAttributeNode(name),
|
||||
oldValue, value, name, aChangeType);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent(event);
|
||||
dispatchSubtreeModified();
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent(event);
|
||||
dispatchSubtreeModified();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -703,18 +708,23 @@ namespace DOM
|
||||
RTL_TEXTENCODING_UTF8);
|
||||
xmlSetNsProp(m_aNodePtr, pNs, pLName, pValue);
|
||||
}
|
||||
// dispatch DOMAttrModified event
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMAttrModified"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(
|
||||
u"DOMAttrModified"_ustr, true, false,
|
||||
getAttributeNodeNS(namespaceURI, OUString(reinterpret_cast<char const *>(pLName), strlen(reinterpret_cast<char const *>(pLName)), RTL_TEXTENCODING_UTF8)),
|
||||
oldValue, value, qualifiedName, aChangeType);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent(event);
|
||||
dispatchSubtreeModified();
|
||||
CDocument& rDocument(GetOwnerDocument());
|
||||
if (rDocument.GetEventDispatcher().hasListeners())
|
||||
{
|
||||
// dispatch DOMAttrModified event
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMAttrModified"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(
|
||||
u"DOMAttrModified"_ustr, true, false,
|
||||
getAttributeNodeNS(namespaceURI, OUString(reinterpret_cast<char const *>(pLName), strlen(reinterpret_cast<char const *>(pLName)), RTL_TEXTENCODING_UTF8)),
|
||||
oldValue, value, qualifiedName, aChangeType);
|
||||
|
||||
guard.clear(); // release mutex before calling event handlers
|
||||
dispatchEvent(event);
|
||||
dispatchSubtreeModified();
|
||||
}
|
||||
}
|
||||
|
||||
Reference< XNamedNodeMap > SAL_CALL
|
||||
|
||||
+46
-37
@@ -357,27 +357,32 @@ namespace DOM
|
||||
// because that will not remove unneeded ns decls
|
||||
nscleanup(res, m_aNodePtr);
|
||||
|
||||
::rtl::Reference<CNode> const pNode = GetOwnerDocument().GetCNode(res);
|
||||
CDocument& rDocument(GetOwnerDocument());
|
||||
::rtl::Reference<CNode> const pNode = rDocument.GetCNode(res);
|
||||
|
||||
if (!pNode.is()) { return nullptr; }
|
||||
|
||||
// dispatch DOMNodeInserted event, target is the new node
|
||||
// this node is the related node
|
||||
// does bubble
|
||||
pNode->m_bUnlinked = false; // will be deleted by xmlFreeDoc
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMNodeInserted"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(u"DOMNodeInserted"_ustr, true, false, this,
|
||||
OUString(), OUString(), OUString(), AttrChangeType(0) );
|
||||
|
||||
// the following dispatch functions use only UNO interfaces
|
||||
// and call event listeners, so release mutex to prevent deadlocks.
|
||||
guard.clear();
|
||||
if (rDocument.GetEventDispatcher().hasListeners())
|
||||
{
|
||||
// dispatch DOMNodeInserted event, target is the new node
|
||||
// this node is the related node
|
||||
// does bubble
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMNodeInserted"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(u"DOMNodeInserted"_ustr, true, false, this,
|
||||
OUString(), OUString(), OUString(), AttrChangeType(0) );
|
||||
|
||||
dispatchEvent(event);
|
||||
// dispatch subtree modified for this node
|
||||
dispatchSubtreeModified();
|
||||
// the following dispatch functions use only UNO interfaces
|
||||
// and call event listeners, so release mutex to prevent deadlocks.
|
||||
guard.clear();
|
||||
|
||||
dispatchEvent(event);
|
||||
// dispatch subtree modified for this node
|
||||
dispatchSubtreeModified();
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
@@ -752,30 +757,34 @@ namespace DOM
|
||||
pOld->m_bUnlinked = true;
|
||||
}
|
||||
|
||||
/*DOMNodeRemoved
|
||||
* Fired when a node is being removed from its parent node.
|
||||
* This event is dispatched before the node is removed from the tree.
|
||||
* The target of this event is the node being removed.
|
||||
* Bubbles: Yes
|
||||
* Cancelable: No
|
||||
* Context Info: relatedNode holds the parent node
|
||||
*/
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMNodeRemoved"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(u"DOMNodeRemoved"_ustr,
|
||||
true,
|
||||
false,
|
||||
this,
|
||||
OUString(), OUString(), OUString(), AttrChangeType(0) );
|
||||
CDocument& rDocument(GetOwnerDocument());
|
||||
if (rDocument.GetEventDispatcher().hasListeners())
|
||||
{
|
||||
/*DOMNodeRemoved
|
||||
* Fired when a node is being removed from its parent node.
|
||||
* This event is dispatched before the node is removed from the tree.
|
||||
* The target of this event is the node being removed.
|
||||
* Bubbles: Yes
|
||||
* Cancelable: No
|
||||
* Context Info: relatedNode holds the parent node
|
||||
*/
|
||||
Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
|
||||
Reference< XMutationEvent > event(docevent->createEvent(
|
||||
u"DOMNodeRemoved"_ustr), UNO_QUERY);
|
||||
event->initMutationEvent(u"DOMNodeRemoved"_ustr,
|
||||
true,
|
||||
false,
|
||||
this,
|
||||
OUString(), OUString(), OUString(), AttrChangeType(0) );
|
||||
|
||||
// the following dispatch functions use only UNO interfaces
|
||||
// and call event listeners, so release mutex to prevent deadlocks.
|
||||
guard.clear();
|
||||
// the following dispatch functions use only UNO interfaces
|
||||
// and call event listeners, so release mutex to prevent deadlocks.
|
||||
guard.clear();
|
||||
|
||||
dispatchEvent(event);
|
||||
// subtree modified for this node
|
||||
dispatchSubtreeModified();
|
||||
dispatchEvent(event);
|
||||
// subtree modified for this node
|
||||
dispatchSubtreeModified();
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,11 @@ namespace DOM::events {
|
||||
}
|
||||
}
|
||||
|
||||
bool CEventDispatcher::hasListeners() const
|
||||
{
|
||||
return !m_CaptureListeners.empty() || !m_TargetListeners.empty();
|
||||
}
|
||||
|
||||
CEventDispatcher::~CEventDispatcher()
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user