зеркало из https://github.com/mozilla/gecko-dev.git
Bug 656311 - Remove XML Events, r=bz
This commit is contained in:
Родитель
d39a545e92
Коммит
27471aa9b8
|
@ -97,8 +97,4 @@ NS_NewGenConImageContent(nsIContent** aResult,
|
|||
already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
imgIRequest* aImageRequest);
|
||||
|
||||
nsresult
|
||||
NS_NewXMLEventsElement(nsIContent** aResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
||||
#endif // nsContentCreatorFunctions_h__
|
||||
|
|
|
@ -79,8 +79,8 @@ class Element;
|
|||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x20d19edb, 0xa74c, 0x4ce4, \
|
||||
{ 0xb2, 0x7c, 0x5b, 0xdd, 0x6f, 0xbd, 0x2b, 0x66 } }
|
||||
{ 0xd69b94c2, 0x92ed, 0x4baa, \
|
||||
{ 0x82, 0x08, 0x56, 0xe4, 0xc4, 0xb3, 0xf3, 0xc8 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -959,8 +959,6 @@ public:
|
|||
|
||||
virtual bool IsScriptEnabled() = 0;
|
||||
|
||||
virtual void AddXMLEventsContent(nsIContent * aXMLEventsElement) = 0;
|
||||
|
||||
/**
|
||||
* Create an element with the specified name, prefix and namespace ID.
|
||||
*/
|
||||
|
|
|
@ -28,8 +28,7 @@ static const int32_t kNameSpaceID_None = 0;
|
|||
#define kNameSpaceID_RDF 8
|
||||
#define kNameSpaceID_XUL 9
|
||||
#define kNameSpaceID_SVG 10
|
||||
#define kNameSpaceID_XMLEvents 11
|
||||
#define kNameSpaceID_LastBuiltin 11 // last 'built-in' namespace
|
||||
#define kNameSpaceID_LastBuiltin 10 // last 'built-in' namespace
|
||||
|
||||
#define NS_NAMESPACEMANAGER_CONTRACTID "@mozilla.org/content/namespacemanager;1"
|
||||
|
||||
|
|
|
@ -1860,10 +1860,6 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
|||
nsNodeUtils::AttributeChanged(this, aNamespaceID, aName, aModType);
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_XMLEvents &&
|
||||
aName == nsGkAtoms::event && mNodeInfo->GetDocument()) {
|
||||
mNodeInfo->GetDocument()->AddXMLEventsContent(this);
|
||||
}
|
||||
if (aCallAfterSetAttr) {
|
||||
rv = AfterSetAttr(aNamespaceID, aName, &aValueForAfterSetAttr, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -90,8 +90,6 @@
|
|||
#include "nsIRadioVisitor.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
||||
#include "nsXMLEventsManager.h"
|
||||
|
||||
#include "nsBidiUtils.h"
|
||||
#include "mozilla/dom/DirectionalityUtils.h"
|
||||
|
||||
|
@ -1849,16 +1847,6 @@ nsIDocument::GetExtraPropertyTable(uint16_t aCategory)
|
|||
return mExtraPropertyTables[aCategory - 1];
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::AddXMLEventsContent(nsIContent *aXMLEventsElement)
|
||||
{
|
||||
if (!mXMLEventsManager) {
|
||||
mXMLEventsManager = new nsXMLEventsManager();
|
||||
AddObserver(mXMLEventsManager);
|
||||
}
|
||||
mXMLEventsManager->AddXMLEventsContent(aXMLEventsElement);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
|
|
|
@ -88,7 +88,6 @@ struct nsRadioGroupStruct;
|
|||
class nsOnloadBlocker;
|
||||
class nsUnblockOnloadEvent;
|
||||
class nsChildContentList;
|
||||
class nsXMLEventsManager;
|
||||
class nsHTMLStyleSheet;
|
||||
class nsHTMLCSSStyleSheet;
|
||||
class nsDOMNavigationTiming;
|
||||
|
@ -771,8 +770,6 @@ public:
|
|||
NS_DECL_NSIOBSERVER
|
||||
|
||||
virtual nsresult Init();
|
||||
|
||||
virtual void AddXMLEventsContent(nsIContent * aXMLEventsElement);
|
||||
|
||||
virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
|
||||
int32_t aNamespaceID,
|
||||
|
@ -1245,7 +1242,6 @@ protected:
|
|||
// The channel that got passed to StartDocumentLoad(), if any
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
|
||||
nsRefPtr<nsXMLEventsManager> mXMLEventsManager;
|
||||
|
||||
// Our update nesting level
|
||||
uint32_t mUpdateNestLevel;
|
||||
|
|
|
@ -31,7 +31,6 @@ using namespace mozilla::dom;
|
|||
#define kRDFNameSpaceURI "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
#define kXULNameSpaceURI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
#define kSVGNameSpaceURI "http://www.w3.org/2000/svg"
|
||||
#define kXMLEventsNameSpaceURI "http://www.w3.org/2001/xml-events"
|
||||
|
||||
class nsNameSpaceKey : public PLDHashEntryHdr
|
||||
{
|
||||
|
@ -119,7 +118,6 @@ nsresult NameSpaceManagerImpl::Init()
|
|||
REGISTER_NAMESPACE(kRDFNameSpaceURI, kNameSpaceID_RDF);
|
||||
REGISTER_NAMESPACE(kXULNameSpaceURI, kNameSpaceID_XUL);
|
||||
REGISTER_NAMESPACE(kSVGNameSpaceURI, kNameSpaceID_SVG);
|
||||
REGISTER_NAMESPACE(kXMLEventsNameSpaceURI, kNameSpaceID_XMLEvents);
|
||||
|
||||
#undef REGISTER_NAMESPACE
|
||||
|
||||
|
@ -204,9 +202,6 @@ NS_NewElement(nsIContent** aResult,
|
|||
if (ns == kNameSpaceID_SVG) {
|
||||
return NS_NewSVGElement(aResult, aNodeInfo, aFromParser);
|
||||
}
|
||||
if (ns == kNameSpaceID_XMLEvents) {
|
||||
return NS_NewXMLEventsElement(aResult, aNodeInfo);
|
||||
}
|
||||
return NS_NewXMLElement(aResult, aNodeInfo);
|
||||
}
|
||||
|
||||
|
@ -219,7 +214,6 @@ NameSpaceManagerImpl::HasElementCreator(int32_t aNameSpaceID)
|
|||
#endif
|
||||
aNameSpaceID == kNameSpaceID_MathML ||
|
||||
aNameSpaceID == kNameSpaceID_SVG ||
|
||||
aNameSpaceID == kNameSpaceID_XMLEvents ||
|
||||
false;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@ CPPSRCS = \
|
|||
nsDOMMessageEvent.cpp \
|
||||
nsPaintRequest.cpp \
|
||||
nsPrivateTextRange.cpp \
|
||||
nsXMLEventsManager.cpp \
|
||||
nsXMLEventsElement.cpp \
|
||||
nsAsyncDOMEvent.cpp \
|
||||
nsEventDispatcher.cpp \
|
||||
nsIMEStateManager.cpp \
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsXMLElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
class nsXMLEventsElement : public nsXMLElement {
|
||||
public:
|
||||
nsXMLEventsElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsXMLEventsElement();
|
||||
|
||||
virtual nsIAtom *GetIDAttributeName() const;
|
||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify);
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
};
|
||||
|
||||
nsXMLEventsElement::nsXMLEventsElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsXMLElement(aNodeInfo)
|
||||
{
|
||||
}
|
||||
|
||||
nsXMLEventsElement::~nsXMLEventsElement()
|
||||
{
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsXMLEventsElement::GetIDAttributeName() const
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::listener))
|
||||
return nsGkAtoms::id;
|
||||
return nsXMLElement::GetIDAttributeName();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXMLEventsElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
||||
const nsAString& aValue, bool aNotify)
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::listener) &&
|
||||
mNodeInfo->GetDocument() && aNameSpaceID == kNameSpaceID_None &&
|
||||
aName == nsGkAtoms::event)
|
||||
mNodeInfo->GetDocument()->AddXMLEventsContent(this);
|
||||
return nsXMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(nsXMLEventsElement)
|
||||
|
||||
nsresult
|
||||
NS_NewXMLEventsElement(nsIContent** aInstancePtrResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
{
|
||||
nsXMLEventsElement* it = new nsXMLEventsElement(aNodeInfo);
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ADDREF(*aInstancePtrResult = it);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -1,389 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsXMLEventsManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
bool nsXMLEventsListener::InitXMLEventsListener(nsIDocument * aDocument,
|
||||
nsXMLEventsManager * aManager,
|
||||
nsIContent * aContent)
|
||||
{
|
||||
nsresult rv;
|
||||
int32_t nameSpaceID;
|
||||
if (aContent->GetDocument() != aDocument)
|
||||
return false;
|
||||
if (aContent->NodeInfo()->Equals(nsGkAtoms::listener,
|
||||
kNameSpaceID_XMLEvents))
|
||||
nameSpaceID = kNameSpaceID_None;
|
||||
else
|
||||
nameSpaceID = kNameSpaceID_XMLEvents;
|
||||
nsAutoString eventType;
|
||||
aContent->GetAttr(nameSpaceID, nsGkAtoms::event, eventType);
|
||||
if (eventType.IsEmpty())
|
||||
return false;
|
||||
nsAutoString handlerURIStr;
|
||||
bool hasHandlerURI = false;
|
||||
nsIContent *handler = nullptr;
|
||||
nsAutoString observerID;
|
||||
nsAutoString targetIdref;
|
||||
|
||||
if (aContent->GetAttr(nameSpaceID, nsGkAtoms::handler, handlerURIStr)) {
|
||||
hasHandlerURI = true;
|
||||
nsAutoCString handlerRef;
|
||||
nsCOMPtr<nsIURI> handlerURI;
|
||||
bool equals = false;
|
||||
nsIURI *docURI = aDocument->GetDocumentURI();
|
||||
nsIURI *baseURI = aDocument->GetDocBaseURI();
|
||||
rv = NS_NewURI( getter_AddRefs(handlerURI), handlerURIStr, nullptr, baseURI);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
handlerURI->GetRef(handlerRef);
|
||||
// We support only XML Events Basic.
|
||||
rv = docURI->EqualsExceptRef(handlerURI, &equals);
|
||||
if (NS_SUCCEEDED(rv) && equals) {
|
||||
handler = aDocument->GetElementById(NS_ConvertUTF8toUTF16(handlerRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
handler = aContent;
|
||||
if (!handler)
|
||||
return false;
|
||||
|
||||
aContent->GetAttr(nameSpaceID, nsGkAtoms::target, targetIdref);
|
||||
|
||||
bool hasObserver =
|
||||
aContent->GetAttr(nameSpaceID, nsGkAtoms::observer, observerID);
|
||||
|
||||
bool capture =
|
||||
aContent->AttrValueIs(nameSpaceID, nsGkAtoms::phase,
|
||||
nsGkAtoms::capture, eCaseMatters);
|
||||
|
||||
bool stopPropagation =
|
||||
aContent->AttrValueIs(nameSpaceID, nsGkAtoms::propagate,
|
||||
nsGkAtoms::stop, eCaseMatters);
|
||||
|
||||
bool cancelDefault =
|
||||
aContent->AttrValueIs(nameSpaceID, nsGkAtoms::defaultAction,
|
||||
nsGkAtoms::cancel, eCaseMatters);
|
||||
|
||||
nsIContent *observer = nullptr;
|
||||
if (!hasObserver) {
|
||||
if (!hasHandlerURI) //Parent should be the observer
|
||||
observer = aContent->GetParent();
|
||||
else //We have the handler, so this is the observer
|
||||
observer = aContent;
|
||||
}
|
||||
else if (!observerID.IsEmpty()) {
|
||||
observer = aDocument->GetElementById(observerID);
|
||||
}
|
||||
nsCOMPtr<nsIDOMEventTarget> eventObserver(do_QueryInterface(observer));
|
||||
if (eventObserver) {
|
||||
nsXMLEventsListener * eli = new nsXMLEventsListener(aManager,
|
||||
aContent,
|
||||
observer,
|
||||
handler,
|
||||
eventType,
|
||||
capture,
|
||||
stopPropagation,
|
||||
cancelDefault,
|
||||
targetIdref);
|
||||
if (eli) {
|
||||
nsresult rv = eventObserver->AddEventListener(eventType, eli, capture);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aManager->RemoveXMLEventsContent(aContent);
|
||||
aManager->RemoveListener(aContent);
|
||||
aManager->AddListener(aContent, eli);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
delete eli;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsXMLEventsListener::nsXMLEventsListener(nsXMLEventsManager * aManager,
|
||||
nsIContent * aElement,
|
||||
nsIContent * aObserver,
|
||||
nsIContent * aHandler,
|
||||
const nsAString& aEvent,
|
||||
bool aPhase,
|
||||
bool aStopPropagation,
|
||||
bool aCancelDefault,
|
||||
const nsAString& aTarget)
|
||||
: mManager(aManager),
|
||||
mElement(aElement),
|
||||
mObserver(aObserver),
|
||||
mHandler(aHandler),
|
||||
mEvent(aEvent),
|
||||
mPhase(aPhase),
|
||||
mStopPropagation(aStopPropagation),
|
||||
mCancelDefault(aCancelDefault)
|
||||
{
|
||||
if (!aTarget.IsEmpty())
|
||||
mTarget = do_GetAtom(aTarget);
|
||||
}
|
||||
|
||||
nsXMLEventsListener::~nsXMLEventsListener()
|
||||
{
|
||||
}
|
||||
|
||||
void nsXMLEventsListener::Unregister()
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mObserver);
|
||||
if (target) {
|
||||
target->RemoveEventListener(mEvent, this, mPhase);
|
||||
}
|
||||
mObserver = nullptr;
|
||||
mHandler = nullptr;
|
||||
}
|
||||
|
||||
void nsXMLEventsListener::SetIncomplete()
|
||||
{
|
||||
Unregister();
|
||||
mManager->AddXMLEventsContent(mElement);
|
||||
mElement = nullptr;
|
||||
}
|
||||
|
||||
bool nsXMLEventsListener::ObserverEquals(nsIContent * aTarget)
|
||||
{
|
||||
return aTarget == mObserver;
|
||||
}
|
||||
|
||||
bool nsXMLEventsListener::HandlerEquals(nsIContent * aTarget)
|
||||
{
|
||||
return aTarget == mHandler;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXMLEventsListener, nsIDOMEventListener)
|
||||
NS_IMETHODIMP
|
||||
nsXMLEventsListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!aEvent)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
bool targetMatched = true;
|
||||
nsCOMPtr<nsIDOMEvent> event(aEvent);
|
||||
if (mTarget) {
|
||||
targetMatched = false;
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
aEvent->GetTarget(getter_AddRefs(target));
|
||||
nsCOMPtr<nsIContent> targetEl(do_QueryInterface(target));
|
||||
if (targetEl && targetEl->GetID() == mTarget)
|
||||
targetMatched = true;
|
||||
}
|
||||
if (!targetMatched)
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIDOMEventListener> handler(do_QueryInterface(mHandler));
|
||||
if (handler) {
|
||||
nsresult rv = handler->HandleEvent(event);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mStopPropagation)
|
||||
event->StopPropagation();
|
||||
if (mCancelDefault)
|
||||
event->PreventDefault();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//XMLEventsManager / DocumentObserver
|
||||
|
||||
static PLDHashOperator EnumAndUnregisterListener(nsISupports * aContent,
|
||||
nsCOMPtr<nsXMLEventsListener> & aListener,
|
||||
void * aData)
|
||||
{
|
||||
if (aListener)
|
||||
aListener->Unregister();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator EnumAndSetIncomplete(nsISupports * aContent,
|
||||
nsCOMPtr<nsXMLEventsListener> & aListener,
|
||||
void * aData)
|
||||
{
|
||||
if (aListener && aData) {
|
||||
nsCOMPtr<nsIContent> content = static_cast<nsIContent *>(aData);
|
||||
if (content) {
|
||||
if (aListener->ObserverEquals(content) || aListener->HandlerEquals(content)) {
|
||||
aListener->SetIncomplete();
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsXMLEventsManager::nsXMLEventsManager()
|
||||
{
|
||||
mListeners.Init();
|
||||
}
|
||||
nsXMLEventsManager::~nsXMLEventsManager()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsXMLEventsManager, nsIDocumentObserver, nsIMutationObserver)
|
||||
|
||||
void nsXMLEventsManager::AddXMLEventsContent(nsIContent * aContent)
|
||||
{
|
||||
mIncomplete.RemoveObject(aContent);
|
||||
mIncomplete.AppendObject(aContent);
|
||||
}
|
||||
|
||||
void nsXMLEventsManager::RemoveXMLEventsContent(nsIContent * aContent)
|
||||
{
|
||||
mIncomplete.RemoveObject(aContent);
|
||||
}
|
||||
|
||||
void nsXMLEventsManager::AddListener(nsIContent * aContent,
|
||||
nsXMLEventsListener * aListener)
|
||||
{
|
||||
mListeners.Put(aContent, aListener);
|
||||
}
|
||||
|
||||
bool nsXMLEventsManager::RemoveListener(nsIContent * aContent)
|
||||
{
|
||||
nsCOMPtr<nsXMLEventsListener> listener;
|
||||
mListeners.Get(aContent, getter_AddRefs(listener));
|
||||
if (listener) {
|
||||
listener->Unregister();
|
||||
mListeners.Remove(aContent);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void nsXMLEventsManager::AddListeners(nsIDocument* aDocument)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
nsIContent *cur;
|
||||
for (int i = 0; i < mIncomplete.Count(); ++i) {
|
||||
cur = mIncomplete[i];
|
||||
//If this succeeds, the object will be removed from mIncomplete
|
||||
if (nsXMLEventsListener::InitXMLEventsListener(aDocument, this, cur))
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
mIncomplete.Clear();
|
||||
mListeners.Enumerate(EnumAndUnregisterListener, this);
|
||||
mListeners.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::EndLoad(nsIDocument* aDocument)
|
||||
{
|
||||
AddListeners(aDocument);
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::AttributeChanged(nsIDocument* aDocument,
|
||||
Element* aElement,
|
||||
int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
int32_t aModType)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_XMLEvents &&
|
||||
(aAttribute == nsGkAtoms::event ||
|
||||
aAttribute == nsGkAtoms::handler ||
|
||||
aAttribute == nsGkAtoms::target ||
|
||||
aAttribute == nsGkAtoms::observer ||
|
||||
aAttribute == nsGkAtoms::phase ||
|
||||
aAttribute == nsGkAtoms::propagate)) {
|
||||
RemoveListener(aElement);
|
||||
AddXMLEventsContent(aElement);
|
||||
nsXMLEventsListener::InitXMLEventsListener(aDocument, this, aElement);
|
||||
}
|
||||
else {
|
||||
if (aElement->NodeInfo()->Equals(nsGkAtoms::listener,
|
||||
kNameSpaceID_XMLEvents)) {
|
||||
RemoveListener(aElement);
|
||||
AddXMLEventsContent(aElement);
|
||||
nsXMLEventsListener::InitXMLEventsListener(aDocument, this, aElement);
|
||||
}
|
||||
else if (aElement->GetIDAttributeName() == aAttribute) {
|
||||
if (aModType == nsIDOMMutationEvent::REMOVAL)
|
||||
mListeners.Enumerate(EnumAndSetIncomplete, aElement);
|
||||
else if (aModType == nsIDOMMutationEvent::MODIFICATION) {
|
||||
//Remove possible listener
|
||||
mListeners.Enumerate(EnumAndSetIncomplete, aElement);
|
||||
//Add new listeners
|
||||
AddListeners(aDocument);
|
||||
}
|
||||
else {
|
||||
//If we are adding the ID attribute, we must check whether we can
|
||||
//add new listeners
|
||||
AddListeners(aDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent,
|
||||
int32_t aNewIndexInContainer)
|
||||
{
|
||||
AddListeners(aDocument);
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
int32_t aIndexInContainer)
|
||||
{
|
||||
AddListeners(aDocument);
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
int32_t aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (!aChild || !aChild->IsElement())
|
||||
return;
|
||||
//Note, we can't use IDs here, the observer may not always have an ID.
|
||||
//And to remember: the same observer can be referenced by many
|
||||
//XMLEventsListeners
|
||||
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
//If the content was an XML Events observer or handler
|
||||
mListeners.Enumerate(EnumAndSetIncomplete, aChild);
|
||||
|
||||
//If the content was an XML Events attributes container
|
||||
if (RemoveListener(aChild)) {
|
||||
//for aContainer.appendChild(aContainer.removeChild(aChild));
|
||||
AddXMLEventsContent(aChild);
|
||||
}
|
||||
|
||||
uint32_t count = aChild->GetChildCount();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
ContentRemoved(aDocument, aChild, aChild->GetChildAt(i), i, aChild->GetPreviousSibling());
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsXMLEventsManager_h___
|
||||
#define nsXMLEventsManager_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsStubDocumentObserver.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
/*
|
||||
* The implementation of the XML Events Basic profile
|
||||
*/
|
||||
|
||||
class nsXMLEventsManager;
|
||||
class nsXMLEventsListener MOZ_FINAL : public nsIDOMEventListener {
|
||||
public:
|
||||
static bool InitXMLEventsListener(nsIDocument * aDocument,
|
||||
nsXMLEventsManager * aManager,
|
||||
nsIContent * aContent);
|
||||
nsXMLEventsListener(nsXMLEventsManager * aManager,
|
||||
nsIContent * aElement,
|
||||
nsIContent* aObserver,
|
||||
nsIContent * aHandler,
|
||||
const nsAString& aEvent,
|
||||
bool aPhase,
|
||||
bool aStopPropagation,
|
||||
bool aCancelDefault,
|
||||
const nsAString& aTarget);
|
||||
~nsXMLEventsListener();
|
||||
void Unregister();
|
||||
//Removes this event listener from observer and adds the element back to the
|
||||
//list of incomplete XML Events declarations in XMLEventsManager
|
||||
void SetIncomplete();
|
||||
bool ObserverEquals(nsIContent * aTarget);
|
||||
bool HandlerEquals(nsIContent * aTarget);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
private:
|
||||
nsXMLEventsManager * mManager;
|
||||
nsCOMPtr<nsIContent> mElement;
|
||||
nsCOMPtr<nsIContent> mObserver;
|
||||
nsCOMPtr<nsIContent> mHandler;
|
||||
nsString mEvent;
|
||||
nsCOMPtr<nsIAtom> mTarget;
|
||||
bool mPhase;
|
||||
bool mStopPropagation;
|
||||
bool mCancelDefault;
|
||||
|
||||
};
|
||||
|
||||
class nsXMLEventsManager MOZ_FINAL : public nsStubDocumentObserver {
|
||||
public:
|
||||
nsXMLEventsManager();
|
||||
~nsXMLEventsManager();
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDocumentObserver
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD
|
||||
|
||||
// nsIMutationObserver
|
||||
NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
void AddXMLEventsContent(nsIContent * aContent);
|
||||
void RemoveXMLEventsContent(nsIContent * aContent);
|
||||
void AddListener(nsIContent * aContent, nsXMLEventsListener * aListener);
|
||||
//Returns true if a listener was removed.
|
||||
bool RemoveListener(nsIContent * aXMLElement);
|
||||
private:
|
||||
void AddListeners(nsIDocument* aDocument);
|
||||
nsInterfaceHashtable<nsISupportsHashKey,nsXMLEventsListener> mListeners;
|
||||
nsCOMArray<nsIContent> mIncomplete;
|
||||
};
|
||||
|
||||
#endif /* nsXMLEventsManager_h___ */
|
Загрузка…
Ссылка в новой задаче