зеркало из https://github.com/mozilla/pjs.git
Bug 242234 - svg event attributes.
Original patch by sicking, r=bryner, sr=jst
This commit is contained in:
Родитель
c453f12cea
Коммит
86240fbc28
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче