mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-02 21:37:32 +09:00
Bug 1365092 - Move side effects of SetAttr and ParseAttribute to BeforeSetAttr and AfterSetAttr
* Moves side effects of nsGenericHTMLElement and Element's SetAttr, UnsetAttr, and ParseAttribute functions to the corresponding BeforeSetAttr and AfterSetAttr functions * Moves side effects of HTMLAnchorElement's SetAttr, UnsetAttr, and ParseAttribute functions to the corresponding BeforeSetAttr and AfterSetAttr functions * Moves side effects of HTMLImageElement's SetAttr function to the corresponding BeforeSetAttr and AfterSetAttr functions * Moves side effects of SetAttr, UnsetAttr, and ParseAttribute functions to BeforeSetAttr and AfterSetAttr Tag #1375
This commit is contained in:
parent
9d8343e19c
commit
6aa436b588
41 changed files with 983 additions and 956 deletions
|
|
@ -2476,7 +2476,7 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
|
||||||
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||||
oldValue, &modType, &hasListeners, &oldValueSet)) {
|
oldValue, &modType, &hasListeners, &oldValueSet)) {
|
||||||
return NS_OK;
|
return OnAttrSetButNotChanged(aNamespaceID, aName, value, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAttrValue attrValue;
|
nsAttrValue attrValue;
|
||||||
|
|
@ -2494,20 +2494,21 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
preparsedAttrValue);
|
preparsedAttrValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Hold a script blocker while calling ParseAttribute since that can call
|
// Hold a script blocker while calling ParseAttribute since that can call
|
||||||
// out to id-observers
|
// out to id-observers
|
||||||
nsIDocument* document = GetComposedDoc();
|
nsIDocument* document = GetComposedDoc();
|
||||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||||
|
|
||||||
// Even the value was pre-parsed, we still need to call ParseAttribute because
|
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
|
||||||
// it can have side effects.
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
|
|
||||||
|
if (!preparsedAttrValue &&
|
||||||
|
!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
|
||||||
attrValue.SetTo(aValue);
|
attrValue.SetTo(aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreIdMaybeChange(aNamespaceID, aName, &value);
|
||||||
|
|
||||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
|
return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
|
||||||
oldValueSet ? &oldValue : nullptr,
|
oldValueSet ? &oldValue : nullptr,
|
||||||
attrValue, modType, hasListeners, aNotify,
|
attrValue, modType, hasListeners, aNotify,
|
||||||
|
|
@ -2538,7 +2539,7 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
|
||||||
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
if (OnlyNotifySameValueSet(aNamespaceID, aName, aPrefix, value, aNotify,
|
||||||
oldValue, &modType, &hasListeners, &oldValueSet)) {
|
oldValue, &modType, &hasListeners, &oldValueSet)) {
|
||||||
return NS_OK;
|
return OnAttrSetButNotChanged(aNamespaceID, aName, value, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aNotify) {
|
if (aNotify) {
|
||||||
|
|
@ -2549,6 +2550,8 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
|
nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PreIdMaybeChange(aNamespaceID, aName, &value);
|
||||||
|
|
||||||
nsIDocument* document = GetComposedDoc();
|
nsIDocument* document = GetComposedDoc();
|
||||||
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
mozAutoDocUpdate updateBatch(document, UPDATE_CONTENT_MODEL, aNotify);
|
||||||
return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
|
return SetAttrAndNotify(aNamespaceID, aName, aPrefix,
|
||||||
|
|
@ -2608,6 +2611,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID,
|
||||||
}
|
}
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PostIdMaybeChange(aNamespaceID, aName, &valueForAfterSetAttr);
|
||||||
|
|
||||||
// If the old value owns its own data, we know it is OK to keep using it.
|
// If the old value owns its own data, we know it is OK to keep using it.
|
||||||
// oldValue will be null if there was no previously set value
|
// oldValue will be null if there was no previously set value
|
||||||
const nsAttrValue* oldValue;
|
const nsAttrValue* oldValue;
|
||||||
|
|
@ -2720,22 +2725,16 @@ Element::ParseAttribute(int32_t aNamespaceID,
|
||||||
nsAttrValue& aResult)
|
nsAttrValue& aResult)
|
||||||
{
|
{
|
||||||
if (aNamespaceID == kNameSpaceID_None) {
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
if (aAttribute == nsGkAtoms::_class) {
|
MOZ_ASSERT(aAttribute != nsGkAtoms::_class,
|
||||||
SetMayHaveClass();
|
"The class attribute should be preparsed and therefore should "
|
||||||
// Result should have been preparsed above.
|
"never be passed to Element::ParseAttribute");
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (aAttribute == nsGkAtoms::id) {
|
if (aAttribute == nsGkAtoms::id) {
|
||||||
// Store id as an atom. id="" means that the element has no id,
|
// Store id as an atom. id="" means that the element has no id,
|
||||||
// not that it has an emptystring as the id.
|
// not that it has an emptystring as the id.
|
||||||
RemoveFromIdTable();
|
|
||||||
if (aValue.IsEmpty()) {
|
if (aValue.IsEmpty()) {
|
||||||
ClearHasID();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
aResult.ParseAtom(aValue);
|
aResult.ParseAtom(aValue);
|
||||||
SetHasID();
|
|
||||||
AddToIdTable(aResult.GetAtomValue());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2754,6 +2753,57 @@ Element::SetAndSwapMappedAttribute(nsIDocument* aDocument,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Element::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue, bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
if (aName == nsGkAtoms::_class) {
|
||||||
|
if (aValue) {
|
||||||
|
// Note: This flag is asymmetrical. It is never unset and isn't exact.
|
||||||
|
// If it is ever made to be exact, we probably need to handle this
|
||||||
|
// similarly to how ids are handled in PreIdMaybeChange and
|
||||||
|
// PostIdMaybeChange.
|
||||||
|
SetMayHaveClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Element::PreIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue)
|
||||||
|
{
|
||||||
|
if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RemoveFromIdTable();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Element::PostIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue)
|
||||||
|
{
|
||||||
|
if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// id="" means that the element has no id, not that it has an empty
|
||||||
|
// string as the id.
|
||||||
|
if (aValue && !aValue->IsEmptyString()) {
|
||||||
|
SetHasID();
|
||||||
|
AddToIdTable(aValue->GetAtomValue());
|
||||||
|
} else {
|
||||||
|
ClearHasID();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EventListenerManager*
|
EventListenerManager*
|
||||||
Element::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
|
Element::GetEventListenerManagerForAttr(nsIAtom* aAttrName,
|
||||||
bool* aDefer)
|
bool* aDefer)
|
||||||
|
|
@ -2847,6 +2897,8 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
|
NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
PreIdMaybeChange(aNameSpaceID, aName, nullptr);
|
||||||
|
|
||||||
// Grab the attr node if needed before we remove it from the attr map
|
// Grab the attr node if needed before we remove it from the attr map
|
||||||
RefPtr<Attr> attrNode;
|
RefPtr<Attr> attrNode;
|
||||||
if (hasMutationListeners) {
|
if (hasMutationListeners) {
|
||||||
|
|
@ -2865,12 +2917,6 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
// react to unexpected attribute changes.
|
// react to unexpected attribute changes.
|
||||||
nsMutationGuard::DidMutate();
|
nsMutationGuard::DidMutate();
|
||||||
|
|
||||||
if (aName == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) {
|
|
||||||
// Have to do this before clearing flag. See RemoveFromIdTable
|
|
||||||
RemoveFromIdTable();
|
|
||||||
ClearHasID();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hadValidDir = false;
|
bool hadValidDir = false;
|
||||||
bool hadDirAuto = false;
|
bool hadDirAuto = false;
|
||||||
|
|
||||||
|
|
@ -2883,6 +2929,8 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
rv = mAttrsAndChildren.RemoveAttrAt(index, oldValue);
|
rv = mAttrsAndChildren.RemoveAttrAt(index, oldValue);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PostIdMaybeChange(aNameSpaceID, aName, nullptr);
|
||||||
|
|
||||||
if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
|
if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
|
||||||
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
RefPtr<nsXBLBinding> binding = GetXBLBinding();
|
||||||
if (binding) {
|
if (binding) {
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,7 @@ public:
|
||||||
already_AddRefed<mozilla::dom::NodeInfo>
|
already_AddRefed<mozilla::dom::NodeInfo>
|
||||||
GetExistingAttrNameFromQName(const nsAString& aStr) const;
|
GetExistingAttrNameFromQName(const nsAString& aStr) const;
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE // Avoid a crashy hook from Avast 10 Beta (Bug 1058131)
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAString& aValue, bool aNotify)
|
const nsAString& aValue, bool aNotify)
|
||||||
{
|
{
|
||||||
|
|
@ -1378,14 +1379,9 @@ protected:
|
||||||
* will be null.
|
* will be null.
|
||||||
* @param aNotify Whether we plan to notify document observers.
|
* @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(int32_t aNamespaceID, nsIAtom* aName,
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
const nsAttrValueOrString* aValue,
|
const nsAttrValueOrString* aValue,
|
||||||
bool aNotify)
|
bool aNotify);
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook that is called by Element::SetAttr to allow subclasses to
|
* Hook that is called by Element::SetAttr to allow subclasses to
|
||||||
|
|
@ -1412,6 +1408,64 @@ protected:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function shall be called just before the id attribute changes. It will
|
||||||
|
* be called after BeforeSetAttr. If the attribute being changed is not the id
|
||||||
|
* attribute, this function does nothing. Otherwise, it will remove the old id
|
||||||
|
* from the document's id cache.
|
||||||
|
*
|
||||||
|
* This must happen after BeforeSetAttr (rather than during) because the
|
||||||
|
* the subclasses' calls to BeforeSetAttr may notify on state changes. If they
|
||||||
|
* incorrectly determine whether the element had an id, the element may not be
|
||||||
|
* restyled properly.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aValue the new id value. Will be null if the id is being unset.
|
||||||
|
*/
|
||||||
|
void PreIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function shall be called just after the id attribute changes. It will
|
||||||
|
* be called before AfterSetAttr. If the attribute being changed is not the id
|
||||||
|
* attribute, this function does nothing. Otherwise, it will add the new id to
|
||||||
|
* the document's id cache and properly set the ElementHasID flag.
|
||||||
|
*
|
||||||
|
* This must happen before AfterSetAttr (rather than during) because the
|
||||||
|
* the subclasses' calls to AfterSetAttr may notify on state changes. If they
|
||||||
|
* incorrectly determine whether the element now has an id, the element may
|
||||||
|
* not be restyled properly.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aValue the new id value. Will be null if the id is being unset.
|
||||||
|
*/
|
||||||
|
void PostIdMaybeChange(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usually, setting an attribute to the value that it already has results in
|
||||||
|
* no action. However, in some cases, setting an attribute to its current
|
||||||
|
* value should have the effect of, for example, forcing a reload of
|
||||||
|
* network data. To address that, this function will be called in this
|
||||||
|
* situation to allow the handling of such a case.
|
||||||
|
*
|
||||||
|
* @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 represented as either a string or
|
||||||
|
* a parsed nsAttrValue.
|
||||||
|
* @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 OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to allow subclasses to produce a different EventListenerManager if
|
* Hook to allow subclasses to produce a different EventListenerManager if
|
||||||
* needed for attachment of attribute-defined handlers
|
* needed for attachment of attribute-defined handlers
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,20 @@ public:
|
||||||
return aOther.EqualsAsStrings(*mAttrValue);
|
return aOther.EqualsAsStrings(*mAttrValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if the value stored is empty
|
||||||
|
*/
|
||||||
|
bool IsEmpty() const
|
||||||
|
{
|
||||||
|
if (mStringPtr) {
|
||||||
|
return mStringPtr->IsEmpty();
|
||||||
|
}
|
||||||
|
if (mAttrValue) {
|
||||||
|
return mAttrValue->IsEmptyString();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const nsAttrValue* mAttrValue;
|
const nsAttrValue* mAttrValue;
|
||||||
mutable const nsAString* mStringPtr;
|
mutable const nsAString* mStringPtr;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ nsStyledElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
nsAttrValue& aResult)
|
nsAttrValue& aResult)
|
||||||
{
|
{
|
||||||
if (aAttribute == nsGkAtoms::style && aNamespaceID == kNameSpaceID_None) {
|
if (aAttribute == nsGkAtoms::style && aNamespaceID == kNameSpaceID_None) {
|
||||||
SetMayHaveStyle();
|
|
||||||
ParseStyleAttribute(aValue, aResult, false);
|
ParseStyleAttribute(aValue, aResult, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +48,22 @@ nsStyledElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
aResult);
|
aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsStyledElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue, bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
if (aName == nsGkAtoms::style) {
|
||||||
|
if (aValue) {
|
||||||
|
SetMayHaveStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsStyledElementBase::BeforeSetAttr(aNamespaceID, aName, aValue,
|
||||||
|
aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||||
const nsAString* aSerialized,
|
const nsAString* aSerialized,
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,10 @@ protected:
|
||||||
* document.
|
* document.
|
||||||
*/
|
*/
|
||||||
nsresult ReparseStyleAttribute(bool aForceInDataDoc);
|
nsresult ReparseStyleAttribute(bool aForceInDataDoc);
|
||||||
|
|
||||||
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsStyledElement, NS_STYLED_ELEMENT_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsStyledElement, NS_STYLED_ELEMENT_IID)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsHTMLDNSPrefetch.h"
|
#include "nsHTMLDNSPrefetch.h"
|
||||||
|
#include "nsAttrValueOrString.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
|
|
@ -372,84 +373,37 @@ HTMLAnchorElement::GetHrefURI() const
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLAnchorElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLAnchorElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValueOrString* aValue,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
bool reset = false;
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
|
if (aName == nsGkAtoms::href) {
|
||||||
// If we do not have a cached URI, we have some value here so we must reset
|
|
||||||
// our link state after calling the parent.
|
|
||||||
if (!Link::HasCachedURI()) {
|
|
||||||
reset = true;
|
|
||||||
}
|
|
||||||
// However, if we have a cached URI, we'll want to see if the value changed.
|
|
||||||
else {
|
|
||||||
nsAutoString val;
|
|
||||||
GetHref(val);
|
|
||||||
if (!val.Equals(aValue)) {
|
|
||||||
reset = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reset) {
|
|
||||||
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
|
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
|
||||||
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
|
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue,
|
||||||
aValue, aNotify);
|
aNotify);
|
||||||
|
|
||||||
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
|
|
||||||
// is important here! The attribute is not set until SetAttr returns, and
|
|
||||||
// we will need the updated attribute value because notifying the document
|
|
||||||
// that content states have changed will call IntrinsicState, which will try
|
|
||||||
// to get updated information about the visitedness from Link.
|
|
||||||
if (reset) {
|
|
||||||
Link::ResetLinkState(!!aNotify, true);
|
|
||||||
if (IsInComposedDoc()) {
|
|
||||||
TryDNSPrefetch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLAnchorElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
HTMLAnchorElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
bool aNotify)
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
bool href =
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
(aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID);
|
if (aName == nsGkAtoms::href) {
|
||||||
|
Link::ResetLinkState(aNotify, !!aValue);
|
||||||
if (href) {
|
if (aValue && IsInComposedDoc()) {
|
||||||
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
|
TryDNSPrefetch();
|
||||||
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
|
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName,
|
||||||
aNotify);
|
aValue, aOldValue, aNotify);
|
||||||
|
|
||||||
// The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
|
|
||||||
// is important here! The attribute is not unset until UnsetAttr returns, and
|
|
||||||
// we will need the updated attribute value because notifying the document
|
|
||||||
// that content states have changed will call IntrinsicState, which will try
|
|
||||||
// to get updated information about the visitedness from Link.
|
|
||||||
if (href) {
|
|
||||||
Link::ResetLinkState(!!aNotify, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
HTMLAnchorElement::ParseAttribute(int32_t aNamespaceID,
|
|
||||||
nsIAtom* aAttribute,
|
|
||||||
const nsAString& aValue,
|
|
||||||
nsAttrValue& aResult)
|
|
||||||
{
|
|
||||||
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
|
|
||||||
aResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventStates
|
EventStates
|
||||||
|
|
|
||||||
|
|
@ -66,20 +66,13 @@ public:
|
||||||
virtual void GetLinkTarget(nsAString& aTarget) override;
|
virtual void GetLinkTarget(nsAString& aTarget) override;
|
||||||
virtual already_AddRefed<nsIURI> GetHrefURI() const override;
|
virtual already_AddRefed<nsIURI> GetHrefURI() const override;
|
||||||
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
const nsAString& aValue, bool aNotify)
|
const nsAttrValueOrString* aValue,
|
||||||
{
|
bool aNotify) override;
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
}
|
const nsAttrValue* aValue,
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
const nsAttrValue* aOldValue,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
bool aNotify) override;
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual bool ParseAttribute(int32_t aNamespaceID,
|
|
||||||
nsIAtom* aAttribute,
|
|
||||||
const nsAString& aValue,
|
|
||||||
nsAttrValue& aResult) override;
|
|
||||||
|
|
||||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,42 +153,22 @@ HTMLAreaElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLAreaElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLAreaElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv =
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, aNotify);
|
// This must happen after the attribute is set. We will need the updated
|
||||||
|
// attribute value because notifying the document that content states have
|
||||||
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
|
// changed will call IntrinsicState, which will try to get updated
|
||||||
// is important here! The attribute is not set until SetAttr returns, and
|
// information about the visitedness from Link.
|
||||||
// we will need the updated attribute value because notifying the document
|
if (aName == nsGkAtoms::href) {
|
||||||
// that content states have changed will call IntrinsicState, which will try
|
Link::ResetLinkState(aNotify, !!aValue);
|
||||||
// to get updated information about the visitedness from Link.
|
}
|
||||||
if (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None) {
|
|
||||||
Link::ResetLinkState(!!aNotify, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||||
}
|
aOldValue, aNotify);
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLAreaElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
|
|
||||||
aNotify);
|
|
||||||
|
|
||||||
// The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
|
|
||||||
// is important here! The attribute is not unset until UnsetAttr returns, and
|
|
||||||
// we will need the updated attribute value because notifying the document
|
|
||||||
// that content states have changed will call IntrinsicState, which will try
|
|
||||||
// to get updated information about the visitedness from Link.
|
|
||||||
if (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
|
|
||||||
Link::ResetLinkState(!!aNotify, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IMPL_URI_PART(_part) \
|
#define IMPL_URI_PART(_part) \
|
||||||
|
|
|
||||||
|
|
@ -56,16 +56,6 @@ public:
|
||||||
bool aCompileEventHandlers) override;
|
bool aCompileEventHandlers) override;
|
||||||
virtual void UnbindFromTree(bool aDeep = true,
|
virtual void UnbindFromTree(bool aDeep = true,
|
||||||
bool aNullParent = true) override;
|
bool aNullParent = true) override;
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
||||||
|
|
||||||
|
|
@ -186,6 +176,11 @@ protected:
|
||||||
|
|
||||||
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
RefPtr<nsDOMTokenList > mRelList;
|
RefPtr<nsDOMTokenList > mRelList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -446,38 +446,37 @@ NS_IMPL_UINT_ATTR_DEFAULT_VALUE(HTMLCanvasElement, Height, height, DEFAULT_CANVA
|
||||||
NS_IMPL_BOOL_ATTR(HTMLCanvasElement, MozOpaque, moz_opaque)
|
NS_IMPL_BOOL_ATTR(HTMLCanvasElement, MozOpaque, moz_opaque)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLCanvasElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLCanvasElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
aNotify);
|
|
||||||
if (NS_SUCCEEDED(rv) && mCurrentContext &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
(aName == nsGkAtoms::width || aName == nsGkAtoms::height || aName == nsGkAtoms::moz_opaque))
|
|
||||||
{
|
|
||||||
ErrorResult dummy;
|
|
||||||
rv = UpdateContext(nullptr, JS::NullHandleValue, dummy);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||||
|
aOldValue, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLCanvasElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLCanvasElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
bool aNotify)
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify);
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
if (NS_SUCCEEDED(rv) && mCurrentContext &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
(aName == nsGkAtoms::width || aName == nsGkAtoms::height || aName == nsGkAtoms::moz_opaque))
|
aValue, aNotify);
|
||||||
{
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLCanvasElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (mCurrentContext && aNamespaceID == kNameSpaceID_None &&
|
||||||
|
(aName == nsGkAtoms::width || aName == nsGkAtoms::height ||
|
||||||
|
aName == nsGkAtoms::moz_opaque)) {
|
||||||
ErrorResult dummy;
|
ErrorResult dummy;
|
||||||
rv = UpdateContext(nullptr, JS::NullHandleValue, dummy);
|
UpdateContext(nullptr, JS::NullHandleValue, dummy);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
}
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -295,20 +295,6 @@ public:
|
||||||
nsAttrValue& aResult) override;
|
nsAttrValue& aResult) override;
|
||||||
nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, int32_t aModType) const override;
|
nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, int32_t aModType) const override;
|
||||||
|
|
||||||
// SetAttr override. C++ is stupid, so have to override both
|
|
||||||
// overloaded methods.
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
||||||
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
||||||
|
|
||||||
|
|
@ -373,6 +359,14 @@ protected:
|
||||||
nsISupports** aResult);
|
nsISupports** aResult);
|
||||||
void CallPrintCallback();
|
void CallPrintCallback();
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
AsyncCanvasRenderer* GetAsyncCanvasRenderer();
|
AsyncCanvasRenderer* GetAsyncCanvasRenderer();
|
||||||
|
|
||||||
bool mResetLayer;
|
bool mResetLayer;
|
||||||
|
|
@ -406,6 +400,18 @@ public:
|
||||||
CanvasContextType GetCurrentContextType() {
|
CanvasContextType GetCurrentContextType() {
|
||||||
return mCurrentContextType;
|
return mCurrentContextType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* This function will be called by AfterSetAttr whether the attribute is being
|
||||||
|
* set or unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName, bool aNotify);
|
||||||
};
|
};
|
||||||
|
|
||||||
class HTMLCanvasPrintState final : public nsWrapperCache
|
class HTMLCanvasPrintState final : public nsWrapperCache
|
||||||
|
|
|
||||||
|
|
@ -210,75 +210,63 @@ IsValidContentSelectors(nsCSSSelector* aSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLContentElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLContentElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::select) {
|
||||||
aValue, aNotify);
|
if (aValue) {
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
// Select attribute was updated, the insertion point may match different
|
||||||
|
// elements.
|
||||||
|
nsIDocument* doc = OwnerDoc();
|
||||||
|
nsCSSParser parser(doc->CSSLoader());
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::select) {
|
mValidSelector = true;
|
||||||
// Select attribute was updated, the insertion point may match different
|
mSelectorList = nullptr;
|
||||||
// elements.
|
|
||||||
nsIDocument* doc = OwnerDoc();
|
|
||||||
nsCSSParser parser(doc->CSSLoader());
|
|
||||||
|
|
||||||
mValidSelector = true;
|
nsAutoString valueStr;
|
||||||
mSelectorList = nullptr;
|
aValue->ToString(valueStr);
|
||||||
|
nsresult rv = parser.ParseSelectorString(valueStr,
|
||||||
|
doc->GetDocumentURI(),
|
||||||
|
// Bug 11240
|
||||||
|
0, // XXX get the line number!
|
||||||
|
getter_Transfers(mSelectorList));
|
||||||
|
|
||||||
nsresult rv = parser.ParseSelectorString(aValue,
|
// We don't want to return an exception if parsing failed because
|
||||||
doc->GetDocumentURI(),
|
// the spec does not define it as an exception case.
|
||||||
// Bug 11240
|
if (NS_SUCCEEDED(rv)) {
|
||||||
0, // XXX get the line number!
|
// Ensure that all the selectors are valid
|
||||||
getter_Transfers(mSelectorList));
|
nsCSSSelectorList* selectors = mSelectorList;
|
||||||
|
while (selectors) {
|
||||||
// We don't want to return an exception if parsing failed because
|
if (!IsValidContentSelectors(selectors->mSelectors)) {
|
||||||
// the spec does not define it as an exception case.
|
// If we have an invalid selector, we can not match anything.
|
||||||
if (NS_SUCCEEDED(rv)) {
|
mValidSelector = false;
|
||||||
// Ensure that all the selectors are valid
|
mSelectorList = nullptr;
|
||||||
nsCSSSelectorList* selectors = mSelectorList;
|
break;
|
||||||
while (selectors) {
|
}
|
||||||
if (!IsValidContentSelectors(selectors->mSelectors)) {
|
selectors = selectors->mNext;
|
||||||
// If we have an invalid selector, we can not match anything.
|
|
||||||
mValidSelector = false;
|
|
||||||
mSelectorList = nullptr;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
selectors = selectors->mNext;
|
}
|
||||||
|
|
||||||
|
ShadowRoot* containingShadow = GetContainingShadow();
|
||||||
|
if (containingShadow) {
|
||||||
|
containingShadow->DistributeAllNodes();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The select attribute was removed. This insertion point becomes
|
||||||
|
// a universal selector.
|
||||||
|
mValidSelector = true;
|
||||||
|
mSelectorList = nullptr;
|
||||||
|
|
||||||
|
ShadowRoot* containingShadow = GetContainingShadow();
|
||||||
|
if (containingShadow) {
|
||||||
|
containingShadow->DistributeAllNodes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShadowRoot* containingShadow = GetContainingShadow();
|
|
||||||
if (containingShadow) {
|
|
||||||
containingShadow->DistributeAllNodes();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||||
}
|
aOldValue, aNotify);
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLContentElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID,
|
|
||||||
aAttribute, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::select) {
|
|
||||||
// The select attribute was removed. This insertion point becomes
|
|
||||||
// a universal selector.
|
|
||||||
mValidSelector = true;
|
|
||||||
mSelectorList = nullptr;
|
|
||||||
|
|
||||||
ShadowRoot* containingShadow = GetContainingShadow();
|
|
||||||
if (containingShadow) {
|
|
||||||
containingShadow->DistributeAllNodes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -63,13 +63,6 @@ public:
|
||||||
void InsertMatchedNode(uint32_t aIndex, nsIContent* aContent);
|
void InsertMatchedNode(uint32_t aIndex, nsIContent* aContent);
|
||||||
void ClearMatchedNodes();
|
void ClearMatchedNodes();
|
||||||
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
// WebIDL methods.
|
// WebIDL methods.
|
||||||
already_AddRefed<DistributedContentList> GetDistributedNodes();
|
already_AddRefed<DistributedContentList> GetDistributedNodes();
|
||||||
void GetSelect(nsAString& aSelect)
|
void GetSelect(nsAString& aSelect)
|
||||||
|
|
@ -95,6 +88,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
void UpdateFallbackDistribution();
|
void UpdateFallbackDistribution();
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of nodes from the ShadowRoot host that match the
|
* An array of nodes from the ShadowRoot host that match the
|
||||||
* content insertion selector.
|
* content insertion selector.
|
||||||
|
|
|
||||||
|
|
@ -189,27 +189,31 @@ HTMLFormElement::GetElements(nsIDOMHTMLCollection** aElements)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLFormElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLFormElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValueOrString* aValue, bool aNotify)
|
||||||
bool aNotify)
|
|
||||||
{
|
{
|
||||||
if ((aName == nsGkAtoms::action || aName == nsGkAtoms::target) &&
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
aNameSpaceID == kNameSpaceID_None) {
|
if (aName == nsGkAtoms::action || aName == nsGkAtoms::target) {
|
||||||
if (mPendingSubmission) {
|
// This check is mostly to preserve previous behavior.
|
||||||
// aha, there is a pending submission that means we're in
|
if (aValue) {
|
||||||
// the script and we need to flush it. let's tell it
|
if (mPendingSubmission) {
|
||||||
// that the event was ignored to force the flush.
|
// aha, there is a pending submission that means we're in
|
||||||
// the second argument is not playing a role at all.
|
// the script and we need to flush it. let's tell it
|
||||||
FlushPendingSubmission();
|
// that the event was ignored to force the flush.
|
||||||
|
// the second argument is not playing a role at all.
|
||||||
|
FlushPendingSubmission();
|
||||||
|
}
|
||||||
|
// Don't forget we've notified the password manager already if the
|
||||||
|
// page sets the action/target in the during submit. (bug 343182)
|
||||||
|
bool notifiedObservers = mNotifiedObservers;
|
||||||
|
ForgetCurrentSubmission();
|
||||||
|
mNotifiedObservers = notifiedObservers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Don't forget we've notified the password manager already if the
|
|
||||||
// page sets the action/target in the during submit. (bug 343182)
|
|
||||||
bool notifiedObservers = mNotifiedObservers;
|
|
||||||
ForgetCurrentSubmission();
|
|
||||||
mNotifiedObservers = notifiedObservers;
|
|
||||||
}
|
}
|
||||||
return nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
|
||||||
aNotify);
|
return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue,
|
||||||
|
aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
||||||
|
|
@ -105,14 +105,9 @@ public:
|
||||||
bool aCompileEventHandlers) override;
|
bool aCompileEventHandlers) override;
|
||||||
virtual void UnbindFromTree(bool aDeep = true,
|
virtual void UnbindFromTree(bool aDeep = true,
|
||||||
bool aNullParent = true) override;
|
bool aNullParent = true) override;
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
const nsAString& aValue, bool aNotify)
|
const nsAttrValueOrString* aValue,
|
||||||
{
|
bool aNotify) override;
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue,
|
const nsAttrValue* aOldValue,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "mozilla/dom/EventHandlerBinding.h"
|
#include "mozilla/dom/EventHandlerBinding.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "mozilla/UniquePtrExtensions.h"
|
#include "mozilla/UniquePtrExtensions.h"
|
||||||
|
#include "nsAttrValueOrString.h"
|
||||||
|
|
||||||
NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
|
NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
|
||||||
|
|
||||||
|
|
@ -65,43 +66,45 @@ HTMLFrameSetElement::GetRows(nsAString& aRows)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLFrameSetElement::SetAttr(int32_t aNameSpaceID,
|
HTMLFrameSetElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aAttribute,
|
const nsAttrValueOrString* aValue,
|
||||||
nsIAtom* aPrefix,
|
bool aNotify)
|
||||||
const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
{
|
||||||
nsresult rv;
|
|
||||||
/* The main goal here is to see whether the _number_ of rows or
|
/* The main goal here is to see whether the _number_ of rows or
|
||||||
* columns has changed. If it has, we need to reframe; otherwise
|
* columns has changed. If it has, we need to reframe; otherwise
|
||||||
* we want to reflow. So we set mCurrentRowColHint here, then call
|
* we want to reflow.
|
||||||
* nsGenericHTMLElement::SetAttr, which will end up calling
|
* Ideally, the style hint would be changed back to reflow after the reframe
|
||||||
* GetAttributeChangeHint and notifying layout with that hint.
|
* has been performed. Unfortunately, however, the reframe will be performed
|
||||||
* Once nsGenericHTMLElement::SetAttr returns, we want to go back to our
|
* by the call to nsNodeUtils::AttributeChanged, which occurs *after*
|
||||||
* normal hint, which is NS_STYLE_HINT_REFLOW.
|
* AfterSetAttr is called, leaving us with no convenient way of changing the
|
||||||
|
* value back to reflow afterwards. However, nsNodeUtils::AttributeChanged is
|
||||||
|
* effectively the only consumer of this value, so as long as we always set
|
||||||
|
* the value correctly here, we should be fine.
|
||||||
*/
|
*/
|
||||||
if (aAttribute == nsGkAtoms::rows && aNameSpaceID == kNameSpaceID_None) {
|
mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
|
||||||
int32_t oldRows = mNumRows;
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
ParseRowCol(aValue, mNumRows, &mRowSpecs);
|
if (aName == nsGkAtoms::rows) {
|
||||||
|
if (aValue) {
|
||||||
|
int32_t oldRows = mNumRows;
|
||||||
|
ParseRowCol(aValue->String(), mNumRows, &mRowSpecs);
|
||||||
|
|
||||||
if (mNumRows != oldRows) {
|
if (mNumRows != oldRows) {
|
||||||
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
||||||
}
|
}
|
||||||
} else if (aAttribute == nsGkAtoms::cols &&
|
}
|
||||||
aNameSpaceID == kNameSpaceID_None) {
|
} else if (aName == nsGkAtoms::cols) {
|
||||||
int32_t oldCols = mNumCols;
|
if (aValue) {
|
||||||
ParseRowCol(aValue, mNumCols, &mColSpecs);
|
int32_t oldCols = mNumCols;
|
||||||
|
ParseRowCol(aValue->String(), mNumCols, &mColSpecs);
|
||||||
|
|
||||||
if (mNumCols != oldCols) {
|
if (mNumCols != oldCols) {
|
||||||
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aAttribute, aPrefix,
|
return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
|
||||||
aValue, aNotify);
|
|
||||||
mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
||||||
|
|
@ -100,17 +100,6 @@ public:
|
||||||
#undef WINDOW_EVENT_HELPER
|
#undef WINDOW_EVENT_HELPER
|
||||||
#undef EVENT
|
#undef EVENT
|
||||||
|
|
||||||
// These override the SetAttr methods in nsGenericHTMLElement (need
|
|
||||||
// both here to silence compiler warnings).
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetRowSpec is used to get the "rows" spec.
|
* GetRowSpec is used to get the "rows" spec.
|
||||||
* @param out int32_t aNumValues The number of row sizes specified.
|
* @param out int32_t aNumValues The number of row sizes specified.
|
||||||
|
|
@ -143,6 +132,10 @@ protected:
|
||||||
|
|
||||||
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult ParseRowCol(const nsAString& aValue,
|
nsresult ParseRowCol(const nsAString& aValue,
|
||||||
int32_t& aNumSpecs,
|
int32_t& aNumSpecs,
|
||||||
|
|
|
||||||
|
|
@ -181,55 +181,50 @@ HTMLIFrameElement::GetAttributeMappingFunction() const
|
||||||
return &MapAttributesIntoRule;
|
return &MapAttributesIntoRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLIFrameElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsGenericHTMLFrameElement::SetAttr(aNameSpaceID, aName,
|
|
||||||
aPrefix, aValue, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::srcdoc) {
|
|
||||||
// Don't propagate error here. The attribute was successfully set, that's
|
|
||||||
// what we should reflect.
|
|
||||||
LoadSrc();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue, bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
if (aName == nsGkAtoms::sandbox &&
|
AfterMaybeChangeAttr(aNameSpaceID, aName, aNotify);
|
||||||
aNameSpaceID == kNameSpaceID_None && mFrameLoader) {
|
|
||||||
// If we have an nsFrameLoader, apply the new sandbox flags.
|
if (aNameSpaceID == kNameSpaceID_None) {
|
||||||
// Since this is called after the setter, the sandbox flags have
|
if (aName == nsGkAtoms::sandbox) {
|
||||||
// alreay been updated.
|
if (mFrameLoader) {
|
||||||
mFrameLoader->ApplySandboxFlags(GetSandboxFlags());
|
// If we have an nsFrameLoader, apply the new sandbox flags.
|
||||||
|
// Since this is called after the setter, the sandbox flags have
|
||||||
|
// alreay been updated.
|
||||||
|
mFrameLoader->ApplySandboxFlags(GetSandboxFlags());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nsGenericHTMLFrameElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
return nsGenericHTMLFrameElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||||
aOldValue, aNotify);
|
aOldValue, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLIFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
HTMLIFrameElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
bool aNotify)
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
{
|
{
|
||||||
// Invoke on the superclass.
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
nsresult rv = nsGenericHTMLFrameElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None &&
|
return nsGenericHTMLFrameElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
aAttribute == nsGkAtoms::srcdoc) {
|
aValue, aNotify);
|
||||||
// Fall back to the src attribute, if any
|
}
|
||||||
LoadSrc();
|
|
||||||
|
void
|
||||||
|
HTMLIFrameElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
|
||||||
|
nsIAtom* aName,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
if (aName == nsGkAtoms::srcdoc) {
|
||||||
|
// Don't propagate errors from LoadSrc. The attribute was successfully
|
||||||
|
// set/unset, that's what we should reflect.
|
||||||
|
LoadSrc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
|
|
||||||
|
|
@ -46,21 +46,6 @@ public:
|
||||||
|
|
||||||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
|
||||||
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAttrValue* aValue,
|
|
||||||
const nsAttrValue* aOldValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
uint32_t GetSandboxFlags();
|
uint32_t GetSandboxFlags();
|
||||||
|
|
||||||
// Web IDL binding methods
|
// Web IDL binding methods
|
||||||
|
|
@ -197,11 +182,30 @@ protected:
|
||||||
|
|
||||||
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||||
nsRuleData* aData);
|
nsRuleData* aData);
|
||||||
|
|
||||||
static const DOMTokenListSupportedToken sSupportedSandboxTokens[];
|
static const DOMTokenListSupportedToken sSupportedSandboxTokens[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* This function will be called by AfterSetAttr whether the attribute is being
|
||||||
|
* set or unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName, bool aNotify);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ private:
|
||||||
HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
HTMLImageElement::HTMLImageElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||||
: nsGenericHTMLElement(aNodeInfo)
|
: nsGenericHTMLElement(aNodeInfo)
|
||||||
, mForm(nullptr)
|
, mForm(nullptr)
|
||||||
|
, mForceReload(false)
|
||||||
, mInDocResponsiveContent(false)
|
, mInDocResponsiveContent(false)
|
||||||
, mCurrentDensity(1.0)
|
, mCurrentDensity(1.0)
|
||||||
{
|
{
|
||||||
|
|
@ -372,6 +373,9 @@ HTMLImageElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValueOrString* aValue,
|
const nsAttrValueOrString* aValue,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
|
if (aValue) {
|
||||||
|
BeforeMaybeChangeAttr(aNameSpaceID, aName, *aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && mForm &&
|
if (aNameSpaceID == kNameSpaceID_None && mForm &&
|
||||||
(aName == nsGkAtoms::name || aName == nsGkAtoms::id)) {
|
(aName == nsGkAtoms::name || aName == nsGkAtoms::id)) {
|
||||||
|
|
@ -394,6 +398,10 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue, bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
|
if (aValue) {
|
||||||
|
AfterMaybeChangeAttr(aNameSpaceID, aName, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && mForm &&
|
if (aNameSpaceID == kNameSpaceID_None && mForm &&
|
||||||
(aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
|
(aName == nsGkAtoms::name || aName == nsGkAtoms::id) &&
|
||||||
aValue && !aValue->IsEmptyString()) {
|
aValue && !aValue->IsEmptyString()) {
|
||||||
|
|
@ -437,6 +445,117 @@ HTMLImageElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
aValue, aOldValue, aNotify);
|
aValue, aOldValue, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
HTMLImageElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
BeforeMaybeChangeAttr(aNamespaceID, aName, aValue, aNotify);
|
||||||
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
|
aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLImageElement::BeforeMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
// We need to force our image to reload. This must be done here, not in
|
||||||
|
// AfterSetAttr or BeforeSetAttr, because we want to do it even if the attr is
|
||||||
|
// being set to its existing value, which is normally optimized away as a
|
||||||
|
// no-op.
|
||||||
|
//
|
||||||
|
// If we are in responsive mode, we drop the forced reload behavior,
|
||||||
|
// but still trigger a image load task for img.src = img.src per
|
||||||
|
// spec.
|
||||||
|
//
|
||||||
|
// Both cases handle unsetting src in AfterSetAttr
|
||||||
|
//
|
||||||
|
// Much of this should probably happen in AfterMaybeChangeAttr.
|
||||||
|
// See Bug 1370705
|
||||||
|
if (aNamespaceID == kNameSpaceID_None &&
|
||||||
|
aName == nsGkAtoms::src) {
|
||||||
|
|
||||||
|
if (InResponsiveMode()) {
|
||||||
|
if (mResponsiveSelector &&
|
||||||
|
mResponsiveSelector->Content() == this) {
|
||||||
|
mResponsiveSelector->SetDefaultSource(aValue.String());
|
||||||
|
}
|
||||||
|
QueueImageLoadTask(true);
|
||||||
|
} else if (aNotify && OwnerDoc()->IsCurrentActiveDocument()) {
|
||||||
|
// If aNotify is false, we are coming from the parser or some such place;
|
||||||
|
// we'll get bound after all the attributes have been set, so we'll do the
|
||||||
|
// sync image load from BindToTree. Skip the LoadImage call in that case.
|
||||||
|
|
||||||
|
// Note that this sync behavior is partially removed from the spec, bug 1076583
|
||||||
|
|
||||||
|
// A hack to get animations to reset. See bug 594771.
|
||||||
|
mNewRequestsWillNeedAnimationReset = true;
|
||||||
|
|
||||||
|
// Force image loading here, so that we'll try to load the image from
|
||||||
|
// network if it's set to be not cacheable... If we change things so that
|
||||||
|
// the state gets in Element's attr-setting happen around this
|
||||||
|
// LoadImage call, we could start passing false instead of aNotify
|
||||||
|
// here.
|
||||||
|
LoadImage(aValue.String(), true, aNotify, eImageLoadType_Normal);
|
||||||
|
|
||||||
|
mNewRequestsWillNeedAnimationReset = false;
|
||||||
|
}
|
||||||
|
} else if (aNamespaceID == kNameSpaceID_None &&
|
||||||
|
aName == nsGkAtoms::crossorigin &&
|
||||||
|
aNotify) {
|
||||||
|
nsAttrValue attrValue;
|
||||||
|
ParseCORSValue(aValue.String(), attrValue);
|
||||||
|
if (GetCORSMode() != AttrValueToCORSMode(&attrValue)) {
|
||||||
|
// Force a new load of the image with the new cross origin policy.
|
||||||
|
mForceReload = true;
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::referrerpolicy &&
|
||||||
|
aNamespaceID == kNameSpaceID_None &&
|
||||||
|
aNotify) {
|
||||||
|
ReferrerPolicy referrerPolicy = AttributeReferrerPolicyFromString(aValue.String());
|
||||||
|
if (!InResponsiveMode() &&
|
||||||
|
referrerPolicy != RP_Unset &&
|
||||||
|
referrerPolicy != GetImageReferrerPolicy()) {
|
||||||
|
// XXX: Bug 1076583 - We still use the older synchronous algorithm
|
||||||
|
// Because referrerPolicy is not treated as relevant mutations, setting
|
||||||
|
// the attribute will neither trigger a reload nor update the referrer
|
||||||
|
// policy of the loading channel (whether it has previously completed or
|
||||||
|
// not). Force a new load of the image with the new referrerpolicy.
|
||||||
|
mForceReload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLImageElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
// Because we load image synchronously in non-responsive-mode, we need to do
|
||||||
|
// reload after the attribute has been set if the reload is triggerred by
|
||||||
|
// cross origin changing.
|
||||||
|
if (mForceReload) {
|
||||||
|
mForceReload = false;
|
||||||
|
|
||||||
|
if (InResponsiveMode()) {
|
||||||
|
// per spec, full selection runs when this changes, even though
|
||||||
|
// it doesn't directly affect the source selection
|
||||||
|
QueueImageLoadTask(true);
|
||||||
|
} else if (OwnerDoc()->IsCurrentActiveDocument()) {
|
||||||
|
// Bug 1076583 - We still use the older synchronous algorithm in
|
||||||
|
// non-responsive mode. Force a new load of the image with the
|
||||||
|
// new cross origin policy
|
||||||
|
ForceReload(aNotify);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLImageElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
HTMLImageElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||||
{
|
{
|
||||||
|
|
@ -489,97 +608,6 @@ HTMLImageElement::IsHTMLFocusable(bool aWithMouse,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLImageElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
bool forceReload = false;
|
|
||||||
// We need to force our image to reload. This must be done here, not in
|
|
||||||
// AfterSetAttr or BeforeSetAttr, because we want to do it even if the attr is
|
|
||||||
// being set to its existing value, which is normally optimized away as a
|
|
||||||
// no-op.
|
|
||||||
//
|
|
||||||
// If we are in responsive mode, we drop the forced reload behavior,
|
|
||||||
// but still trigger a image load task for img.src = img.src per
|
|
||||||
// spec.
|
|
||||||
//
|
|
||||||
// Both cases handle unsetting src in AfterSetAttr
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
aName == nsGkAtoms::src) {
|
|
||||||
|
|
||||||
if (InResponsiveMode()) {
|
|
||||||
if (mResponsiveSelector &&
|
|
||||||
mResponsiveSelector->Content() == this) {
|
|
||||||
mResponsiveSelector->SetDefaultSource(aValue);
|
|
||||||
}
|
|
||||||
QueueImageLoadTask(true);
|
|
||||||
} else if (aNotify) {
|
|
||||||
// If aNotify is false, we are coming from the parser or some such place;
|
|
||||||
// we'll get bound after all the attributes have been set, so we'll do the
|
|
||||||
// sync image load from BindToTree. Skip the LoadImage call in that case.
|
|
||||||
|
|
||||||
// Note that this sync behavior is partially removed from the spec, bug 1076583
|
|
||||||
|
|
||||||
// A hack to get animations to reset. See bug 594771.
|
|
||||||
mNewRequestsWillNeedAnimationReset = true;
|
|
||||||
|
|
||||||
// Force image loading here, so that we'll try to load the image from
|
|
||||||
// network if it's set to be not cacheable... If we change things so that
|
|
||||||
// the state gets in Element's attr-setting happen around this
|
|
||||||
// LoadImage call, we could start passing false instead of aNotify
|
|
||||||
// here.
|
|
||||||
LoadImage(aValue, true, aNotify, eImageLoadType_Normal);
|
|
||||||
|
|
||||||
mNewRequestsWillNeedAnimationReset = false;
|
|
||||||
}
|
|
||||||
} else if (aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
aName == nsGkAtoms::crossorigin &&
|
|
||||||
aNotify) {
|
|
||||||
nsAttrValue attrValue;
|
|
||||||
ParseCORSValue(aValue, attrValue);
|
|
||||||
if (GetCORSMode() != AttrValueToCORSMode(&attrValue)) {
|
|
||||||
// Force a new load of the image with the new cross origin policy.
|
|
||||||
forceReload = true;
|
|
||||||
}
|
|
||||||
} else if (aName == nsGkAtoms::referrerpolicy &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
aNotify) {
|
|
||||||
ReferrerPolicy referrerPolicy = AttributeReferrerPolicyFromString(aValue);
|
|
||||||
if (!InResponsiveMode() &&
|
|
||||||
referrerPolicy != RP_Unset &&
|
|
||||||
referrerPolicy != GetImageReferrerPolicy()) {
|
|
||||||
// XXX: Bug 1076583 - We still use the older synchronous algorithm
|
|
||||||
// Because referrerPolicy is not treated as relevant mutations, setting
|
|
||||||
// the attribute will neither trigger a reload nor update the referrer
|
|
||||||
// policy of the loading channel (whether it has previously completed or
|
|
||||||
// not). Force a new load of the image with the new referrerpolicy.
|
|
||||||
forceReload = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
|
||||||
aValue, aNotify);
|
|
||||||
|
|
||||||
// Because we load image synchronously in non-responsive-mode, we need to do
|
|
||||||
// reload after the attribute has been set if the reload is triggerred by
|
|
||||||
// cross origin changing.
|
|
||||||
if (forceReload) {
|
|
||||||
if (InResponsiveMode()) {
|
|
||||||
// per spec, full selection runs when this changes, even though
|
|
||||||
// it doesn't directly affect the source selection
|
|
||||||
QueueImageLoadTask(true);
|
|
||||||
} else {
|
|
||||||
// Bug 1076583 - We still use the older synchronous algorithm in
|
|
||||||
// non-responsive mode. Force a new load of the image with the
|
|
||||||
// new cross origin policy
|
|
||||||
ForceReload(aNotify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
HTMLImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
nsIContent* aBindingParent,
|
nsIContent* aBindingParent,
|
||||||
|
|
|
||||||
|
|
@ -75,17 +75,6 @@ public:
|
||||||
|
|
||||||
bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
|
bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
|
||||||
|
|
||||||
// SetAttr override. C++ is stupid, so have to override both
|
|
||||||
// overloaded methods.
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
nsIContent* aBindingParent,
|
nsIContent* aBindingParent,
|
||||||
bool aCompileEventHandlers) override;
|
bool aCompileEventHandlers) override;
|
||||||
|
|
@ -352,6 +341,10 @@ protected:
|
||||||
const nsAttrValue* aOldValue,
|
const nsAttrValue* aOldValue,
|
||||||
bool aNotify) override;
|
bool aNotify) override;
|
||||||
|
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
// This is a weak reference that this element and the HTMLFormElement
|
// This is a weak reference that this element and the HTMLFormElement
|
||||||
// cooperate in maintaining.
|
// cooperate in maintaining.
|
||||||
HTMLFormElement* mForm;
|
HTMLFormElement* mForm;
|
||||||
|
|
@ -365,6 +358,36 @@ private:
|
||||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||||
nsRuleData* aData);
|
nsRuleData* aData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called by BeforeSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* It will not be called if the value is being unset.
|
||||||
|
*
|
||||||
|
* @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 represented as either a string or
|
||||||
|
* a parsed nsAttrValue.
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
void BeforeMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify);
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* It will not be called if the value is being unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify);
|
||||||
|
/**
|
||||||
|
* Used by BeforeMaybeChangeAttr and AfterMaybeChangeAttr to keep track of
|
||||||
|
* whether a reload needs to be forced after an attribute change that is
|
||||||
|
* currently in progress.
|
||||||
|
*/
|
||||||
|
bool mForceReload;
|
||||||
|
|
||||||
bool mInDocResponsiveContent;
|
bool mInDocResponsiveContent;
|
||||||
RefPtr<ImageLoadTask> mPendingImageLoadTask;
|
RefPtr<ImageLoadTask> mPendingImageLoadTask;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,21 +70,6 @@ HTMLLegendElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLLegendElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
return nsGenericHTMLElement::SetAttr(aNameSpaceID, aAttribute,
|
|
||||||
aPrefix, aValue, aNotify);
|
|
||||||
}
|
|
||||||
nsresult
|
|
||||||
HTMLLegendElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLLegendElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
HTMLLegendElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
nsIContent* aBindingParent,
|
nsIContent* aBindingParent,
|
||||||
|
|
|
||||||
|
|
@ -42,16 +42,6 @@ public:
|
||||||
nsAttrValue& aResult) override;
|
nsAttrValue& aResult) override;
|
||||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||||
int32_t aModType) const override;
|
int32_t aModType) const override;
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3726,80 +3726,76 @@ int32_t HTMLMediaElement::TabIndexDefault()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult HTMLMediaElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv =
|
|
||||||
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
|
||||||
aNotify);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
|
|
||||||
DoLoad();
|
|
||||||
}
|
|
||||||
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
|
|
||||||
if (aName == nsGkAtoms::autoplay) {
|
|
||||||
StopSuspendingAfterFirstFrame();
|
|
||||||
CheckAutoplayDataReady();
|
|
||||||
// This attribute can affect AddRemoveSelfReference
|
|
||||||
AddRemoveSelfReference();
|
|
||||||
UpdatePreloadAction();
|
|
||||||
} else if (aName == nsGkAtoms::preload) {
|
|
||||||
UpdatePreloadAction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult HTMLMediaElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttr, aNotify);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
|
|
||||||
if (aAttr == nsGkAtoms::autoplay) {
|
|
||||||
// This attribute can affect AddRemoveSelfReference
|
|
||||||
AddRemoveSelfReference();
|
|
||||||
UpdatePreloadAction();
|
|
||||||
} else if (aAttr == nsGkAtoms::preload) {
|
|
||||||
UpdatePreloadAction();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLMediaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLMediaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue, bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
|
if (aNameSpaceID == kNameSpaceID_None) {
|
||||||
mSrcMediaSource = nullptr;
|
if (aName == nsGkAtoms::src) {
|
||||||
if (aValue) {
|
mSrcMediaSource = nullptr;
|
||||||
nsString srcStr = aValue->GetStringValue();
|
if (aValue) {
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsString srcStr = aValue->GetStringValue();
|
||||||
NewURIFromString(srcStr, getter_AddRefs(uri));
|
nsCOMPtr<nsIURI> uri;
|
||||||
if (uri && IsMediaSourceURI(uri)) {
|
NewURIFromString(srcStr, getter_AddRefs(uri));
|
||||||
nsresult rv =
|
if (uri && IsMediaSourceURI(uri)) {
|
||||||
NS_GetSourceForMediaSourceURI(uri, getter_AddRefs(mSrcMediaSource));
|
nsresult rv =
|
||||||
if (NS_FAILED(rv)) {
|
NS_GetSourceForMediaSourceURI(uri, getter_AddRefs(mSrcMediaSource));
|
||||||
nsAutoString spec;
|
if (NS_FAILED(rv)) {
|
||||||
GetCurrentSrc(spec);
|
nsAutoString spec;
|
||||||
const char16_t* params[] = { spec.get() };
|
GetCurrentSrc(spec);
|
||||||
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
|
const char16_t* params[] = { spec.get() };
|
||||||
|
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (aName == nsGkAtoms::autoplay) {
|
||||||
|
if (aNotify) {
|
||||||
|
if (aValue) {
|
||||||
|
StopSuspendingAfterFirstFrame();
|
||||||
|
CheckAutoplayDataReady();
|
||||||
|
}
|
||||||
|
// This attribute can affect AddRemoveSelfReference
|
||||||
|
AddRemoveSelfReference();
|
||||||
|
UpdatePreloadAction();
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::preload) {
|
||||||
|
UpdatePreloadAction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since AfterMaybeChangeAttr may call DoLoad, make sure that it is called
|
||||||
|
// *after* any possible changes to mSrcMediaSource.
|
||||||
|
if (aValue) {
|
||||||
|
AfterMaybeChangeAttr(aNameSpaceID, aName, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
|
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName,
|
||||||
aValue, aOldValue, aNotify);
|
aValue, aOldValue, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
HTMLMediaElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
|
aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLMediaElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
if (aName == nsGkAtoms::src) {
|
||||||
|
DoLoad();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
nsresult HTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
nsIContent* aBindingParent,
|
nsIContent* aBindingParent,
|
||||||
bool aCompileEventHandlers)
|
bool aCompileEventHandlers)
|
||||||
|
|
|
||||||
|
|
@ -132,22 +132,6 @@ public:
|
||||||
nsIAtom* aAttribute,
|
nsIAtom* aAttribute,
|
||||||
const nsAString& aValue,
|
const nsAString& aValue,
|
||||||
nsAttrValue& aResult) override;
|
nsAttrValue& aResult) override;
|
||||||
// SetAttr override. C++ is stupid, so have to override both
|
|
||||||
// overloaded methods.
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAttrValue* aValue,
|
|
||||||
const nsAttrValue* aOldValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
nsIContent* aBindingParent,
|
nsIContent* aBindingParent,
|
||||||
|
|
@ -1315,6 +1299,14 @@ protected:
|
||||||
|
|
||||||
already_AddRefed<Promise> CreateDOMPromise(ErrorResult& aRv) const;
|
already_AddRefed<Promise> CreateDOMPromise(ErrorResult& aRv) const;
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
// The current decoder. Load() has been called on this decoder.
|
// The current decoder. Load() has been called on this decoder.
|
||||||
// At most one of mDecoder and mSrcStream can be non-null.
|
// At most one of mDecoder and mSrcStream can be non-null.
|
||||||
RefPtr<MediaDecoder> mDecoder;
|
RefPtr<MediaDecoder> mDecoder;
|
||||||
|
|
@ -1717,6 +1709,17 @@ private:
|
||||||
// We keep track of these because the load algorithm resolves/rejects all
|
// We keep track of these because the load algorithm resolves/rejects all
|
||||||
// already-dispatched pending play promises.
|
// already-dispatched pending play promises.
|
||||||
nsTArray<nsResolveOrRejectPendingPlayPromisesRunner*> mPendingPlayPromisesRunners;
|
nsTArray<nsResolveOrRejectPendingPlayPromisesRunner*> mPendingPlayPromisesRunners;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* It will not be called if the value is being unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName, bool aNotify);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -298,41 +298,45 @@ HTMLObjectElement::UnbindFromTree(bool aDeep,
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
|
HTMLObjectElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom *aPrefix, const nsAString &aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
aValue, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// if aNotify is false, we are coming from the parser or some such place;
|
return nsGenericHTMLFormElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||||
// we'll get bound after all the attributes have been set, so we'll do the
|
aOldValue, aNotify);
|
||||||
// object load from BindToTree/DoneAddingChildren.
|
|
||||||
// Skip the LoadObject call in that case.
|
|
||||||
// We also don't want to start loading the object when we're not yet in
|
|
||||||
// a document, just in case that the caller wants to set additional
|
|
||||||
// attributes before inserting the node into the document.
|
|
||||||
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) {
|
|
||||||
return LoadObject(aNotify, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
HTMLObjectElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
bool aNotify)
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID,
|
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
aAttribute, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// See comment in SetAttr
|
return nsGenericHTMLFormElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
|
aValue, aNotify);
|
||||||
aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) {
|
}
|
||||||
return LoadObject(aNotify, true);
|
|
||||||
|
nsresult
|
||||||
|
HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
// if aNotify is false, we are coming from the parser or some such place;
|
||||||
|
// we'll get bound after all the attributes have been set, so we'll do the
|
||||||
|
// object load from BindToTree/DoneAddingChildren.
|
||||||
|
// Skip the LoadObject call in that case.
|
||||||
|
// We also don't want to start loading the object when we're not yet in
|
||||||
|
// a document, just in case that the caller wants to set additional
|
||||||
|
// attributes before inserting the node into the document.
|
||||||
|
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
|
||||||
|
aName == nsGkAtoms::data) {
|
||||||
|
return LoadObject(aNotify, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,6 @@ public:
|
||||||
bool aCompileEventHandlers) override;
|
bool aCompileEventHandlers) override;
|
||||||
virtual void UnbindFromTree(bool aDeep = true,
|
virtual void UnbindFromTree(bool aDeep = true,
|
||||||
bool aNullParent = true) override;
|
bool aNullParent = true) override;
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
|
|
||||||
nsIAtom *aPrefix, const nsAString &aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
|
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
|
||||||
virtual IMEState GetDesiredIMEState() override;
|
virtual IMEState GetDesiredIMEState() override;
|
||||||
|
|
@ -247,6 +242,15 @@ public:
|
||||||
return GetContentDocument(aSubjectPrincipal);
|
return GetContentDocument(aSubjectPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Calls LoadObject with the correct arguments to start the plugin load.
|
* Calls LoadObject with the correct arguments to start the plugin load.
|
||||||
|
|
@ -271,6 +275,18 @@ private:
|
||||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||||
nsRuleData* aData);
|
nsRuleData* aData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* This function will be called by AfterSetAttr whether the attribute is being
|
||||||
|
* set or unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
nsresult AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify);
|
||||||
|
|
||||||
bool mIsDoneAddingChildren;
|
bool mIsDoneAddingChildren;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1272,9 +1272,22 @@ HTMLSelectElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValueOrString* aValue,
|
const nsAttrValueOrString* aValue,
|
||||||
bool aNotify)
|
bool aNotify)
|
||||||
{
|
{
|
||||||
if (aNotify && aName == nsGkAtoms::disabled &&
|
if (aNameSpaceID == kNameSpaceID_None) {
|
||||||
aNameSpaceID == kNameSpaceID_None) {
|
if (aName == nsGkAtoms::disabled) {
|
||||||
mDisabledChanged = true;
|
if (aNotify) {
|
||||||
|
mDisabledChanged = true;
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::multiple) {
|
||||||
|
if (!aValue && aNotify && mSelectedIndex >= 0) {
|
||||||
|
// We're changing from being a multi-select to a single-select.
|
||||||
|
// Make sure we only have one option selected before we do that.
|
||||||
|
// Note that this needs to come before we really unset the attr,
|
||||||
|
// since SetOptionsSelectedByIndex does some bail-out type
|
||||||
|
// optimization for cases when the select is not multiple that
|
||||||
|
// would lead to only a single option getting deselected.
|
||||||
|
SetSelectedIndexInternal(mSelectedIndex, aNotify);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
|
return nsGenericHTMLFormElementWithState::BeforeSetAttr(aNameSpaceID, aName,
|
||||||
|
|
@ -1294,6 +1307,12 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
} else if (aName == nsGkAtoms::autocomplete) {
|
} else if (aName == nsGkAtoms::autocomplete) {
|
||||||
// Clear the cached @autocomplete attribute state
|
// Clear the cached @autocomplete attribute state
|
||||||
mAutocompleteAttrState = nsContentUtils::eAutocompleteAttrState_Unknown;
|
mAutocompleteAttrState = nsContentUtils::eAutocompleteAttrState_Unknown;
|
||||||
|
} else if (aName == nsGkAtoms::multiple) {
|
||||||
|
if (!aValue && aNotify) {
|
||||||
|
// We might have become a combobox; make sure _something_ gets
|
||||||
|
// selected in that case
|
||||||
|
CheckSelectSomething(aNotify);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1302,37 +1321,6 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
aNotify);
|
aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLSelectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
if (aNotify && aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
aAttribute == nsGkAtoms::multiple) {
|
|
||||||
// We're changing from being a multi-select to a single-select.
|
|
||||||
// Make sure we only have one option selected before we do that.
|
|
||||||
// Note that this needs to come before we really unset the attr,
|
|
||||||
// since SetOptionsSelectedByIndex does some bail-out type
|
|
||||||
// optimization for cases when the select is not multiple that
|
|
||||||
// would lead to only a single option getting deselected.
|
|
||||||
if (mSelectedIndex >= 0) {
|
|
||||||
SetSelectedIndexInternal(mSelectedIndex, aNotify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = nsGenericHTMLFormElementWithState::UnsetAttr(aNameSpaceID, aAttribute,
|
|
||||||
aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aNotify && aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
aAttribute == nsGkAtoms::multiple) {
|
|
||||||
// We might have become a combobox; make sure _something_ gets
|
|
||||||
// selected in that case
|
|
||||||
CheckSelectSomething(aNotify);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HTMLSelectElement::DoneAddingChildren(bool aHaveNotified)
|
HTMLSelectElement::DoneAddingChildren(bool aHaveNotified)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -381,8 +381,6 @@ public:
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue,
|
const nsAttrValue* aOldValue,
|
||||||
bool aNotify) override;
|
bool aNotify) override;
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual void DoneAddingChildren(bool aHaveNotified) override;
|
virtual void DoneAddingChildren(bool aHaveNotified) override;
|
||||||
virtual bool IsDoneAddingChildren() override {
|
virtual bool IsDoneAddingChildren() override {
|
||||||
|
|
|
||||||
|
|
@ -231,52 +231,32 @@ SetBaseTargetUsingFirstBaseWithTarget(nsIDocument* aDocument,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLSharedElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
HTMLSharedElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
aValue, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// If the href attribute of a <base> tag is changing, we may need to update
|
|
||||||
// the document's base URI, which will cause all the links on the page to be
|
|
||||||
// re-resolved given the new base. If the target attribute is changing, we
|
|
||||||
// similarly need to change the base target.
|
|
||||||
if (mNodeInfo->Equals(nsGkAtoms::base) &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
IsInUncomposedDoc()) {
|
|
||||||
if (aName == nsGkAtoms::href) {
|
if (aName == nsGkAtoms::href) {
|
||||||
SetBaseURIUsingFirstBaseWithHref(GetUncomposedDoc(), this);
|
// If the href attribute of a <base> tag is changing, we may need to
|
||||||
|
// update the document's base URI, which will cause all the links on the
|
||||||
|
// page to be re-resolved given the new base.
|
||||||
|
// If the href is being unset (aValue is null), we will need to find a new
|
||||||
|
// <base>.
|
||||||
|
if (mNodeInfo->Equals(nsGkAtoms::base) && IsInUncomposedDoc()) {
|
||||||
|
SetBaseURIUsingFirstBaseWithHref(GetUncomposedDoc(),
|
||||||
|
aValue ? this : nullptr);
|
||||||
|
}
|
||||||
} else if (aName == nsGkAtoms::target) {
|
} else if (aName == nsGkAtoms::target) {
|
||||||
SetBaseTargetUsingFirstBaseWithTarget(GetUncomposedDoc(), this);
|
// The target attribute is in pretty much the same situation as the href
|
||||||
|
// attribute, above.
|
||||||
|
if (mNodeInfo->Equals(nsGkAtoms::base) && IsInUncomposedDoc()) {
|
||||||
|
SetBaseTargetUsingFirstBaseWithTarget(GetUncomposedDoc(),
|
||||||
|
aValue ? this : nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||||
return NS_OK;
|
aOldValue, aNotify);
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
HTMLSharedElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// If we're the first <base> with an href and our href attribute is being
|
|
||||||
// unset, then we're no longer the first <base> with an href, and we need to
|
|
||||||
// find the new one. Similar for target.
|
|
||||||
if (mNodeInfo->Equals(nsGkAtoms::base) &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
IsInUncomposedDoc()) {
|
|
||||||
if (aName == nsGkAtoms::href) {
|
|
||||||
SetBaseURIUsingFirstBaseWithHref(GetUncomposedDoc(), nullptr);
|
|
||||||
} else if (aName == nsGkAtoms::target) {
|
|
||||||
SetBaseTargetUsingFirstBaseWithTarget(GetUncomposedDoc(), nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
||||||
|
|
@ -59,17 +59,6 @@ public:
|
||||||
nsIAtom* aAttribute,
|
nsIAtom* aAttribute,
|
||||||
const nsAString& aValue,
|
const nsAString& aValue,
|
||||||
nsAttrValue& aResult) override;
|
nsAttrValue& aResult) override;
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
nsIContent* aBindingParent,
|
nsIContent* aBindingParent,
|
||||||
|
|
@ -181,6 +170,11 @@ protected:
|
||||||
virtual ~HTMLSharedElement();
|
virtual ~HTMLSharedElement();
|
||||||
|
|
||||||
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -161,27 +161,53 @@ HTMLSharedObjectElement::UnbindFromTree(bool aDeep,
|
||||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
HTMLSharedObjectElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (aValue) {
|
||||||
|
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||||
|
aOldValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
|
HTMLSharedObjectElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
|
||||||
nsIAtom *aPrefix, const nsAString &aValue,
|
nsIAtom* aName,
|
||||||
bool aNotify)
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||||
aValue, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// if aNotify is false, we are coming from the parser or some such place;
|
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
// we'll get bound after all the attributes have been set, so we'll do the
|
aValue, aNotify);
|
||||||
// object load from BindToTree/DoneAddingChildren.
|
}
|
||||||
// Skip the LoadObject call in that case.
|
|
||||||
// We also don't want to start loading the object when we're not yet in
|
nsresult
|
||||||
// a document, just in case that the caller wants to set additional
|
HTMLSharedObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
|
||||||
// attributes before inserting the node into the document.
|
nsIAtom* aName,
|
||||||
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
|
bool aNotify)
|
||||||
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()
|
{
|
||||||
&& !BlockEmbedContentLoading()) {
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
return LoadObject(aNotify, true);
|
if (aName == URIAttrName()) {
|
||||||
|
// If aNotify is false, we are coming from the parser or some such place;
|
||||||
|
// we'll get bound after all the attributes have been set, so we'll do the
|
||||||
|
// object load from BindToTree/DoneAddingChildren.
|
||||||
|
// Skip the LoadObject call in that case.
|
||||||
|
// We also don't want to start loading the object when we're not yet in
|
||||||
|
// a document, just in case that the caller wants to set additional
|
||||||
|
// attributes before inserting the node into the document.
|
||||||
|
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren) {
|
||||||
|
nsresult rv = LoadObject(aNotify, true);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,6 @@ public:
|
||||||
bool aCompileEventHandlers) override;
|
bool aCompileEventHandlers) override;
|
||||||
virtual void UnbindFromTree(bool aDeep = true,
|
virtual void UnbindFromTree(bool aDeep = true,
|
||||||
bool aNullParent = true) override;
|
bool aNullParent = true) override;
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
|
|
||||||
nsIAtom *aPrefix, const nsAString &aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
|
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex) override;
|
||||||
virtual IMEState GetDesiredIMEState() override;
|
virtual IMEState GetDesiredIMEState() override;
|
||||||
|
|
@ -200,6 +197,16 @@ public:
|
||||||
* Calls LoadObject with the correct arguments to start the plugin load.
|
* Calls LoadObject with the correct arguments to start the plugin load.
|
||||||
*/
|
*/
|
||||||
void StartObjectLoad(bool aNotify, bool aForceLoad);
|
void StartObjectLoad(bool aNotify, bool aForceLoad);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~HTMLSharedObjectElement();
|
virtual ~HTMLSharedObjectElement();
|
||||||
|
|
||||||
|
|
@ -221,6 +228,17 @@ private:
|
||||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||||
nsRuleData* aData);
|
nsRuleData* aData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* It will not be called if the value is being unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
nsresult AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
bool aNotify);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decides whether we should load embed node content.
|
* Decides whether we should load embed node content.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -654,6 +654,43 @@ nsGenericHTMLElement::GetHrefURIForAnchors() const
|
||||||
return uri.forget();
|
return uri.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
if (aName == nsGkAtoms::accesskey) {
|
||||||
|
// Have to unregister before clearing flag. See UnregAccessKey
|
||||||
|
UnregAccessKey();
|
||||||
|
if (!aValue) {
|
||||||
|
UnsetFlags(NODE_HAS_ACCESSKEY);
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::name) {
|
||||||
|
// Have to do this before clearing flag. See RemoveFromNameTable
|
||||||
|
RemoveFromNameTable();
|
||||||
|
if (!aValue || aValue->IsEmpty()) {
|
||||||
|
ClearHasName();
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::contenteditable) {
|
||||||
|
if (aValue) {
|
||||||
|
// Set this before the attribute is set so that any subclass code that
|
||||||
|
// runs before the attribute is set won't think we're missing a
|
||||||
|
// contenteditable attr when we actually have one.
|
||||||
|
SetMayHaveContentEditableAttr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!aValue && IsEventAttributeName(aName)) {
|
||||||
|
if (EventListenerManager* manager = GetExistingListenerManager()) {
|
||||||
|
manager->RemoveEventHandler(aName, EmptyString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsGenericHTMLElementBase::BeforeSetAttr(aNamespaceID, aName, aValue,
|
||||||
|
aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
|
|
@ -694,6 +731,34 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetDirectionalityOnDescendants(this, dir, aNotify);
|
SetDirectionalityOnDescendants(this, dir, aNotify);
|
||||||
|
} else if (aName == nsGkAtoms::contenteditable) {
|
||||||
|
int32_t editableCountDelta = 0;
|
||||||
|
if (aOldValue &&
|
||||||
|
(aOldValue->Equals(NS_LITERAL_STRING("true"), eIgnoreCase) ||
|
||||||
|
aOldValue->Equals(EmptyString(), eIgnoreCase))) {
|
||||||
|
editableCountDelta = -1;
|
||||||
|
}
|
||||||
|
if (aValue && (aValue->Equals(NS_LITERAL_STRING("true"), eIgnoreCase) ||
|
||||||
|
aValue->Equals(EmptyString(), eIgnoreCase))) {
|
||||||
|
++editableCountDelta;
|
||||||
|
}
|
||||||
|
ChangeEditableState(editableCountDelta);
|
||||||
|
} else if (aName == nsGkAtoms::accesskey) {
|
||||||
|
if (aValue && !aValue->Equals(EmptyString(), eIgnoreCase)) {
|
||||||
|
SetFlags(NODE_HAS_ACCESSKEY);
|
||||||
|
RegAccessKey();
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::name) {
|
||||||
|
if (aValue && !aValue->Equals(EmptyString(), eIgnoreCase) &&
|
||||||
|
CanHaveName(NodeInfo()->NameAtom())) {
|
||||||
|
// This may not be quite right because we can have subclass code run
|
||||||
|
// before here. But in practice subclasses don't care about this flag,
|
||||||
|
// and in particular selector matching does not care. Otherwise we'd
|
||||||
|
// want to handle it like we handle id attributes (in PreIdMaybeChange
|
||||||
|
// and PostIdMaybeChange).
|
||||||
|
SetHasName();
|
||||||
|
AddToNameTable(aValue->GetAtomValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -819,87 +884,6 @@ nsGenericHTMLElement::SetOn##name_(EventHandlerNonNull* handler) \
|
||||||
#undef FORWARDED_EVENT
|
#undef FORWARDED_EVENT
|
||||||
#undef EVENT
|
#undef EVENT
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsGenericHTMLElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
bool contentEditable = aNameSpaceID == kNameSpaceID_None &&
|
|
||||||
aName == nsGkAtoms::contenteditable;
|
|
||||||
bool accessKey = aName == nsGkAtoms::accesskey &&
|
|
||||||
aNameSpaceID == kNameSpaceID_None;
|
|
||||||
|
|
||||||
int32_t change = 0;
|
|
||||||
if (contentEditable) {
|
|
||||||
change = GetContentEditableValue() == eTrue ? -1 : 0;
|
|
||||||
SetMayHaveContentEditableAttr();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accessKey) {
|
|
||||||
UnregAccessKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = nsStyledElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
|
||||||
aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (contentEditable) {
|
|
||||||
if (aValue.IsEmpty() || aValue.LowerCaseEqualsLiteral("true")) {
|
|
||||||
change += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChangeEditableState(change);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accessKey && !aValue.IsEmpty()) {
|
|
||||||
SetFlags(NODE_HAS_ACCESSKEY);
|
|
||||||
RegAccessKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsGenericHTMLElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
bool contentEditable = false;
|
|
||||||
int32_t contentEditableChange = 0;
|
|
||||||
|
|
||||||
// Check for event handlers
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None) {
|
|
||||||
if (aAttribute == nsGkAtoms::name) {
|
|
||||||
// Have to do this before clearing flag. See RemoveFromNameTable
|
|
||||||
RemoveFromNameTable();
|
|
||||||
ClearHasName();
|
|
||||||
}
|
|
||||||
else if (aAttribute == nsGkAtoms::contenteditable) {
|
|
||||||
contentEditable = true;
|
|
||||||
contentEditableChange = GetContentEditableValue() == eTrue ? -1 : 0;
|
|
||||||
}
|
|
||||||
else if (aAttribute == nsGkAtoms::accesskey) {
|
|
||||||
// Have to unregister before clearing flag. See UnregAccessKey
|
|
||||||
UnregAccessKey();
|
|
||||||
UnsetFlags(NODE_HAS_ACCESSKEY);
|
|
||||||
}
|
|
||||||
else if (IsEventAttributeName(aAttribute)) {
|
|
||||||
if (EventListenerManager* manager = GetExistingListenerManager()) {
|
|
||||||
manager->RemoveEventHandler(aAttribute, EmptyString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = nsGenericHTMLElementBase::UnsetAttr(aNameSpaceID, aAttribute,
|
|
||||||
aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (contentEditable) {
|
|
||||||
ChangeEditableState(contentEditableChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const
|
nsGenericHTMLElement::GetBaseTarget(nsAString& aBaseTarget) const
|
||||||
{
|
{
|
||||||
|
|
@ -929,8 +913,7 @@ nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
|
|
||||||
if (aAttribute == nsGkAtoms::name) {
|
if (aAttribute == nsGkAtoms::name) {
|
||||||
// Store name as an atom. name="" means that the element has no name,
|
// Store name as an atom. name="" means that the element has no name,
|
||||||
// not that it has an emptystring as the name.
|
// not that it has an empty string as the name.
|
||||||
RemoveFromNameTable();
|
|
||||||
if (aValue.IsEmpty()) {
|
if (aValue.IsEmpty()) {
|
||||||
ClearHasName();
|
ClearHasName();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -938,11 +921,6 @@ nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
|
|
||||||
aResult.ParseAtom(aValue);
|
aResult.ParseAtom(aValue);
|
||||||
|
|
||||||
if (CanHaveName(NodeInfo()->NameAtom())) {
|
|
||||||
SetHasName();
|
|
||||||
AddToNameTable(aResult.GetAtomValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -465,17 +465,6 @@ public:
|
||||||
virtual void UnbindFromTree(bool aDeep = true,
|
virtual void UnbindFromTree(bool aDeep = true,
|
||||||
bool aNullParent = true) override;
|
bool aNullParent = true) override;
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE // Avoid a crashy hook from Avast 10 Beta
|
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual bool IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse) override
|
virtual bool IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse) override
|
||||||
{
|
{
|
||||||
bool isFocusable = false;
|
bool isFocusable = false;
|
||||||
|
|
@ -914,6 +903,9 @@ private:
|
||||||
void RegUnRegAccessKey(bool aDoReg);
|
void RegUnRegAccessKey(bool aDoReg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify) override;
|
||||||
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue,
|
const nsAttrValue* aOldValue,
|
||||||
|
|
|
||||||
|
|
@ -334,55 +334,6 @@ nsGenericHTMLFrameElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsGenericHTMLFrameElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
|
||||||
aValue, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src &&
|
|
||||||
(!IsHTMLElement(nsGkAtoms::iframe) ||
|
|
||||||
!HasAttr(kNameSpaceID_None,nsGkAtoms::srcdoc))) {
|
|
||||||
// Don't propagate error here. The attribute was successfully set, that's
|
|
||||||
// what we should reflect.
|
|
||||||
LoadSrc();
|
|
||||||
} else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::name) {
|
|
||||||
// Propagate "name" to the docshell to make browsing context names live,
|
|
||||||
// per HTML5.
|
|
||||||
nsIDocShell *docShell = mFrameLoader ? mFrameLoader->GetExistingDocShell()
|
|
||||||
: nullptr;
|
|
||||||
if (docShell) {
|
|
||||||
docShell->SetName(aValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsGenericHTMLFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
// Invoke on the superclass.
|
|
||||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::name) {
|
|
||||||
// Propagate "name" to the docshell to make browsing context names live,
|
|
||||||
// per HTML5.
|
|
||||||
nsIDocShell *docShell = mFrameLoader ? mFrameLoader->GetExistingDocShell()
|
|
||||||
: nullptr;
|
|
||||||
if (docShell) {
|
|
||||||
docShell->SetName(EmptyString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ int32_t
|
/* static */ int32_t
|
||||||
nsGenericHTMLFrameElement::MapScrollingAttribute(const nsAttrValue* aValue)
|
nsGenericHTMLFrameElement::MapScrollingAttribute(const nsAttrValue* aValue)
|
||||||
{
|
{
|
||||||
|
|
@ -415,39 +366,88 @@ nsGenericHTMLFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
const nsAttrValue* aValue,
|
const nsAttrValue* aValue,
|
||||||
const nsAttrValue* aOldValue, bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
if (aName == nsGkAtoms::scrolling && aNameSpaceID == kNameSpaceID_None) {
|
if (aValue) {
|
||||||
if (mFrameLoader) {
|
nsAttrValueOrString value(aValue);
|
||||||
nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
|
AfterMaybeChangeAttr(aNameSpaceID, aName, &value, aNotify);
|
||||||
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(docshell);
|
} else {
|
||||||
if (scrollable) {
|
AfterMaybeChangeAttr(aNameSpaceID, aName, nullptr, aNotify);
|
||||||
int32_t cur;
|
}
|
||||||
scrollable->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, &cur);
|
|
||||||
int32_t val = MapScrollingAttribute(aValue);
|
if (aNameSpaceID == kNameSpaceID_None) {
|
||||||
if (cur != val) {
|
if (aName == nsGkAtoms::scrolling) {
|
||||||
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, val);
|
if (mFrameLoader) {
|
||||||
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, val);
|
nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
|
||||||
RefPtr<nsPresContext> presContext;
|
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(docshell);
|
||||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
if (scrollable) {
|
||||||
nsIPresShell* shell = presContext ? presContext->GetPresShell() : nullptr;
|
int32_t cur;
|
||||||
nsIFrame* rootScroll = shell ? shell->GetRootScrollFrame() : nullptr;
|
scrollable->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, &cur);
|
||||||
if (rootScroll) {
|
int32_t val = MapScrollingAttribute(aValue);
|
||||||
shell->FrameNeedsReflow(rootScroll, nsIPresShell::eStyleChange,
|
if (cur != val) {
|
||||||
NS_FRAME_IS_DIRTY);
|
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, val);
|
||||||
|
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, val);
|
||||||
|
RefPtr<nsPresContext> presContext;
|
||||||
|
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||||
|
nsIPresShell* shell = presContext ? presContext->GetPresShell() : nullptr;
|
||||||
|
nsIFrame* rootScroll = shell ? shell->GetRootScrollFrame() : nullptr;
|
||||||
|
if (rootScroll) {
|
||||||
|
shell->FrameNeedsReflow(rootScroll, nsIPresShell::eStyleChange,
|
||||||
|
NS_FRAME_IS_DIRTY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (aName == nsGkAtoms::mozbrowser) {
|
||||||
|
mReallyIsBrowser = !!aValue && BrowserFramesEnabled() &&
|
||||||
|
PrincipalAllowsBrowserFrame(NodePrincipal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aName == nsGkAtoms::mozbrowser && aNameSpaceID == kNameSpaceID_None) {
|
|
||||||
mReallyIsBrowser = !!aValue && BrowserFramesEnabled() &&
|
|
||||||
PrincipalAllowsBrowserFrame(NodePrincipal());
|
|
||||||
}
|
|
||||||
|
|
||||||
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||||
aOldValue, aNotify);
|
aOldValue, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLFrameElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
|
||||||
|
nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
AfterMaybeChangeAttr(aNamespaceID, aName, &aValue, aNotify);
|
||||||
|
|
||||||
|
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||||
|
aValue, aNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsGenericHTMLFrameElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
|
||||||
|
nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify)
|
||||||
|
{
|
||||||
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
|
if (aName == nsGkAtoms::src) {
|
||||||
|
if (aValue && (!IsHTMLElement(nsGkAtoms::iframe) ||
|
||||||
|
!HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc))) {
|
||||||
|
// Don't propagate error here. The attribute was successfully set,
|
||||||
|
// that's what we should reflect.
|
||||||
|
LoadSrc();
|
||||||
|
}
|
||||||
|
} else if (aName == nsGkAtoms::name) {
|
||||||
|
// Propagate "name" to the docshell to make browsing context names live,
|
||||||
|
// per HTML5.
|
||||||
|
nsIDocShell* docShell = mFrameLoader ? mFrameLoader->GetExistingDocShell()
|
||||||
|
: nullptr;
|
||||||
|
if (docShell) {
|
||||||
|
if (aValue) {
|
||||||
|
docShell->SetName(aValue->String());
|
||||||
|
} else {
|
||||||
|
docShell->SetName(EmptyString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGenericHTMLFrameElement::DestroyContent()
|
nsGenericHTMLFrameElement::DestroyContent()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -53,20 +53,7 @@ public:
|
||||||
bool aCompileEventHandlers) override;
|
bool aCompileEventHandlers) override;
|
||||||
virtual void UnbindFromTree(bool aDeep = true,
|
virtual void UnbindFromTree(bool aDeep = true,
|
||||||
bool aNullParent = true) override;
|
bool aNullParent = true) override;
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAttrValue* aValue,
|
|
||||||
const nsAttrValue* aOldValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual void DestroyContent() override;
|
virtual void DestroyContent() override;
|
||||||
|
|
||||||
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
|
||||||
|
|
@ -111,6 +98,14 @@ protected:
|
||||||
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
|
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
|
||||||
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString& aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
RefPtr<nsFrameLoader> mFrameLoader;
|
RefPtr<nsFrameLoader> mFrameLoader;
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> mOpenerWindow;
|
nsCOMPtr<nsPIDOMWindowOuter> mOpenerWindow;
|
||||||
|
|
||||||
|
|
@ -133,6 +128,18 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GetManifestURL(nsAString& aOut);
|
void GetManifestURL(nsAString& aOut);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
|
* It will be called whether the value is being set or unset.
|
||||||
|
*
|
||||||
|
* @param aNamespaceID the namespace of the attr being set
|
||||||
|
* @param aName the localname of the attribute being set
|
||||||
|
* @param aValue the value being set or null if the value is being unset
|
||||||
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
|
*/
|
||||||
|
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue, bool aNotify);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsGenericHTMLFrameElement_h
|
#endif // nsGenericHTMLFrameElement_h
|
||||||
|
|
|
||||||
|
|
@ -1085,50 +1085,27 @@ nsMathMLElement::GetHrefURI() const
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMathMLElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
nsMathMLElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
const nsAttrValue* aValue,
|
||||||
bool aNotify)
|
const nsAttrValue* aOldValue, bool aNotify)
|
||||||
{
|
{
|
||||||
nsresult rv = nsMathMLElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
|
// It is important that this be done after the attribute is set/unset.
|
||||||
aValue, aNotify);
|
// We will need the updated attribute value because notifying the document
|
||||||
|
|
||||||
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
|
|
||||||
// is important here! The attribute is not set until SetAttr returns, and
|
|
||||||
// we will need the updated attribute value because notifying the document
|
|
||||||
// that content states have changed will call IntrinsicState, which will try
|
// that content states have changed will call IntrinsicState, which will try
|
||||||
// to get updated information about the visitedness from Link.
|
// to get updated information about the visitedness from Link.
|
||||||
if (aName == nsGkAtoms::href &&
|
if (aName == nsGkAtoms::href &&
|
||||||
(aNameSpaceID == kNameSpaceID_None ||
|
(aNameSpaceID == kNameSpaceID_None ||
|
||||||
aNameSpaceID == kNameSpaceID_XLink)) {
|
aNameSpaceID == kNameSpaceID_XLink)) {
|
||||||
if (aNameSpaceID == kNameSpaceID_XLink) {
|
if (aValue && aNameSpaceID == kNameSpaceID_XLink) {
|
||||||
WarnDeprecated(u"xlink:href", u"href", OwnerDoc());
|
WarnDeprecated(u"xlink:href", u"href", OwnerDoc());
|
||||||
}
|
}
|
||||||
Link::ResetLinkState(!!aNotify, true);
|
// Note: When unsetting href, there may still be another href since there
|
||||||
|
// are 2 possible namespaces.
|
||||||
|
Link::ResetLinkState(aNotify, aValue || Link::ElementHasHref());
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return nsMathMLElementBase::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||||
}
|
aOldValue, aNotify);
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsMathMLElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr,
|
|
||||||
bool aNotify)
|
|
||||||
{
|
|
||||||
nsresult rv = nsMathMLElementBase::UnsetAttr(aNameSpaceID, aAttr, aNotify);
|
|
||||||
|
|
||||||
// The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
|
|
||||||
// is important here! The attribute is not unset until UnsetAttr returns, and
|
|
||||||
// we will need the updated attribute value because notifying the document
|
|
||||||
// that content states have changed will call IntrinsicState, which will try
|
|
||||||
// to get updated information about the visitedness from Link.
|
|
||||||
if (aAttr == nsGkAtoms::href &&
|
|
||||||
(aNameSpaceID == kNameSpaceID_None ||
|
|
||||||
aNameSpaceID == kNameSpaceID_XLink)) {
|
|
||||||
// Note: just because we removed a single href attr doesn't mean there's no href,
|
|
||||||
// since there are 2 possible namespaces.
|
|
||||||
Link::ResetLinkState(!!aNotify, Link::ElementHasHref());
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject*
|
JSObject*
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,6 @@ public:
|
||||||
virtual bool IsLink(nsIURI** aURI) const override;
|
virtual bool IsLink(nsIURI** aURI) const override;
|
||||||
virtual void GetLinkTarget(nsAString& aTarget) override;
|
virtual void GetLinkTarget(nsAString& aTarget) override;
|
||||||
virtual already_AddRefed<nsIURI> GetHrefURI() const override;
|
virtual already_AddRefed<nsIURI> GetHrefURI() const override;
|
||||||
nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
const nsAString& aValue, bool aNotify)
|
|
||||||
{
|
|
||||||
return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
|
|
||||||
}
|
|
||||||
virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|
||||||
nsIAtom* aPrefix, const nsAString& aValue,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
|
|
||||||
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
||||||
|
|
||||||
|
|
@ -111,6 +101,11 @@ protected:
|
||||||
|
|
||||||
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
|
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValue* aValue,
|
||||||
|
const nsAttrValue* aOldValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mIncrementScriptLevel;
|
bool mIncrementScriptLevel;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "mozilla/dom/XBLChildrenElement.h"
|
#include "mozilla/dom/XBLChildrenElement.h"
|
||||||
#include "nsCharSeparatedTokenizer.h"
|
#include "nsCharSeparatedTokenizer.h"
|
||||||
#include "mozilla/dom/NodeListBinding.h"
|
#include "mozilla/dom/NodeListBinding.h"
|
||||||
|
#include "nsAttrValueOrString.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
@ -27,34 +28,24 @@ NS_INTERFACE_MAP_END_INHERITING(Element)
|
||||||
NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
|
NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
XBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
XBLChildrenElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
bool aNotify)
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify)
|
||||||
{
|
{
|
||||||
if (aAttribute == nsGkAtoms::includes &&
|
if (aNamespaceID == kNameSpaceID_None) {
|
||||||
aNameSpaceID == kNameSpaceID_None) {
|
if (aName == nsGkAtoms::includes) {
|
||||||
mIncludes.Clear();
|
mIncludes.Clear();
|
||||||
}
|
if (aValue) {
|
||||||
|
nsCharSeparatedTokenizer tok(aValue->String(), '|',
|
||||||
return Element::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||||
}
|
while (tok.hasMoreTokens()) {
|
||||||
|
mIncludes.AppendElement(NS_Atomize(tok.nextToken()));
|
||||||
bool
|
}
|
||||||
XBLChildrenElement::ParseAttribute(int32_t aNamespaceID,
|
}
|
||||||
nsIAtom* aAttribute,
|
|
||||||
const nsAString& aValue,
|
|
||||||
nsAttrValue& aResult)
|
|
||||||
{
|
|
||||||
if (aAttribute == nsGkAtoms::includes &&
|
|
||||||
aNamespaceID == kNameSpaceID_None) {
|
|
||||||
mIncludes.Clear();
|
|
||||||
nsCharSeparatedTokenizer tok(aValue, '|',
|
|
||||||
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
|
||||||
while (tok.hasMoreTokens()) {
|
|
||||||
mIncludes.AppendElement(NS_Atomize(tok.nextToken()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return nsXMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,6 @@ public:
|
||||||
|
|
||||||
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
virtual nsIDOMNode* AsDOMNode() override { return this; }
|
||||||
|
|
||||||
// nsIContent interface methods
|
|
||||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
|
||||||
bool aNotify) override;
|
|
||||||
virtual bool ParseAttribute(int32_t aNamespaceID,
|
|
||||||
nsIAtom* aAttribute,
|
|
||||||
const nsAString& aValue,
|
|
||||||
nsAttrValue& aResult) override;
|
|
||||||
|
|
||||||
void AppendInsertedChild(nsIContent* aChild)
|
void AppendInsertedChild(nsIContent* aChild)
|
||||||
{
|
{
|
||||||
mInsertedChildren.AppendElement(aChild);
|
mInsertedChildren.AppendElement(aChild);
|
||||||
|
|
@ -147,6 +139,10 @@ public:
|
||||||
protected:
|
protected:
|
||||||
~XBLChildrenElement();
|
~XBLChildrenElement();
|
||||||
|
|
||||||
|
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||||
|
const nsAttrValueOrString* aValue,
|
||||||
|
bool aNotify) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsTArray<nsIContent*> mInsertedChildren; // WEAK
|
nsTArray<nsIContent*> mInsertedChildren; // WEAK
|
||||||
nsTArray<nsCOMPtr<nsIAtom> > mIncludes;
|
nsTArray<nsCOMPtr<nsIAtom> > mIncludes;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue