Bug 242234 - svg event attributes.

Original patch by sicking, r=bryner, sr=jst
This commit is contained in:
tor%cs.brown.edu 2004-07-22 16:38:05 +00:00
Родитель c453f12cea
Коммит 86240fbc28
15 изменённых файлов: 171 добавлений и 11 удалений

Просмотреть файл

@ -367,7 +367,14 @@ public:
{
return aNodeInfo->NodeInfoManager()->GetDocument();
}
/**
* Returns the appropriate event argument name for the specified
* namespace. Added because we need to switch between SVG's "evt"
* and the rest of the world's "event".
*/
static const char *GetEventArgName(PRInt32 aNameSpaceID);
private:
static nsresult doReparentContentWrapper(nsIContent *aChild,
nsIDocument *aNewDocument,

Просмотреть файл

@ -1800,6 +1800,19 @@ nsContentUtils::UnregisterPrefCallback(const char *aPref,
}
static const char gEventName[] = "event";
static const char gSVGEventName[] = "evt";
// static
const char *
nsContentUtils::GetEventArgName(PRInt32 aNameSpaceID)
{
if (aNameSpaceID == kNameSpaceID_SVG)
return gSVGEventName;
return gEventName;
}
void
nsCxPusher::Push(nsISupports *aCurrentTarget)
{

Просмотреть файл

@ -1218,7 +1218,18 @@ nsEventListenerManager::AddScriptEventListener(nsISupports *aObject,
aBody, url.get(), lineNo, &handler);
}
else {
rv = context->CompileEventHandler(scriptObject, aName, aBody,
PRInt32 nameSpace = kNameSpaceID_Unknown;
if (content)
content->GetNameSpaceID(&nameSpace);
else if (doc) {
nsCOMPtr<nsIContent> root = doc->GetRootContent();
if (root)
root->GetNameSpaceID(&nameSpace);
}
const char *eventName = nsContentUtils::GetEventArgName(nameSpace);
rv = context->CompileEventHandler(scriptObject, aName, eventName,
aBody,
url.get(), lineNo,
(handlerOwner != nsnull),
&handler);
@ -1427,7 +1438,12 @@ nsEventListenerManager::CompileEventHandlerInternal(nsIScriptContext *aContext,
&handler);
}
else {
result = aContext->CompileEventHandler(jsobj, aName, handlerBody,
PRInt32 nameSpace = kNameSpaceID_Unknown;
content->GetNameSpaceID(&nameSpace);
const char *eventName = nsContentUtils::GetEventArgName(nameSpace);
result = aContext->CompileEventHandler(jsobj, aName, eventName,
handlerBody,
url.get(), lineNo,
(handlerOwner != nsnull),
&handler);

Просмотреть файл

@ -108,6 +108,13 @@ SVG_ATOM(kerning, "kerning")
SVG_ATOM(letter_spacing, "letter-spacing")
SVG_ATOM(mask, "mask")
SVG_ATOM(media, "media")
SVG_ATOM(onclick, "onclick")
SVG_ATOM(onmousedown, "onmousedown")
SVG_ATOM(onmouseup, "onmouseup")
SVG_ATOM(onmouseover, "onmouseover")
SVG_ATOM(onmousemove, "onmousemove")
SVG_ATOM(onmouseout, "onmouseout")
SVG_ATOM(onload, "onload")
SVG_ATOM(opacity, "opacity")
SVG_ATOM(pathLength, "pathLength")
SVG_ATOM(pointer_events, "pointer-events")

Просмотреть файл

@ -108,6 +108,13 @@ SVG_ATOM(kerning, "kerning")
SVG_ATOM(letter_spacing, "letter-spacing")
SVG_ATOM(mask, "mask")
SVG_ATOM(media, "media")
SVG_ATOM(onclick, "onclick")
SVG_ATOM(onmousedown, "onmousedown")
SVG_ATOM(onmouseup, "onmouseup")
SVG_ATOM(onmouseover, "onmouseover")
SVG_ATOM(onmousemove, "onmousemove")
SVG_ATOM(onmouseout, "onmouseout")
SVG_ATOM(onload, "onload")
SVG_ATOM(opacity, "opacity")
SVG_ATOM(pathLength, "pathLength")
SVG_ATOM(pointer_events, "pointer-events")

Просмотреть файл

@ -61,6 +61,7 @@
#include "nsICSSParser.h"
#include "nsGenericHTMLElement.h"
#include "nsNodeInfoManager.h"
#include "nsIScriptGlobalObject.h"
nsSVGElement::nsSVGElement(nsINodeInfo *aNodeInfo)
: nsGenericElement(aNodeInfo)
@ -199,11 +200,53 @@ nsSVGElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix,
// We don't have an nsISVGValue attribute.
attrValue.SetTo(aValue);
}
if (aNamespaceID == kNameSpaceID_None && IsEventName(aName)) {
nsCOMPtr<nsIEventListenerManager> manager;
if (aName == nsSVGAtoms::onload) {
// If we have a document, and it has a script global, add the
// event listener on the global.
// until we figure out how to handle multiple onloads, only
// onload on the root element (least surprise, hopefully)
if (mDocument &&
mDocument->GetRootContent() == NS_STATIC_CAST(nsIContent*, this)) {
nsCOMPtr<nsIDOMEventReceiver> receiver =
do_QueryInterface(mDocument->GetScriptGlobalObject());
if (receiver) {
receiver->GetListenerManager(getter_AddRefs(manager));
}
}
}
else {
GetListenerManager(getter_AddRefs(manager));
}
if (manager) {
manager->AddScriptEventListener(NS_STATIC_CAST(nsIContent*, this), aName,
aValue, PR_TRUE);
}
}
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, attrValue,
modification, hasListeners, aNotify);
}
nsresult
nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
PRBool aNotify)
{
if (aNamespaceID == kNameSpaceID_None && IsEventName(aName)) {
nsCOMPtr<nsIEventListenerManager> manager;
GetListenerManager(getter_AddRefs(manager));
if (manager) {
manager->RemoveScriptEventListener(aName);
}
}
return nsGenericElement::UnsetAttr(aNamespaceID, aName, aNotify);
}
nsresult
nsSVGElement::SetBindingParent(nsIContent* aParent)
{
@ -548,6 +591,12 @@ nsSVGElement::ParentChainChanged()
//----------------------------------------------------------------------
// Implementation Helpers:
PRBool
nsSVGElement::IsEventName(nsIAtom* aName)
{
return PR_FALSE;
}
nsresult
nsSVGElement::SetAttrAndNotify(PRInt32 aNamespaceID, nsIAtom* aAttribute,
nsIAtom* aPrefix, const nsAString& aOldValue,
@ -742,3 +791,22 @@ nsSVGElement::AddMappedSVGValue(nsIAtom* aName, nsISupports* aValue,
return NS_OK;
}
/* static */
PRBool
nsSVGElement::IsGraphicElementEventName(nsIAtom* aName)
{
const char* name;
aName->GetUTF8String(&name);
if (name[0] != 'o' || name[1] != 'n') {
return PR_FALSE;
}
return (aName == nsSVGAtoms::onclick ||
aName == nsSVGAtoms::onmousedown ||
aName == nsSVGAtoms::onmouseup ||
aName == nsSVGAtoms::onmouseover ||
aName == nsSVGAtoms::onmousemove ||
aName == nsSVGAtoms::onmouseout);
}

Просмотреть файл

@ -79,7 +79,9 @@ public:
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify);
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify);
virtual nsresult SetBindingParent(nsIContent* aParent);
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
@ -115,6 +117,9 @@ public:
virtual void ParentChainChanged();
protected:
// Hooks for subclasses
virtual PRBool IsEventName(nsIAtom* aName);
/**
* Set attribute and (if needed) notify documentobservers and fire off
* mutation events.
@ -145,6 +150,8 @@ protected:
nsresult AddMappedSVGValue(nsIAtom* aName, nsISupports* aValue,
PRInt32 aNamespaceID = kNameSpaceID_None);
static PRBool IsGraphicElementEventName(nsIAtom* aName);
nsCOMPtr<nsICSSStyleRule> mContentStyleRule;
nsAttrAndChildArray mMappedAttributes;
};

Просмотреть файл

@ -323,3 +323,11 @@ nsSVGGraphicElement::IsAttributeMapped(const nsIAtom* name) const
nsSVGGraphicElementBase::IsAttributeMapped(name);
}
//----------------------------------------------------------------------
// nsSVGElement overrides
PRBool
nsSVGGraphicElement::IsEventName(nsIAtom* aName)
{
return IsGraphicElementEventName(aName);
}

Просмотреть файл

@ -61,8 +61,10 @@ public:
// nsIStyledContent interface
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
protected:
// nsSVGElement overrides
virtual PRBool IsEventName(nsIAtom* aName);
nsCOMPtr<nsIDOMSVGAnimatedTransformList> mTransforms;
};

Просмотреть файл

@ -104,7 +104,9 @@ public:
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable);
protected:
// nsSVGElement overrides
PRBool IsEventName(nsIAtom* aName);
// implementation helpers:
void GetScreenPosition(PRInt32 &x, PRInt32 &y);
@ -1188,6 +1190,16 @@ nsSVGSVGElement::DidModifySVGObservable (nsISVGValue* observable)
return NS_OK;
}
//----------------------------------------------------------------------
// nsSVGElement overrides
PRBool
nsSVGSVGElement::IsEventName(nsIAtom* aName)
{
return IsGraphicElementEventName(aName) ||
aName == nsSVGAtoms::onclick;
}
//----------------------------------------------------------------------
// implementation helpers
void nsSVGSVGElement::GetScreenPosition(PRInt32 &x, PRInt32 &y)

Просмотреть файл

@ -444,8 +444,14 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
NS_ENSURE_SUCCESS(rv, rv);
}
PRInt32 nameSpace = kNameSpaceID_Unknown;
if (content)
content->GetNameSpaceID(&nameSpace);
const char *eventName = nsContentUtils::GetEventArgName(nameSpace);
if (isXULKey)
boundContext->CompileEventHandler(scriptObject, onEventAtom, xulText,
boundContext->CompileEventHandler(scriptObject, onEventAtom, eventName,
xulText,
nsnull, 0,
PR_TRUE, &handler);
else {
@ -457,7 +463,8 @@ nsXBLPrototypeHandler::ExecuteHandler(nsIDOMEventReceiver* aReceiver,
if (mPrototypeBinding)
mPrototypeBinding->DocURI()->GetSpec(bindingURI);
boundContext->CompileEventHandler(scriptObject, onEventAtom, handlerText,
boundContext->CompileEventHandler(scriptObject, onEventAtom, eventName,
handlerText,
bindingURI.get(),
mLineNumber,
PR_TRUE, &handler);

Просмотреть файл

@ -1495,7 +1495,8 @@ nsXULElement::CompileEventHandler(nsIScriptContext* aContext,
}
// Compile the event handler
rv = context->CompileEventHandler(scopeObject, aName, aBody,
const char *eventName = nsContentUtils::GetEventArgName(kNameSpaceID_XUL);
rv = context->CompileEventHandler(scopeObject, aName, eventName, aBody,
aURL, aLineNo, !scopeObject,
aHandler);
if (NS_FAILED(rv)) return rv;

Просмотреть файл

@ -160,6 +160,7 @@ public:
* @param aName an nsIAtom pointer naming the function; it must be lowercase
* and ASCII, and should not be longer than 63 chars. This bound on
* length is enforced only by assertions, so caveat caller!
* @param aEventName the name that the event object should be bound to
* @param aBody the event handler function's body
* @param aURL the URL or filename for error messages
* @param aLineNo the starting line number of the script for error messages
@ -176,6 +177,7 @@ public:
*/
virtual nsresult CompileEventHandler(void* aTarget,
nsIAtom* aName,
const char* aEventName,
const nsAString& aBody,
const char* aURL,
PRUint32 aLineNo,

Просмотреть файл

@ -1184,7 +1184,6 @@ nsJSContext::ExecuteScript(void* aScriptObject,
return rv;
}
const char *gEventArgv[] = {"event"};
static inline const char *
AtomToEventHandlerName(nsIAtom *aName)
@ -1209,6 +1208,7 @@ AtomToEventHandlerName(nsIAtom *aName)
nsresult
nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName,
const char *aEventName,
const nsAString& aBody,
const char *aURL, PRUint32 aLineNo,
PRBool aShared, void** aHandler)
@ -1241,9 +1241,11 @@ nsJSContext::CompileEventHandler(void *aTarget, nsIAtom *aName,
const char *charName = AtomToEventHandlerName(aName);
const char *argList[] = { aEventName };
JSFunction* fun =
::JS_CompileUCFunctionForPrincipals(mContext, target, jsprin,
charName, 1, gEventArgv,
charName, 1, argList,
(jschar*)(const PRUnichar*)PromiseFlatString(aBody).get(),
aBody.Length(),
aURL, aLineNo);

Просмотреть файл

@ -89,6 +89,7 @@ public:
PRBool* aIsUndefined);
virtual nsresult CompileEventHandler(void *aTarget,
nsIAtom *aName,
const char *aEventName,
const nsAString& aBody,
const char *aURL,
PRUint32 aLineNo,