зеркало из https://github.com/mozilla/pjs.git
Combine various SetAttr implementations so that we just have
nsGenericElement::SetAttr. Bug 308270, r=sicking, sr=jst
This commit is contained in:
Родитель
cd8d0700c3
Коммит
e22e482952
|
@ -3789,43 +3789,24 @@ nsGenericElement::TriggerLink(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::AddScriptEventListener(nsIAtom* aAttribute,
|
||||
nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
|
||||
const nsAString& aValue)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsISupports *target = NS_STATIC_CAST(nsIContent *, this);
|
||||
NS_PRECONDITION(aEventName, "Must have event name!");
|
||||
nsCOMPtr<nsISupports> target;
|
||||
PRBool defer = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
// Attributes on the body and frameset tags get set on the global object
|
||||
if (mNodeInfo->Equals(nsHTMLAtoms::body) ||
|
||||
mNodeInfo->Equals(nsHTMLAtoms::frameset)) {
|
||||
nsIScriptGlobalObject *sgo;
|
||||
|
||||
// If we have a document, and it has a script global, add the
|
||||
// event listener on the global. If not, proceed as normal.
|
||||
// XXXbz should we instead use GetCurrentDoc() here, override
|
||||
// BindToTree for those classes and munge event listeners there?
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
if (document && (sgo = document->GetScriptGlobalObject())) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(sgo));
|
||||
NS_ENSURE_TRUE(receiver, NS_ERROR_FAILURE);
|
||||
|
||||
receiver->GetListenerManager(getter_AddRefs(manager));
|
||||
|
||||
target = sgo;
|
||||
defer = PR_FALSE;
|
||||
}
|
||||
} else {
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
}
|
||||
nsresult rv = GetEventListenerManagerForAttr(getter_AddRefs(manager),
|
||||
getter_AddRefs(target),
|
||||
&defer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (manager) {
|
||||
nsIDocument *ownerDoc = GetOwnerDoc();
|
||||
|
||||
rv =
|
||||
manager->AddScriptEventListener(target, aAttribute, aValue, defer,
|
||||
manager->AddScriptEventListener(target, aEventName, aValue, defer,
|
||||
!nsContentUtils::IsChromeDoc(ownerDoc));
|
||||
}
|
||||
|
||||
|
@ -4001,47 +3982,82 @@ nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
}
|
||||
}
|
||||
|
||||
PRBool modification = PR_FALSE;
|
||||
nsAutoString oldValue;
|
||||
PRBool hasListeners = PR_FALSE;
|
||||
PRBool modification = PR_FALSE;
|
||||
|
||||
PRInt32 index = mAttrsAndChildren.IndexOfAttr(aName, aNamespaceID);
|
||||
if (index >= 0) {
|
||||
modification = PR_TRUE;
|
||||
|
||||
// Get old value and see if it's the same as new one
|
||||
const nsAttrName* attrName = mAttrsAndChildren.GetSafeAttrNameAt(index);
|
||||
const nsAttrValue* val = mAttrsAndChildren.AttrAt(index);
|
||||
NS_ASSERTION(attrName && val, "attribute is supposed to be there");
|
||||
val->ToString(oldValue);
|
||||
if (oldValue.Equals(aValue) &&
|
||||
aPrefix == attrName->GetPrefix()) {
|
||||
// Nothing to do
|
||||
|
||||
return NS_OK;
|
||||
if (IsInDoc()) {
|
||||
hasListeners =
|
||||
HasMutationListeners(this, NS_EVENT_BITS_MUTATION_ATTRMODIFIED);
|
||||
}
|
||||
|
||||
// If we have no listeners and aNotify is false, we are almost certainly
|
||||
// coming from the content sink and will almost certainly have no previous
|
||||
// value. Even if we do, setting the value is cheap when we have no
|
||||
// listeners and don't plan to notify. The check for aNotify here is an
|
||||
// optimization, the check for haveListeners is a correctness issue.
|
||||
if (hasListeners || aNotify) {
|
||||
nsAttrInfo info(GetAttrInfo(aNamespaceID, aName));
|
||||
if (info.mValue) {
|
||||
// Check whether the old value is the same as the new one. Note that we
|
||||
// only need to actually _get_ the old value if we have listeners.
|
||||
PRBool valueMatches;
|
||||
if (hasListeners) {
|
||||
// Need to store the old value
|
||||
info.mValue->ToString(oldValue);
|
||||
valueMatches = aValue.Equals(oldValue);
|
||||
} else if (aNotify) {
|
||||
valueMatches = info.mValue->Equals(aValue, eCaseMatters);
|
||||
}
|
||||
if (valueMatches && aPrefix == info.mName->GetPrefix()) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Begin the update _before_ changing the attr value
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &aValue, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAttrValue attrValue;
|
||||
if (aNamespaceID != kNameSpaceID_None ||
|
||||
!ParseAttribute(aName, aValue, attrValue)) {
|
||||
attrValue.SetTo(aValue);
|
||||
}
|
||||
|
||||
rv = SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
|
||||
attrValue, modification, hasListeners, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return AfterSetAttr(aNamespaceID, aName, &aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint8 modType = aModification ?
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::MODIFICATION) :
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::ADDITION);
|
||||
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||
if (aNotify && document) {
|
||||
document->AttributeWillChange(this, aNamespaceID, aName);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == GetIDAttributeName() && !aValue.IsEmpty()) {
|
||||
// Store id as atom. id="" means that the element has no id, not that it has
|
||||
// an emptystring as the id.
|
||||
nsAttrValue attrValue;
|
||||
attrValue.ParseAtom(aValue);
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(aName, attrValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
rv = mAttrsAndChildren.SetAttr(aName, aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// XXXbz Perhaps we should push up the attribute mapping function
|
||||
// stuff to nsGenericElement?
|
||||
if (!IsAttributeMapped(aName) ||
|
||||
!SetMappedAttribute(document, aName, aParsedValue, &rv)) {
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(aName, aParsedValue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -4051,17 +4067,17 @@ nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAttrValue attrVal(aValue);
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(ni, attrVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (document) {
|
||||
nsXBLBinding *binding = document->BindingManager()->GetBinding(this);
|
||||
if (binding)
|
||||
if (binding) {
|
||||
binding->AttributeChanged(aName, aNamespaceID, PR_FALSE, aNotify);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(this, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
if (aFireMutation) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node =
|
||||
do_QueryInterface(NS_STATIC_CAST(nsIContent *, this));
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED, node);
|
||||
|
@ -4073,40 +4089,88 @@ nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aName;
|
||||
if (!oldValue.IsEmpty()) {
|
||||
mutation.mPrevAttrValue = do_GetAtom(oldValue);
|
||||
nsAutoString newValue;
|
||||
aParsedValue.ToString(newValue);
|
||||
if (!newValue.IsEmpty()) {
|
||||
mutation.mNewAttrValue = do_GetAtom(newValue);
|
||||
}
|
||||
|
||||
if (!aValue.IsEmpty()) {
|
||||
mutation.mNewAttrValue = do_GetAtom(aValue);
|
||||
if (!aOldValue.IsEmpty()) {
|
||||
mutation.mPrevAttrValue = do_GetAtom(aOldValue);
|
||||
}
|
||||
|
||||
if (modification) {
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::MODIFICATION;
|
||||
} else {
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::ADDITION;
|
||||
}
|
||||
|
||||
mutation.mAttrChange = modType;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
PRInt32 modHint = modification ? PRInt32(nsIDOMMutationEvent::MODIFICATION)
|
||||
: PRInt32(nsIDOMMutationEvent::ADDITION);
|
||||
document->AttributeChanged(this, aNamespaceID, aName, modHint);
|
||||
document->AttributeChanged(this, aNamespaceID, aName, modType);
|
||||
}
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_XMLEvents && aName == nsHTMLAtoms::_event &&
|
||||
mNodeInfo->GetDocument()) {
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_XMLEvents &&
|
||||
aName == nsHTMLAtoms::_event && mNodeInfo->GetDocument()) {
|
||||
mNodeInfo->GetDocument()->AddXMLEventsContent(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericElement::ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aAttribute == GetIDAttributeName() && !aValue.IsEmpty()) {
|
||||
// Store id as an atom. id="" means that the element has no id,
|
||||
// not that it has an emptystring as the id.
|
||||
aResult.ParseAtom(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericElement::SetMappedAttribute(nsIDocument* aDocument,
|
||||
nsIAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
nsresult* aRetval)
|
||||
{
|
||||
*aRetval = NS_OK;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
||||
nsISupports** aTarget,
|
||||
PRBool* aDefer)
|
||||
{
|
||||
nsresult rv = GetListenerManager(aManager);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = NS_STATIC_CAST(nsIContent*, this));
|
||||
}
|
||||
*aDefer = PR_TRUE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsGenericElement::nsAttrInfo
|
||||
nsGenericElement::GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const
|
||||
{
|
||||
NS_ASSERTION(nsnull != aName, "must have attribute name");
|
||||
NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
|
||||
"must have a real namespace ID!");
|
||||
|
||||
PRInt32 index = mAttrsAndChildren.IndexOfAttr(aName, aNamespaceID);
|
||||
if (index >= 0) {
|
||||
return nsAttrInfo(mAttrsAndChildren.GetSafeAttrNameAt(index),
|
||||
mAttrsAndChildren.AttrAt(index));
|
||||
}
|
||||
|
||||
return nsAttrInfo(nsnull, nsnull);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsGenericElement::GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAString& aResult) const
|
||||
|
|
|
@ -546,12 +546,12 @@ public:
|
|||
//----------------------------------------
|
||||
|
||||
/**
|
||||
* Add a script event listener with the given attr name (like onclick)
|
||||
* and with the value as JS
|
||||
* @param aAttribute the event listener name
|
||||
* Add a script event listener with the given event handler name
|
||||
* (like onclick) and with the value as JS
|
||||
* @param aEventName the event listener name
|
||||
* @param aValue the JS to attach
|
||||
*/
|
||||
nsresult AddScriptEventListener(nsIAtom* aAttribute,
|
||||
nsresult AddScriptEventListener(nsIAtom* aEventName,
|
||||
const nsAString& aValue);
|
||||
|
||||
/**
|
||||
|
@ -685,6 +685,138 @@ public:
|
|||
static PLDHashTable sRangeListsHash;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Struct that stores info on an attribute. The name and value must
|
||||
* either both be null or both be non-null.
|
||||
*/
|
||||
struct nsAttrInfo {
|
||||
nsAttrInfo(const nsAttrName* aName, const nsAttrValue* aValue) :
|
||||
mName(aName), mValue(aValue) {}
|
||||
nsAttrInfo(const nsAttrInfo& aOther) :
|
||||
mName(aOther.mName), mValue(aOther.mValue) {}
|
||||
|
||||
const nsAttrName* mName;
|
||||
const nsAttrValue* mValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set attribute and (if needed) notify documentobservers and fire off
|
||||
* mutation events.
|
||||
*
|
||||
* @param aNamespaceID namespace of attribute
|
||||
* @param aAttribute local-name of attribute
|
||||
* @param aPrefix aPrefix of attribute
|
||||
* @param aOldValue previous value of attribute. Only needed if
|
||||
* aFireMutation is true.
|
||||
* @param aParsedValue parsed new value of attribute
|
||||
* @param aModification is this a attribute-modification or addition. Only
|
||||
* needed if aFireMutation or aNotify is true.
|
||||
* @param aFireMutation should mutation-events be fired?
|
||||
* @param aNotify should we notify document-observers?
|
||||
*/
|
||||
nsresult SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify);
|
||||
|
||||
/**
|
||||
* Convert an attribute string value to attribute type based on the type of
|
||||
* attribute. Called by SetAttr(). Note that at the moment we only do this
|
||||
* for attributes in the null namespace (kNameSpaceID_None).
|
||||
*
|
||||
* @param aAttribute the attribute to convert
|
||||
* @param aValue the string value to convert
|
||||
* @param aResult the nsAttrValue [OUT]
|
||||
* @return PR_TRUE if the parsing was successful, PR_FALSE otherwise
|
||||
*/
|
||||
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
/**
|
||||
* Try to set the attribute as a mapped attribute, if applicable. This will
|
||||
* only be called for attributes that are in the null namespace and only on
|
||||
* attributes that returned true when passed to IsAttributeMapped. The
|
||||
* caller will not try to set the attr in any other way if this method
|
||||
* returns PR_TRUE (the value of aRetval does not matter for that purpose).
|
||||
*
|
||||
* @param aDocument the current document of this node (an optimization)
|
||||
* @param aName the name of the attribute
|
||||
* @param aValue the nsAttrValue to set
|
||||
* @param [out] aRetval the nsresult status of the operation, if any.
|
||||
* @return PR_TRUE if the setting was attempted, PR_FALSE otherwise.
|
||||
*/
|
||||
virtual PRBool SetMappedAttribute(nsIDocument* aDocument,
|
||||
nsIAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
nsresult* aRetval);
|
||||
|
||||
/**
|
||||
* Hook that is called by nsGenericElement::SetAttr to allow subclasses to
|
||||
* deal with attribute sets. This will only be called after we verify that
|
||||
* we're actually doing an attr set and will be called before ParseAttribute
|
||||
* and hence before we've set the new value.
|
||||
*
|
||||
* @param aNamespaceID the namespace of the attr being set
|
||||
* @param aName the localname of the attribute being set
|
||||
* @param aValue the value it's being set to. If null, the attr is being
|
||||
* removed.
|
||||
* // XXXbz we don't actually call this method when we're removing attrs yet.
|
||||
* But we will eventually.
|
||||
* @param aNotify Whether we plan to notify document observers.
|
||||
*/
|
||||
// Note that this is inlined so that when subclasses call it it gets
|
||||
// inlined. Those calls don't go through a vtable.
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook that is called by nsGenericElement::SetAttr to allow subclasses to
|
||||
* deal with attribute sets. This will only be called after we have called
|
||||
* SetAndTakeAttr (that is, after we have actually set the attr).
|
||||
*
|
||||
* @param aNamespaceID the namespace of the attr being set
|
||||
* @param aName the localname of the attribute being set
|
||||
* @param aValue the value it's being set to. If null, the attr is being
|
||||
* removed.
|
||||
* // XXXbz we don't actually call this method when we're removing attrs yet.
|
||||
* But we will eventually.
|
||||
* @param aNotify Whether we plan to notify document observers.
|
||||
*/
|
||||
// Note that this is inlined so that when subclasses call it it gets
|
||||
// inlined. Those calls don't go through a vtable.
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to allow subclasses to produce a different nsIEventListenerManager if
|
||||
* needed for attachment of attribute-defined handlers
|
||||
*/
|
||||
virtual nsresult
|
||||
GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
||||
nsISupports** aTarget,
|
||||
PRBool* aDefer);
|
||||
|
||||
/**
|
||||
* Get the attr info for the given namespace ID and attribute name. The
|
||||
* namespace ID must not be kNameSpaceID_Unknown and the name must not be
|
||||
* null. Note that this can only return info on attributes that actually
|
||||
* live on this element (and is only virtual to handle XUL prototypes). That
|
||||
* is, this should only be called from methods that only care about attrs
|
||||
* that effectively live in mAttrsAndChildren.
|
||||
*/
|
||||
virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
|
||||
|
||||
/**
|
||||
* Duplicate children by calling importNode and append them to another
|
||||
* element.
|
||||
|
|
|
@ -1664,152 +1664,6 @@ nsGenericHTMLElement::GetHrefURIForAnchors(nsIURI** aURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
{
|
||||
NS_ASSERTION(aNamespaceID != kNameSpaceID_XHTML,
|
||||
"Error, attribute on [X]HTML element set with XHTML namespace, "
|
||||
"this is wrong, trust me! Lose the prefix on the attribute!");
|
||||
|
||||
nsresult rv;
|
||||
nsAutoString oldValue;
|
||||
PRBool hasListeners = PR_FALSE;
|
||||
PRBool modification = PR_FALSE;
|
||||
|
||||
if (IsInDoc()) {
|
||||
hasListeners = nsGenericElement::HasMutationListeners(this,
|
||||
NS_EVENT_BITS_MUTATION_ATTRMODIFIED);
|
||||
|
||||
// If we have no listeners and aNotify is false, we are almost certainly
|
||||
// coming from the content sink and will almost certainly have no previous
|
||||
// value. Even if we do, setting the value is cheap when we have no
|
||||
// listeners and don't plan to notify. The check for aNotify here is an
|
||||
// optimization, the check for haveListeners is a correctness issue.
|
||||
if (hasListeners || aNotify) {
|
||||
// don't do any update if old == new.
|
||||
// It would be nice to not have to call GetAttr here but to rather just
|
||||
// grab the nsAttrValue from mAttrsAndChildren and compare that to
|
||||
// aValue. However not all nsAttrValues can currently be converted to
|
||||
// strings (specifically enums and nsISupports can't) so we have to take
|
||||
// the detour through GetAttr for now.
|
||||
rv = GetAttr(aNamespaceID, aAttribute, oldValue);
|
||||
modification = rv != NS_CONTENT_ATTR_NOT_THERE;
|
||||
if (modification && aValue.Equals(oldValue)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse into a nsAttrValue
|
||||
nsAttrValue attrValue;
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (!ParseAttribute(aAttribute, aValue, attrValue)) {
|
||||
attrValue.SetTo(aValue);
|
||||
}
|
||||
|
||||
if (IsEventName(aAttribute)) {
|
||||
AddScriptEventListener(aAttribute, aValue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
attrValue.SetTo(aValue);
|
||||
}
|
||||
|
||||
return SetAttrAndNotify(aNamespaceID, aAttribute, aPrefix, oldValue,
|
||||
attrValue, modification, hasListeners, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint8 modType = aModification ?
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::MODIFICATION) :
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::ADDITION);
|
||||
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||
if (aNotify && document) {
|
||||
document->AttributeWillChange(this, aNamespaceID, aAttribute);
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (IsAttributeMapped(aAttribute)) {
|
||||
nsHTMLStyleSheet* sheet = document ?
|
||||
document->GetAttributeStyleSheet() : nsnull;
|
||||
rv = mAttrsAndChildren.SetAndTakeMappedAttr(aAttribute, aParsedValue,
|
||||
this, sheet);
|
||||
}
|
||||
else {
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(aAttribute, aParsedValue);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
rv = mNodeInfo->NodeInfoManager()->GetNodeInfo(aAttribute, aPrefix,
|
||||
aNamespaceID,
|
||||
getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (document) {
|
||||
nsXBLBinding *binding = document->BindingManager()->GetBinding(this);
|
||||
if (binding) {
|
||||
binding->AttributeChanged(aAttribute, aNamespaceID, PR_FALSE, aNotify);
|
||||
}
|
||||
|
||||
if (aFireMutation) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node =
|
||||
do_QueryInterface(NS_STATIC_CAST(nsIContent *, this));
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED, node);
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
nsAutoString newValue;
|
||||
aParsedValue.ToString(newValue);
|
||||
if (!newValue.IsEmpty()) {
|
||||
mutation.mNewAttrValue = do_GetAtom(newValue);
|
||||
}
|
||||
if (!aOldValue.IsEmpty()) {
|
||||
mutation.mPrevAttrValue = do_GetAtom(aOldValue);
|
||||
}
|
||||
mutation.mAttrChange = modType;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
document->AttributeChanged(this, aNamespaceID, aAttribute, modType);
|
||||
}
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_XMLEvents &&
|
||||
aAttribute == nsHTMLAtoms::_event && mNodeInfo->GetDocument()) {
|
||||
mNodeInfo->GetDocument()->AddXMLEventsContent(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsGenericHTMLElement::IsEventName(nsIAtom* aName)
|
||||
{
|
||||
const char* name;
|
||||
|
@ -1859,6 +1713,58 @@ PRBool nsGenericHTMLElement::IsEventName(nsIAtom* aName)
|
|||
aName == nsLayoutAtoms::onDOMFocusOut);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None && IsEventName(aName) && aValue) {
|
||||
nsresult rv = AddScriptEventListener(aName, *aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return nsGenericElement::AfterSetAttr(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
||||
nsISupports** aTarget,
|
||||
PRBool* aDefer)
|
||||
{
|
||||
// Attributes on the body and frameset tags get set on the global object
|
||||
if (mNodeInfo->Equals(nsHTMLAtoms::body) ||
|
||||
mNodeInfo->Equals(nsHTMLAtoms::frameset)) {
|
||||
nsIScriptGlobalObject *sgo;
|
||||
|
||||
// If we have a document, and it has a script global, add the
|
||||
// event listener on the global. If not, proceed as normal.
|
||||
// XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc() here,
|
||||
// override BindToTree for those classes and munge event listeners there?
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
nsresult rv = NS_OK;
|
||||
if (document && (sgo = document->GetScriptGlobalObject())) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(sgo));
|
||||
NS_ENSURE_TRUE(receiver, NS_ERROR_FAILURE);
|
||||
|
||||
rv = receiver->GetListenerManager(aManager);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = sgo);
|
||||
}
|
||||
*aDefer = PR_FALSE;
|
||||
} else {
|
||||
*aManager = nsnull;
|
||||
*aTarget = nsnull;
|
||||
*aDefer = PR_FALSE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
return nsGenericElement::GetEventListenerManagerForAttr(aManager, aTarget,
|
||||
aDefer);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
|
@ -1960,6 +1866,8 @@ nsGenericHTMLElement::SetInlineStyleRule(nsICSSStyleRule* aStyleRule,
|
|||
// and thus will be the same.
|
||||
if (hasListeners) {
|
||||
// save the old attribute so we can set up the mutation event properly
|
||||
// XXXbz if the old rule points to the same declaration as the new one,
|
||||
// this is getting the new attr value, not the old one....
|
||||
modification = GetAttr(kNameSpaceID_None, nsHTMLAtoms::style,
|
||||
oldValueStr) != NS_CONTENT_ATTR_NOT_THERE;
|
||||
}
|
||||
|
@ -2148,11 +2056,6 @@ nsGenericHTMLElement::ParseAttribute(nsIAtom* aAttribute,
|
|||
aValue, aResult);
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (aAttribute == nsHTMLAtoms::id && !aValue.IsEmpty()) {
|
||||
aResult.ParseAtom(aValue);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (aAttribute == nsHTMLAtoms::kClass) {
|
||||
aResult.ParseAtomArray(aValue);
|
||||
|
||||
|
@ -2163,7 +2066,7 @@ nsGenericHTMLElement::ParseAttribute(nsIAtom* aAttribute,
|
|||
return aResult.ParseIntWithBounds(aValue, -32768, 32767);
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
return nsGenericElement::ParseAttribute(aAttribute, aValue, aResult);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -2176,6 +2079,22 @@ nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
|||
return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericHTMLElement::SetMappedAttribute(nsIDocument* aDocument,
|
||||
nsIAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
nsresult* aRetval)
|
||||
{
|
||||
NS_PRECONDITION(aDocument == GetCurrentDoc(), "Unexpected document");
|
||||
nsHTMLStyleSheet* sheet = aDocument ?
|
||||
aDocument->GetAttributeStyleSheet() : nsnull;
|
||||
|
||||
*aRetval = mAttrsAndChildren.SetAndTakeMappedAttr(aName, aValue,
|
||||
this, sheet);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
nsMapRuleToAttributesFunc
|
||||
nsGenericHTMLElement::GetAttributeMappingFunction() const
|
||||
{
|
||||
|
@ -3268,22 +3187,17 @@ nsGenericHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
nsGenericHTMLFormElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (aNameSpaceID != kNameSpaceID_None) {
|
||||
rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
||||
aNotify);
|
||||
} else {
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
nsCOMPtr<nsIFormControl> thisControl;
|
||||
nsAutoString tmp;
|
||||
|
||||
QueryInterface(NS_GET_IID(nsIFormControl), getter_AddRefs(thisControl));
|
||||
|
||||
// Add & remove the control to and/or from the hash table
|
||||
// remove the control from the hashtable as needed
|
||||
|
||||
if (mForm && (aName == nsHTMLAtoms::name || aName == nsHTMLAtoms::id)) {
|
||||
GetAttr(kNameSpaceID_None, aName, tmp);
|
||||
|
||||
|
@ -3307,19 +3221,32 @@ nsGenericHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
|
||||
mForm->RemoveElement(thisControl);
|
||||
}
|
||||
}
|
||||
|
||||
rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
||||
aNotify);
|
||||
return nsGenericHTMLElement::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
if (mForm && (aName == nsHTMLAtoms::name || aName == nsHTMLAtoms::id)) {
|
||||
GetAttr(kNameSpaceID_None, aName, tmp);
|
||||
nsresult
|
||||
nsGenericHTMLFormElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
nsCOMPtr<nsIFormControl> thisControl =
|
||||
do_QueryInterface(NS_STATIC_CAST(nsIContent, this));
|
||||
|
||||
if (!tmp.IsEmpty()) {
|
||||
mForm->AddElementToTable(thisControl, tmp);
|
||||
// add the control to the hashtable as needed
|
||||
|
||||
if (mForm && (aName == nsHTMLAtoms::name || aName == nsHTMLAtoms::id) &&
|
||||
aValue) {
|
||||
if (!aValue->IsEmpty()) {
|
||||
mForm->AddElementToTable(thisControl, *aValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (mForm && aName == nsHTMLAtoms::type) {
|
||||
nsAutoString tmp;
|
||||
|
||||
GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, tmp);
|
||||
|
||||
if (!tmp.IsEmpty()) {
|
||||
|
@ -3334,17 +3261,29 @@ nsGenericHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
|
||||
mForm->AddElement(thisControl);
|
||||
}
|
||||
|
||||
// And notify on content state changes, if any
|
||||
|
||||
if (aNotify && aName == nsHTMLAtoms::disabled && CanBeDisabled()) {
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
if (document) {
|
||||
mozAutoDocUpdate(document, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
document->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_DISABLED |
|
||||
NS_EVENT_STATE_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AfterSetAttr(aNameSpaceID, aName, &aValue, aNotify);
|
||||
|
||||
return rv;
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFormElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
PRBool aNotify)
|
||||
{
|
||||
BeforeSetAttr(aNameSpaceID, aName, nsnull, aNotify);
|
||||
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify);
|
||||
|
||||
AfterSetAttr(aNameSpaceID, aName, nsnull, aNotify);
|
||||
|
@ -3364,21 +3303,6 @@ nsGenericHTMLFormElement::CanBeDisabled() const
|
|||
type != NS_FORM_OBJECT;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNotify && aNameSpaceID == kNameSpaceID_None &&
|
||||
aName == nsHTMLAtoms::disabled && CanBeDisabled()) {
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
if (document) {
|
||||
mozAutoDocUpdate(document, UPDATE_CONTENT_STATE, PR_TRUE);
|
||||
document->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_DISABLED |
|
||||
NS_EVENT_STATE_ENABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::FindAndSetForm()
|
||||
{
|
||||
|
|
|
@ -185,14 +185,6 @@ public:
|
|||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
||||
const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAString& aResult) const;
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
|
@ -272,6 +264,10 @@ public:
|
|||
nsAttrValue& aResult);
|
||||
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
virtual PRBool SetMappedAttribute(nsIDocument* aDocument,
|
||||
nsIAtom* aName,
|
||||
nsAttrValue& aValue,
|
||||
nsresult* aRetval);
|
||||
|
||||
/**
|
||||
* Get the base target for any links within this piece
|
||||
|
@ -615,30 +611,6 @@ public:
|
|||
*/
|
||||
static PRBool InNavQuirksMode(nsIDocument* aDoc);
|
||||
|
||||
/**
|
||||
* Set attribute and (if needed) notify documentobservers and fire off
|
||||
* mutation events.
|
||||
*
|
||||
* @param aNamespaceID namespace of attribute
|
||||
* @param aAttribute local-name of attribute
|
||||
* @param aPrefix aPrefix of attribute
|
||||
* @param aOldValue previous value of attribute. Only needed if
|
||||
* aFireMutation is true.
|
||||
* @param aParsedValue parsed new value of attribute
|
||||
* @param aModification is this a attribute-modification or addition. Only
|
||||
* needed if aFireMutation or aNotify is true.
|
||||
* @param aFireMutation should mutation-events be fired?
|
||||
* @param aNotify should we notify document-observers?
|
||||
*/
|
||||
nsresult SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify);
|
||||
|
||||
// Helper functions for <a> and <area>
|
||||
static nsresult SetProtocolInHrefString(const nsAString &aHref,
|
||||
const nsAString &aProtocol,
|
||||
|
@ -711,6 +683,14 @@ protected:
|
|||
*/
|
||||
PRBool IsEventName(nsIAtom* aName);
|
||||
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
virtual nsresult
|
||||
GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
||||
nsISupports** aTarget,
|
||||
PRBool* aDefer);
|
||||
|
||||
virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
|
||||
|
||||
/**
|
||||
|
@ -865,15 +845,6 @@ public:
|
|||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
PRBool aNotify);
|
||||
|
||||
|
@ -886,18 +857,11 @@ protected:
|
|||
*/
|
||||
void FindAndSetForm();
|
||||
|
||||
/**
|
||||
* Called when an attribute has just been changed.
|
||||
*
|
||||
* Note that this function is also called if the attribute change fails.
|
||||
*
|
||||
* @param aNameSpaceID The namespace ID of the attribute
|
||||
* @param aName The attribute name (atom)
|
||||
* @param aValue The new value (nsnull if it being removed)
|
||||
* @param aNotify Notify about changes?
|
||||
*/
|
||||
virtual void AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
/**
|
||||
* Returns true if the control can be disabled
|
||||
|
|
|
@ -198,32 +198,6 @@ public:
|
|||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
{
|
||||
BeforeSetAttr(aNameSpaceID, aName, &aValue, aNotify);
|
||||
|
||||
nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName,
|
||||
aPrefix, aValue, aNotify);
|
||||
return rv;
|
||||
}
|
||||
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
BeforeSetAttr(aNameSpaceID, aAttribute, nsnull, aNotify);
|
||||
|
||||
nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, aAttribute,
|
||||
aNotify);
|
||||
return rv;
|
||||
}
|
||||
|
||||
virtual void DoneCreatingElement();
|
||||
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
@ -271,13 +245,13 @@ protected:
|
|||
/**
|
||||
* Called when an attribute is about to be changed
|
||||
*/
|
||||
void BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
/**
|
||||
* Called when an attribute has just been changed
|
||||
*/
|
||||
virtual void AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
void SelectAll(nsPresContext* aPresContext);
|
||||
PRBool IsImage() const
|
||||
|
@ -438,126 +412,128 @@ nsHTMLInputElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
|||
return nsGenericElement::CloneNode(aDeep, this, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsHTMLInputElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue,
|
||||
PRBool aNotify)
|
||||
{
|
||||
if (aNameSpaceID != kNameSpaceID_None) {
|
||||
return;
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
//
|
||||
// When name or type changes, radio should be removed from radio group.
|
||||
// (type changes are handled in the form itself currently)
|
||||
// If the parser is not done creating the radio, we also should not do it.
|
||||
//
|
||||
if ((aName == nsHTMLAtoms::name ||
|
||||
(aName == nsHTMLAtoms::type && !mForm)) &&
|
||||
mType == NS_FORM_INPUT_RADIO &&
|
||||
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
||||
WillRemoveFromRadioGroup();
|
||||
} else if (aNotify && aName == nsHTMLAtoms::src &&
|
||||
aValue && mType == NS_FORM_INPUT_IMAGE) {
|
||||
// Null value means the attr got unset; don't trigger on that
|
||||
ImageURIChanged(*aValue, PR_TRUE, aNotify);
|
||||
} else if (aNotify && aName == nsHTMLAtoms::disabled) {
|
||||
SET_BOOLBIT(mBitField, BF_DISABLED_CHANGED, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// When name or type changes, radio should be removed from radio group.
|
||||
// (type changes are handled in the form itself currently)
|
||||
// If the parser is not done creating the radio, we also should not do it.
|
||||
//
|
||||
if ((aName == nsHTMLAtoms::name || (aName == nsHTMLAtoms::type && !mForm)) &&
|
||||
mType == NS_FORM_INPUT_RADIO &&
|
||||
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
||||
WillRemoveFromRadioGroup();
|
||||
} else if (aNotify && aName == nsHTMLAtoms::src &&
|
||||
aValue && mType == NS_FORM_INPUT_IMAGE) {
|
||||
// Null value means the attr got unset; don't trigger on that
|
||||
ImageURIChanged(*aValue, PR_TRUE, aNotify);
|
||||
} else if (aNotify && aName == nsHTMLAtoms::disabled) {
|
||||
SET_BOOLBIT(mBitField, BF_DISABLED_CHANGED, PR_TRUE);
|
||||
}
|
||||
return nsGenericHTMLFormElement::BeforeSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, aValue, aNotify);
|
||||
|
||||
if (aNameSpaceID != kNameSpaceID_None) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// When name or type changes, radio should be added to radio group.
|
||||
// (type changes are handled in the form itself currently)
|
||||
// If the parser is not done creating the radio, we also should not do it.
|
||||
//
|
||||
if ((aName == nsHTMLAtoms::name || (aName == nsHTMLAtoms::type && !mForm)) &&
|
||||
mType == NS_FORM_INPUT_RADIO &&
|
||||
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
||||
AddedToRadioGroup();
|
||||
}
|
||||
|
||||
//
|
||||
// Some elements have to change their value when the value and checked
|
||||
// attributes change (but they only do so when ValueChanged() and
|
||||
// CheckedChanged() are false--i.e. the value has not been changed by the
|
||||
// user or by JS)
|
||||
//
|
||||
// We only really need to call reset for the value so that the text control
|
||||
// knows the new value. No other reason.
|
||||
//
|
||||
if (aName == nsHTMLAtoms::value &&
|
||||
!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) &&
|
||||
(mType == NS_FORM_INPUT_TEXT ||
|
||||
mType == NS_FORM_INPUT_PASSWORD ||
|
||||
mType == NS_FORM_INPUT_FILE)) {
|
||||
Reset();
|
||||
}
|
||||
//
|
||||
// Checked must be set no matter what type of control it is, since
|
||||
// GetChecked() must reflect the new value
|
||||
//
|
||||
if (aName == nsHTMLAtoms::checked &&
|
||||
!GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED)) {
|
||||
// Delay setting checked if the parser is creating this element (wait until
|
||||
// everything is set)
|
||||
if (GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) {
|
||||
SET_BOOLBIT(mBitField, BF_SHOULD_INIT_CHECKED, PR_TRUE);
|
||||
} else {
|
||||
PRBool defaultChecked;
|
||||
GetDefaultChecked(&defaultChecked);
|
||||
DoSetChecked(defaultChecked);
|
||||
SetCheckedChanged(PR_FALSE);
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
//
|
||||
// When name or type changes, radio should be added to radio group.
|
||||
// (type changes are handled in the form itself currently)
|
||||
// If the parser is not done creating the radio, we also should not do it.
|
||||
//
|
||||
if ((aName == nsHTMLAtoms::name ||
|
||||
(aName == nsHTMLAtoms::type && !mForm)) &&
|
||||
mType == NS_FORM_INPUT_RADIO &&
|
||||
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
||||
AddedToRadioGroup();
|
||||
}
|
||||
}
|
||||
|
||||
if (aName == nsHTMLAtoms::type) {
|
||||
if (!aValue) {
|
||||
// We're now a text input. Note that we have to handle this manually,
|
||||
// since removing an attribute (which is what happened, since aValue is
|
||||
// null) doesn't call ParseAttribute.
|
||||
mType = NS_FORM_INPUT_TEXT;
|
||||
//
|
||||
// Some elements have to change their value when the value and checked
|
||||
// attributes change (but they only do so when ValueChanged() and
|
||||
// CheckedChanged() are false--i.e. the value has not been changed by the
|
||||
// user or by JS)
|
||||
//
|
||||
// We only really need to call reset for the value so that the text control
|
||||
// knows the new value. No other reason.
|
||||
//
|
||||
if (aName == nsHTMLAtoms::value &&
|
||||
!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) &&
|
||||
(mType == NS_FORM_INPUT_TEXT ||
|
||||
mType == NS_FORM_INPUT_PASSWORD ||
|
||||
mType == NS_FORM_INPUT_FILE)) {
|
||||
Reset();
|
||||
}
|
||||
//
|
||||
// Checked must be set no matter what type of control it is, since
|
||||
// GetChecked() must reflect the new value
|
||||
//
|
||||
if (aName == nsHTMLAtoms::checked &&
|
||||
!GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED)) {
|
||||
// Delay setting checked if the parser is creating this element
|
||||
// (wait until everything is set)
|
||||
if (GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) {
|
||||
SET_BOOLBIT(mBitField, BF_SHOULD_INIT_CHECKED, PR_TRUE);
|
||||
} else {
|
||||
PRBool defaultChecked;
|
||||
GetDefaultChecked(&defaultChecked);
|
||||
DoSetChecked(defaultChecked);
|
||||
SetCheckedChanged(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (aName == nsHTMLAtoms::type) {
|
||||
if (!aValue) {
|
||||
// We're now a text input. Note that we have to handle this manually,
|
||||
// since removing an attribute (which is what happened, since aValue is
|
||||
// null) doesn't call ParseAttribute.
|
||||
mType = NS_FORM_INPUT_TEXT;
|
||||
}
|
||||
|
||||
// If we are changing type from File/Text/Passwd to other input types
|
||||
// we need save the mValue into value attribute
|
||||
if (mValue &&
|
||||
mType != NS_FORM_INPUT_TEXT &&
|
||||
mType != NS_FORM_INPUT_PASSWORD &&
|
||||
mType != NS_FORM_INPUT_FILE) {
|
||||
SetAttr(kNameSpaceID_None, nsHTMLAtoms::value,
|
||||
NS_ConvertUTF8toUCS2(mValue), PR_FALSE);
|
||||
if (mValue) {
|
||||
nsMemory::Free(mValue);
|
||||
mValue = nsnull;
|
||||
// If we are changing type from File/Text/Passwd to other input types
|
||||
// we need save the mValue into value attribute
|
||||
if (mValue &&
|
||||
mType != NS_FORM_INPUT_TEXT &&
|
||||
mType != NS_FORM_INPUT_PASSWORD &&
|
||||
mType != NS_FORM_INPUT_FILE) {
|
||||
SetAttr(kNameSpaceID_None, nsHTMLAtoms::value,
|
||||
NS_ConvertUTF8toUCS2(mValue), PR_FALSE);
|
||||
if (mValue) {
|
||||
nsMemory::Free(mValue);
|
||||
mValue = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mType != NS_FORM_INPUT_IMAGE) {
|
||||
// We're no longer an image input. Cancel our image requests, if we have
|
||||
// any. Note that doing this when we already weren't an image is ok --
|
||||
// just does nothing.
|
||||
CancelImageRequests(aNotify);
|
||||
} else if (aNotify) {
|
||||
// We just got switched to be an image input; we should see
|
||||
// whether we have an image to load;
|
||||
nsAutoString src;
|
||||
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, src);
|
||||
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
ImageURIChanged(src, PR_FALSE, aNotify);
|
||||
if (mType != NS_FORM_INPUT_IMAGE) {
|
||||
// We're no longer an image input. Cancel our image requests, if we have
|
||||
// any. Note that doing this when we already weren't an image is ok --
|
||||
// just does nothing.
|
||||
CancelImageRequests(aNotify);
|
||||
} else if (aNotify) {
|
||||
// We just got switched to be an image input; we should see
|
||||
// whether we have an image to load;
|
||||
nsAutoString src;
|
||||
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, src);
|
||||
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
ImageURIChanged(src, PR_FALSE, aNotify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
// nsIDOMHTMLInputElement
|
||||
|
|
|
@ -87,22 +87,6 @@ public:
|
|||
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
|
||||
AfterSetAttr(aNameSpaceID, aName, &aValue, aNotify);
|
||||
return rv;
|
||||
}
|
||||
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
|
@ -124,8 +108,8 @@ protected:
|
|||
/**
|
||||
* Called when an attribute has just been changed
|
||||
*/
|
||||
void AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
};
|
||||
|
||||
|
||||
|
@ -200,7 +184,7 @@ nsHTMLOptGroupElement::GetSelect(nsISelectElement **aSelectElement)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsHTMLOptGroupElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -213,6 +197,9 @@ nsHTMLOptGroupElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
NS_EVENT_STATE_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -114,22 +114,6 @@ public:
|
|||
// nsIContent
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
|
||||
AfterSetAttr(aNameSpaceID, aName, &aValue, aNotify);
|
||||
return rv;
|
||||
}
|
||||
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
|
@ -158,8 +142,8 @@ protected:
|
|||
/**
|
||||
* Called when an attribute has just been changed
|
||||
*/
|
||||
void AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
PRPackedBool mIsInitialized;
|
||||
PRPackedBool mIsSelected;
|
||||
};
|
||||
|
@ -511,7 +495,7 @@ nsHTMLOptionElement::GetSelect(nsIDOMHTMLSelectElement **aSelectElement) const
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsHTMLOptionElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
|
@ -524,6 +508,9 @@ nsHTMLOptionElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
NS_EVENT_STATE_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||
aNotify);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -138,62 +138,50 @@ nsSVGElement::GetClassAttributeName() const
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsSVGElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
||||
const nsAString& aValue,
|
||||
PRBool aNotify)
|
||||
nsSVGElement::BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aName);
|
||||
NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
|
||||
"Don't call SetAttr with unknown namespace");
|
||||
|
||||
nsresult rv;
|
||||
nsAutoString oldValue;
|
||||
PRBool hasListeners = PR_FALSE;
|
||||
PRBool modification = PR_FALSE;
|
||||
|
||||
PRInt32 index = mAttrsAndChildren.IndexOfAttr(aName, aNamespaceID);
|
||||
|
||||
if (IsInDoc()) {
|
||||
hasListeners = nsGenericElement::HasMutationListeners(this,
|
||||
NS_EVENT_BITS_MUTATION_ATTRMODIFIED);
|
||||
|
||||
// If we have no listeners and aNotify is false, we are almost certainly
|
||||
// coming from the content sink and will almost certainly have no previous
|
||||
// value. Even if we do, setting the value is cheap when we have no
|
||||
// listeners and don't plan to notify. The check for aNotify here is an
|
||||
// optimization, the check for haveListeners is a correctness issue.
|
||||
if (index >= 0 && (hasListeners || aNotify)) {
|
||||
modification = PR_TRUE;
|
||||
// don't do any update if old == new.
|
||||
mAttrsAndChildren.AttrAt(index)->ToString(oldValue);
|
||||
if (aValue.Equals(oldValue) &&
|
||||
aPrefix == mAttrsAndChildren.GetSafeAttrNameAt(index)->GetPrefix()) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an svg presentation attribute we need to map it into
|
||||
// the content stylerule.
|
||||
// XXX For some reason incremental mapping doesn't work, so for now
|
||||
// just delete the style rule and lazily reconstruct it in
|
||||
// GetContentStyleRule()
|
||||
if(aNamespaceID == kNameSpaceID_None && IsAttributeMapped(aName))
|
||||
if (aNamespaceID == kNameSpaceID_None && IsAttributeMapped(aName)) {
|
||||
mContentStyleRule = nsnull;
|
||||
|
||||
}
|
||||
|
||||
return nsGenericElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (IsEventName(aName) && aValue) {
|
||||
nsresult rv = AddScriptEventListener(GetEventNameForAttr(aName), *aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return nsGenericElement::AfterSetAttr(aNamespaceID, aName, aValue, aNotify);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGElement::ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
// Parse value
|
||||
nsAttrValue attrValue;
|
||||
nsCOMPtr<nsISVGValue> svg_value;
|
||||
if (index >= 0) {
|
||||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aAttribute);
|
||||
if (val) {
|
||||
// Found the attr in the list.
|
||||
const nsAttrValue* currVal = mAttrsAndChildren.AttrAt(index);
|
||||
if (currVal->Type() == nsAttrValue::eSVGValue) {
|
||||
svg_value = currVal->GetSVGValue();
|
||||
if (val->Type() == nsAttrValue::eSVGValue) {
|
||||
svg_value = val->GetSVGValue();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Could be a mapped attribute.
|
||||
svg_value = GetMappedAttribute(aNamespaceID, aName);
|
||||
svg_value = GetMappedAttribute(kNameSpaceID_None, aAttribute);
|
||||
}
|
||||
|
||||
if (svg_value) {
|
||||
|
@ -204,43 +192,29 @@ nsSVGElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
|||
// To accomodate this "erronous" value, we'll insert a proxy
|
||||
// object between ourselves and the actual value object:
|
||||
nsCOMPtr<nsISVGValue> proxy;
|
||||
rv = NS_CreateSVGStringProxyValue(svg_value, getter_AddRefs(proxy));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv =
|
||||
NS_CreateSVGStringProxyValue(svg_value, getter_AddRefs(proxy));
|
||||
// Failure means we'll store this attr as a string, not an SVGValue, but
|
||||
// that's the best we can do short of throwing outright.
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
svg_value->RemoveObserver(this);
|
||||
proxy->SetValueString(aValue);
|
||||
proxy->AddObserver(this);
|
||||
attrValue.SetTo(proxy);
|
||||
aResult.SetTo(proxy);
|
||||
}
|
||||
else {
|
||||
attrValue.SetTo(svg_value);
|
||||
aResult.SetTo(svg_value);
|
||||
}
|
||||
}
|
||||
else if (aName == nsSVGAtoms::style && aNamespaceID == kNameSpaceID_None) {
|
||||
nsGenericHTMLElement::ParseStyleAttribute(this, PR_TRUE, aValue, attrValue);
|
||||
}
|
||||
// We don't have an nsISVGValue attribute.
|
||||
else if (aName == nsSVGAtoms::id && aNamespaceID == kNameSpaceID_None){
|
||||
attrValue.ParseAtom(aValue);
|
||||
}
|
||||
else {
|
||||
attrValue.SetTo(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None && IsEventName(aName)) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
nsIAtom* eventName = GetEventNameForAttr(aName);
|
||||
nsIDocument *ownerDoc = GetOwnerDoc();
|
||||
manager->AddScriptEventListener(NS_STATIC_CAST(nsIContent*, this), eventName,
|
||||
aValue, PR_TRUE,
|
||||
!nsContentUtils::IsChromeDoc(ownerDoc));
|
||||
}
|
||||
if (aAttribute == nsSVGAtoms::style) {
|
||||
nsGenericHTMLElement::ParseStyleAttribute(this, PR_TRUE, aValue, aResult);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, attrValue,
|
||||
modification, hasListeners, aNotify);
|
||||
|
||||
return nsGenericElement::ParseAttribute(aAttribute, aValue, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -628,86 +602,6 @@ nsSVGElement::IsEventName(nsIAtom* aName)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGElement::SetAttrAndNotify(PRInt32 aNamespaceID, nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix, const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue, PRBool aModification,
|
||||
PRBool aFireMutation, PRBool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint8 modType = aModification ?
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::MODIFICATION) :
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::ADDITION);
|
||||
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||
if (aNotify && document) {
|
||||
document->AttributeWillChange(this, aNamespaceID, aAttribute);
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
// XXX doesn't check IsAttributeMapped here.
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(aAttribute, aParsedValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
rv = mNodeInfo->NodeInfoManager()->GetNodeInfo(aAttribute, aPrefix,
|
||||
aNamespaceID,
|
||||
getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (document) {
|
||||
nsXBLBinding *binding = document->BindingManager()->GetBinding(this);
|
||||
if (binding) {
|
||||
binding->AttributeChanged(aAttribute, aNamespaceID, PR_FALSE, aNotify);
|
||||
}
|
||||
|
||||
if (aFireMutation) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node = do_QueryInterface(NS_STATIC_CAST(nsIContent *, this));
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED, node);
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
nsAutoString newValue;
|
||||
// We don't really need to call GetAttr here, but lets try to keep this
|
||||
// code as similar to nsGenericHTMLElement::SetAttrAndNotify as possible
|
||||
// so that they can merge sometime in the future.
|
||||
GetAttr(aNamespaceID, aAttribute, newValue);
|
||||
if (!newValue.IsEmpty()) {
|
||||
mutation.mNewAttrValue = do_GetAtom(newValue);
|
||||
}
|
||||
if (!aOldValue.IsEmpty()) {
|
||||
mutation.mPrevAttrValue = do_GetAtom(aOldValue);
|
||||
}
|
||||
mutation.mAttrChange = modType;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
document->AttributeChanged(this, aNamespaceID, aAttribute, modType);
|
||||
}
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_XMLEvents &&
|
||||
aAttribute == nsHTMLAtoms::_event && GetOwnerDoc()) {
|
||||
GetOwnerDoc()->AddXMLEventsContent(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGElement::UpdateContentStyleRule()
|
||||
{
|
||||
|
|
|
@ -76,14 +76,6 @@ public:
|
|||
PRBool aNullParent = PR_TRUE);
|
||||
virtual nsIAtom *GetIDAttributeName() const;
|
||||
virtual nsIAtom *GetClassAttributeName() const;
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
|
@ -124,33 +116,17 @@ public:
|
|||
virtual void ParentChainChanged();
|
||||
|
||||
protected:
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
// Hooks for subclasses
|
||||
virtual PRBool IsEventName(nsIAtom* aName);
|
||||
|
||||
/**
|
||||
* Set attribute and (if needed) notify documentobservers and fire off
|
||||
* mutation events.
|
||||
*
|
||||
* @param aNamespaceID namespace of attribute
|
||||
* @param aAttribute local-name of attribute
|
||||
* @param aPrefix aPrefix of attribute
|
||||
* @param aOldValue previous value of attribute. Only needed if
|
||||
* aFireMutation is true.
|
||||
* @param aParsedValue parsed new value of attribute
|
||||
* @param aModification is this a attribute-modification or addition. Only
|
||||
* needed if aFireMutation or aNotify is true.
|
||||
* @param aFireMutation should mutation-events be fired?
|
||||
* @param aNotify should we notify document-observers?
|
||||
*/
|
||||
nsresult SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify);
|
||||
|
||||
void UpdateContentStyleRule();
|
||||
nsISVGValue* GetMappedAttribute(PRInt32 aNamespaceID, nsIAtom* aName);
|
||||
nsresult AddMappedSVGValue(nsIAtom* aName, nsISupports* aValue,
|
||||
|
|
|
@ -552,44 +552,36 @@ nsXULElement::MaybeTriggerAutoLink(nsIDocShell *aShell)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::AddScriptEventListener(nsIAtom* aName, const nsAString& aValue)
|
||||
nsXULElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
||||
nsISupports** aTarget,
|
||||
PRBool* aDefer)
|
||||
{
|
||||
// XXX sXBL/XBL2 issue! Owner or current document?
|
||||
// Note that If it's current, then we need to hook up listeners on the root
|
||||
// when we BindToTree...
|
||||
// XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc()
|
||||
// here, override BindToTree for those classes and munge event
|
||||
// listeners there?
|
||||
nsIDocument* doc = GetOwnerDoc();
|
||||
if (!doc)
|
||||
return NS_OK; // XXX
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsISupports *target = NS_STATIC_CAST(nsIContent *, this);
|
||||
PRBool defer = PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
return NS_ERROR_UNEXPECTED; // XXX
|
||||
|
||||
nsIContent *root = doc->GetRootContent();
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, this)));
|
||||
if ((!root || root == content) && !mNodeInfo->Equals(nsXULAtoms::overlay)) {
|
||||
if ((!root || root == this) && !mNodeInfo->Equals(nsXULAtoms::overlay)) {
|
||||
nsIScriptGlobalObject *global = doc->GetScriptGlobalObject();
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver = do_QueryInterface(global);
|
||||
if (! receiver)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
rv = receiver->GetListenerManager(getter_AddRefs(manager));
|
||||
|
||||
target = global;
|
||||
defer = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
rv = GetListenerManager(getter_AddRefs(manager));
|
||||
nsresult rv = receiver->GetListenerManager(aManager);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = global);
|
||||
}
|
||||
*aDefer = PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return manager->AddScriptEventListener(target, aName, aValue, defer,
|
||||
!nsContentUtils::IsChromeDoc(doc));
|
||||
return nsGenericElement::GetEventListenerManagerForAttr(aManager,
|
||||
aTarget,
|
||||
aDefer);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1195,185 +1187,79 @@ nsXULElement::UnregisterAccessKey(const nsAString& aOldValue)
|
|||
}
|
||||
}
|
||||
|
||||
// XXX attribute code swiped from nsGenericContainerElement
|
||||
// this class could probably just use nsGenericContainerElement
|
||||
// needed to maintain attribute namespace ID as well as ordering
|
||||
// NOTE: Changes to this function may need to be made in
|
||||
// |SetInlineStyleRule| as well.
|
||||
nsresult
|
||||
nsXULElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
nsXULElement::BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
nsAutoString oldValue;
|
||||
PRBool hasListeners = PR_FALSE;
|
||||
PRBool modification = PR_FALSE;
|
||||
|
||||
if (IsInDoc()) {
|
||||
PRBool isAccessKey = aName == nsXULAtoms::accesskey &&
|
||||
aNamespaceID == kNameSpaceID_None;
|
||||
hasListeners = nsGenericElement::HasMutationListeners(this,
|
||||
NS_EVENT_BITS_MUTATION_ATTRMODIFIED);
|
||||
|
||||
// If we have no listeners and aNotify is false, we are almost
|
||||
// certainly coming from the content sink and will almost certainly
|
||||
// have no previous value. Even if we do, setting the value is cheap
|
||||
// when we have no listeners and don't plan to notify. The check for
|
||||
// aNotify here is an optimization, the check for haveListeners is a
|
||||
// correctness issue.
|
||||
// The check for isAccessKey is so that we get the old value and can
|
||||
// unregister the old key.
|
||||
if (hasListeners || aNotify || isAccessKey) {
|
||||
// Don't do any update if old == new.
|
||||
const nsAttrValue* attrVal =
|
||||
mAttrsAndChildren.GetAttr(aName, aNamespaceID);
|
||||
if (attrVal) {
|
||||
modification = PR_TRUE;
|
||||
attrVal->ToString(oldValue);
|
||||
if (aValue.Equals(oldValue)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If the accesskey attribute changes, unregister it here. It will
|
||||
// be registered for the new value in the relevant frames. Also see
|
||||
// nsAreaFrame, nsBoxFrame and nsTextBoxFrame's AttributeChanged
|
||||
// If we want to merge with nsGenericElement then we could maybe
|
||||
// do this in WillChangeAttr instead. That is only called when
|
||||
// aNotify is true, but that might be enough.
|
||||
if (isAccessKey) {
|
||||
UnregisterAccessKey(oldValue);
|
||||
}
|
||||
if (aNamespaceID == kNameSpaceID_None && aName == nsXULAtoms::accesskey &&
|
||||
IsInDoc()) {
|
||||
const nsAttrValue* attrVal = FindLocalOrProtoAttr(aNamespaceID, aName);
|
||||
if (attrVal) {
|
||||
nsAutoString oldValue;
|
||||
attrVal->ToString(oldValue);
|
||||
UnregisterAccessKey(oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX UnsetAttr handles more attributes then we do. See bug 233642.
|
||||
return nsGenericElement::BeforeSetAttr(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
// Parse into a nsAttrValue
|
||||
|
||||
// WARNING!!
|
||||
// This code is largely duplicated in nsXULPrototypeElement::SetAttrAt.
|
||||
// Any changes should be made to both functions.
|
||||
nsAttrValue attrValue;
|
||||
nsresult
|
||||
nsXULElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsXULAtoms::style) {
|
||||
nsGenericHTMLElement::ParseStyleAttribute(this, PR_TRUE, aValue,
|
||||
attrValue);
|
||||
}
|
||||
else if (aName == nsXULAtoms::id &&
|
||||
!aValue.IsEmpty()) {
|
||||
// Store id as atom.
|
||||
// id="" means that the element has no id. Not that it has
|
||||
// emptystring as id.
|
||||
attrValue.ParseAtom(aValue);
|
||||
}
|
||||
else if (aName == nsXULAtoms::clazz) {
|
||||
attrValue.ParseAtomArray(aValue);
|
||||
}
|
||||
else {
|
||||
attrValue.ParseStringOrAtom(aValue);
|
||||
}
|
||||
// XXX UnsetAttr handles more attributes then we do. See bug 233642.
|
||||
|
||||
// Add popup and event listeners. We can't call AddListenerFor since
|
||||
// the attribute isn't set yet.
|
||||
MaybeAddPopupListener(aName);
|
||||
if (IsEventHandler(aName)) {
|
||||
AddScriptEventListener(aName, aValue);
|
||||
if (IsEventHandler(aName) && aValue) {
|
||||
AddScriptEventListener(aName, *aValue);
|
||||
}
|
||||
|
||||
// Hide chrome if needed
|
||||
if (aName == nsXULAtoms::hidechrome &&
|
||||
mNodeInfo->Equals(nsXULAtoms::window)) {
|
||||
HideWindowChrome(NS_LITERAL_STRING("true").Equals(aValue));
|
||||
HideWindowChrome(aValue && NS_LITERAL_STRING("true").Equals(*aValue));
|
||||
}
|
||||
|
||||
// XXX need to check if they're changing an event handler: if so, then we need
|
||||
// to unhook the old one.
|
||||
}
|
||||
else {
|
||||
attrValue.ParseStringOrAtom(aValue);
|
||||
// XXX need to check if they're changing an event handler: if
|
||||
// so, then we need to unhook the old one. Or something.
|
||||
}
|
||||
|
||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue,
|
||||
attrValue, modification, hasListeners, aNotify);
|
||||
return nsGenericElement::AfterSetAttr(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify)
|
||||
PRBool
|
||||
nsXULElement::ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint8 modType = aModification ?
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::MODIFICATION) :
|
||||
NS_STATIC_CAST(PRUint8, nsIDOMMutationEvent::ADDITION);
|
||||
// Parse into a nsAttrValue
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
|
||||
if (aNotify && doc) {
|
||||
doc->AttributeWillChange(this, aNamespaceID, aAttribute);
|
||||
// WARNING!!
|
||||
// This code is largely duplicated in nsXULPrototypeElement::SetAttrAt.
|
||||
// Any changes should be made to both functions.
|
||||
if (aAttribute == nsXULAtoms::style) {
|
||||
nsGenericHTMLElement::ParseStyleAttribute(this, PR_TRUE, aValue,
|
||||
aResult);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(aAttribute, aParsedValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
rv = mNodeInfo->NodeInfoManager()->GetNodeInfo(aAttribute, aPrefix,
|
||||
aNamespaceID,
|
||||
getter_AddRefs(ni));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aAttribute == nsXULAtoms::clazz) {
|
||||
aResult.ParseAtomArray(aValue);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
nsXBLBinding *binding = doc->BindingManager()->GetBinding(this);
|
||||
if (binding) {
|
||||
binding->AttributeChanged(aAttribute, aNamespaceID, PR_FALSE, aNotify);
|
||||
}
|
||||
|
||||
if (aFireMutation) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node =
|
||||
do_QueryInterface(NS_STATIC_CAST(nsIContent *, this));
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_ATTRMODIFIED, node);
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
nsAutoString newValue;
|
||||
// We don't really need to call GetAttr here, but lets do it
|
||||
// anyway to ease future codeshare with nsGenericHTMLElement
|
||||
// which has to call GetAttr here due to enums.
|
||||
GetAttr(aNamespaceID, aAttribute, newValue);
|
||||
if (!newValue.IsEmpty()) {
|
||||
mutation.mNewAttrValue = do_GetAtom(newValue);
|
||||
}
|
||||
if (!aOldValue.IsEmpty()) {
|
||||
mutation.mPrevAttrValue = do_GetAtom(aOldValue);
|
||||
}
|
||||
mutation.mAttrChange = modType;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
doc->AttributeChanged(this, aNamespaceID, aAttribute, modType);
|
||||
}
|
||||
if (!nsGenericElement::ParseAttribute(aAttribute, aValue, aResult)) {
|
||||
// Fall back to parsing as atom for short values
|
||||
aResult.ParseStringOrAtom(aValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
const nsAttrName*
|
||||
|
@ -2718,22 +2604,20 @@ NS_IMETHODIMP nsXULElement::HandleChromeEvent(nsPresContext* aPresContext,
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
const nsAttrValue*
|
||||
nsXULElement::FindLocalOrProtoAttr(PRInt32 aNamespaceID, nsIAtom *aName) const
|
||||
nsGenericElement::nsAttrInfo
|
||||
nsXULElement::GetAttrInfo(PRInt32 aNamespaceID, nsIAtom *aName) const
|
||||
{
|
||||
|
||||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNamespaceID);
|
||||
if (val) {
|
||||
return val;
|
||||
nsAttrInfo info(nsGenericElement::GetAttrInfo(aNamespaceID, aName));
|
||||
if (!info.mValue) {
|
||||
nsXULPrototypeAttribute *protoattr =
|
||||
FindPrototypeAttribute(aNamespaceID, aName);
|
||||
if (protoattr) {
|
||||
return nsAttrInfo(&protoattr->mName, &protoattr->mValue);
|
||||
}
|
||||
}
|
||||
|
||||
nsXULPrototypeAttribute *protoattr =
|
||||
FindPrototypeAttribute(aNamespaceID, aName);
|
||||
if (protoattr) {
|
||||
return &protoattr->mValue;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -478,13 +478,6 @@ public:
|
|||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsIAtom *GetIDAttributeName() const;
|
||||
virtual nsIAtom *GetClassAttributeName() const;
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
|
||||
const nsAString& aValue, PRBool aNotify);
|
||||
virtual nsresult GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAString& aResult) const;
|
||||
virtual PRBool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
|
||||
|
@ -548,8 +541,6 @@ public:
|
|||
{ UnsetFlags(aFlags << XUL_ELEMENT_LAZY_STATE_OFFSET); }
|
||||
PRBool GetLazyState(LazyState aFlag)
|
||||
{ return GetFlags() & (aFlag << XUL_ELEMENT_LAZY_STATE_OFFSET); }
|
||||
NS_HIDDEN_(nsresult) AddScriptEventListener(nsIAtom* aName,
|
||||
const nsAString& aValue);
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericElement::)
|
||||
|
@ -611,8 +602,31 @@ protected:
|
|||
*/
|
||||
nsresult MakeHeavyweight();
|
||||
|
||||
/**
|
||||
* Get the attr info for the given namespace ID and attribute name.
|
||||
* The namespace ID must not be kNameSpaceID_Unknown and the name
|
||||
* must not be null.
|
||||
*/
|
||||
virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
|
||||
|
||||
const nsAttrValue* FindLocalOrProtoAttr(PRInt32 aNameSpaceID,
|
||||
nsIAtom *aName) const;
|
||||
nsIAtom *aName) const {
|
||||
return nsXULElement::GetAttrInfo(aNameSpaceID, aName).mValue;
|
||||
}
|
||||
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
virtual nsresult
|
||||
GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
||||
nsISupports** aTarget,
|
||||
PRBool* aDefer);
|
||||
|
||||
/**
|
||||
* Return our prototype's attribute, if one exists.
|
||||
|
@ -629,16 +643,6 @@ protected:
|
|||
|
||||
nsresult HideWindowChrome(PRBool aShouldHide);
|
||||
|
||||
|
||||
nsresult SetAttrAndNotify(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aOldValue,
|
||||
nsAttrValue& aParsedValue,
|
||||
PRBool aModification,
|
||||
PRBool aFireMutation,
|
||||
PRBool aNotify);
|
||||
|
||||
const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const;
|
||||
|
||||
protected:
|
||||
|
|
Загрузка…
Ссылка в новой задаче