зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1365092 - Move side effects of SetAttr, UnsetAttr, and ParseAttribute functions to BeforeSetAttr and AfterSetAttr r=bz
This is necessary to facilitate the transition to cloning attributes instead of reparsing them. MozReview-Commit-ID: Gyd1tD6ldly --HG-- extra : rebase_source : 777cfed750c95c448f953a6ec98026481997e227
This commit is contained in:
Родитель
2feb07c8c6
Коммит
99a80af5db
|
@ -40,7 +40,6 @@ nsStyledElement::ParseAttribute(int32_t aNamespaceID,
|
|||
nsAttrValue& aResult)
|
||||
{
|
||||
if (aAttribute == nsGkAtoms::style && aNamespaceID == kNameSpaceID_None) {
|
||||
SetMayHaveStyle();
|
||||
ParseStyleAttribute(aValue, aResult, false);
|
||||
return true;
|
||||
}
|
||||
|
@ -49,6 +48,22 @@ nsStyledElement::ParseAttribute(int32_t aNamespaceID,
|
|||
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
|
||||
nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
|
||||
const nsAString* aSerialized,
|
||||
|
|
|
@ -82,6 +82,10 @@ protected:
|
|||
nsresult ReparseStyleAttribute(bool aForceInDataDoc, bool aForceIfAlreadyParsed);
|
||||
|
||||
virtual void NodeInfoChanged(nsIDocument* aOldDoc) override;
|
||||
|
||||
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue,
|
||||
bool aNotify) override;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsStyledElement, NS_STYLED_ELEMENT_IID)
|
||||
|
|
|
@ -146,42 +146,22 @@ HTMLAreaElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLAreaElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify)
|
||||
HTMLAreaElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
nsresult rv =
|
||||
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, 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 (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None) {
|
||||
Link::ResetLinkState(!!aNotify, true);
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
// This must happen after the attribute is set. 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 (aName == nsGkAtoms::href) {
|
||||
Link::ResetLinkState(aNotify, !!aValue);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
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;
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
#define IMPL_URI_PART(_part) \
|
||||
|
|
|
@ -56,16 +56,6 @@ public:
|
|||
bool aCompileEventHandlers) override;
|
||||
virtual void UnbindFromTree(bool aDeep = true,
|
||||
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,
|
||||
bool aPreallocateChildren) const override;
|
||||
|
@ -193,6 +183,11 @@ protected:
|
|||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -461,38 +461,37 @@ NS_IMPL_UINT_ATTR_DEFAULT_VALUE(HTMLCanvasElement, Height, height, DEFAULT_CANVA
|
|||
NS_IMPL_BOOL_ATTR(HTMLCanvasElement, MozOpaque, moz_opaque)
|
||||
|
||||
nsresult
|
||||
HTMLCanvasElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify)
|
||||
HTMLCanvasElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
|
||||
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);
|
||||
}
|
||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
|
||||
return rv;
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLCanvasElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
bool aNotify)
|
||||
HTMLCanvasElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aName, aNotify);
|
||||
if (NS_SUCCEEDED(rv) && mCurrentContext &&
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::width || aName == nsGkAtoms::height || aName == nsGkAtoms::moz_opaque))
|
||||
{
|
||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
|
||||
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||
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;
|
||||
rv = UpdateContext(nullptr, JS::NullHandleValue, dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
UpdateContext(nullptr, JS::NullHandleValue, dummy);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -293,20 +293,6 @@ public:
|
|||
nsAttrValue& aResult) 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,
|
||||
bool aPreallocateChildren) const override;
|
||||
nsresult CopyInnerTo(mozilla::dom::Element* aDest,
|
||||
|
@ -377,6 +363,14 @@ protected:
|
|||
File** aResult);
|
||||
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();
|
||||
|
||||
bool mResetLayer;
|
||||
|
@ -410,6 +404,18 @@ public:
|
|||
CanvasContextType GetCurrentContextType() {
|
||||
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
|
||||
|
|
|
@ -210,75 +210,63 @@ IsValidContentSelectors(nsCSSSelector* aSelector)
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLContentElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify)
|
||||
HTMLContentElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::select) {
|
||||
if (aValue) {
|
||||
// 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) {
|
||||
// Select attribute was updated, the insertion point may match different
|
||||
// elements.
|
||||
nsIDocument* doc = OwnerDoc();
|
||||
nsCSSParser parser(doc->CSSLoader());
|
||||
mValidSelector = true;
|
||||
mSelectorList = nullptr;
|
||||
|
||||
mValidSelector = true;
|
||||
mSelectorList = nullptr;
|
||||
nsAutoString valueStr;
|
||||
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,
|
||||
doc->GetDocumentURI(),
|
||||
// Bug 11240
|
||||
0, // XXX get the line number!
|
||||
getter_Transfers(mSelectorList));
|
||||
|
||||
// We don't want to return an exception if parsing failed because
|
||||
// the spec does not define it as an exception case.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Ensure that all the selectors are valid
|
||||
nsCSSSelectorList* selectors = mSelectorList;
|
||||
while (selectors) {
|
||||
if (!IsValidContentSelectors(selectors->mSelectors)) {
|
||||
// If we have an invalid selector, we can not match anything.
|
||||
mValidSelector = false;
|
||||
mSelectorList = nullptr;
|
||||
break;
|
||||
// We don't want to return an exception if parsing failed because
|
||||
// the spec does not define it as an exception case.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Ensure that all the selectors are valid
|
||||
nsCSSSelectorList* selectors = mSelectorList;
|
||||
while (selectors) {
|
||||
if (!IsValidContentSelectors(selectors->mSelectors)) {
|
||||
// If we have an invalid selector, we can not match anything.
|
||||
mValidSelector = false;
|
||||
mSelectorList = nullptr;
|
||||
break;
|
||||
}
|
||||
selectors = selectors->mNext;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -64,13 +64,6 @@ public:
|
|||
void InsertMatchedNode(uint32_t aIndex, nsIContent* aContent);
|
||||
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.
|
||||
already_AddRefed<DistributedContentList> GetDistributedNodes();
|
||||
void GetSelect(nsAString& aSelect)
|
||||
|
@ -96,6 +89,11 @@ protected:
|
|||
*/
|
||||
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
|
||||
* content insertion selector.
|
||||
|
|
|
@ -190,27 +190,31 @@ HTMLFormElement::GetElements(nsIDOMHTMLCollection** aElements)
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLFormElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify)
|
||||
HTMLFormElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue, bool aNotify)
|
||||
{
|
||||
if ((aName == nsGkAtoms::action || aName == nsGkAtoms::target) &&
|
||||
aNameSpaceID == kNameSpaceID_None) {
|
||||
if (mPendingSubmission) {
|
||||
// aha, there is a pending submission that means we're in
|
||||
// the script and we need to flush it. let's tell it
|
||||
// that the event was ignored to force the flush.
|
||||
// the second argument is not playing a role at all.
|
||||
FlushPendingSubmission();
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::action || aName == nsGkAtoms::target) {
|
||||
// This check is mostly to preserve previous behavior.
|
||||
if (aValue) {
|
||||
if (mPendingSubmission) {
|
||||
// aha, there is a pending submission that means we're in
|
||||
// the script and we need to flush it. let's tell it
|
||||
// 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
|
||||
|
|
|
@ -105,14 +105,9 @@ public:
|
|||
bool aCompileEventHandlers) override;
|
||||
virtual void UnbindFromTree(bool aDeep = true,
|
||||
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 BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue,
|
||||
bool aNotify) override;
|
||||
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/dom/EventHandlerBinding.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "nsAttrValueOrString.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
|
||||
|
||||
|
@ -65,43 +66,45 @@ HTMLFrameSetElement::GetRows(nsAString& aRows)
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLFrameSetElement::SetAttr(int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
nsIAtom* aPrefix,
|
||||
const nsAString& aValue,
|
||||
bool aNotify)
|
||||
HTMLFrameSetElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
/* The main goal here is to see whether the _number_ of rows or
|
||||
* columns has changed. If it has, we need to reframe; otherwise
|
||||
* we want to reflow. So we set mCurrentRowColHint here, then call
|
||||
* nsGenericHTMLElement::SetAttr, which will end up calling
|
||||
* GetAttributeChangeHint and notifying layout with that hint.
|
||||
* Once nsGenericHTMLElement::SetAttr returns, we want to go back to our
|
||||
* normal hint, which is NS_STYLE_HINT_REFLOW.
|
||||
* columns has changed. If it has, we need to reframe; otherwise
|
||||
* we want to reflow.
|
||||
* Ideally, the style hint would be changed back to reflow after the reframe
|
||||
* has been performed. Unfortunately, however, the reframe will be performed
|
||||
* by the call to nsNodeUtils::AttributeChanged, which occurs *after*
|
||||
* 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) {
|
||||
int32_t oldRows = mNumRows;
|
||||
ParseRowCol(aValue, mNumRows, &mRowSpecs);
|
||||
mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::rows) {
|
||||
if (aValue) {
|
||||
int32_t oldRows = mNumRows;
|
||||
ParseRowCol(aValue->String(), mNumRows, &mRowSpecs);
|
||||
|
||||
if (mNumRows != oldRows) {
|
||||
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
||||
}
|
||||
} else if (aAttribute == nsGkAtoms::cols &&
|
||||
aNameSpaceID == kNameSpaceID_None) {
|
||||
int32_t oldCols = mNumCols;
|
||||
ParseRowCol(aValue, mNumCols, &mColSpecs);
|
||||
if (mNumRows != oldRows) {
|
||||
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
||||
}
|
||||
}
|
||||
} else if (aName == nsGkAtoms::cols) {
|
||||
if (aValue) {
|
||||
int32_t oldCols = mNumCols;
|
||||
ParseRowCol(aValue->String(), mNumCols, &mColSpecs);
|
||||
|
||||
if (mNumCols != oldCols) {
|
||||
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
||||
if (mNumCols != oldCols) {
|
||||
mCurrentRowColHint = nsChangeHint_ReconstructFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aAttribute, aPrefix,
|
||||
aValue, aNotify);
|
||||
mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
|
||||
|
||||
return rv;
|
||||
return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -100,17 +100,6 @@ public:
|
|||
#undef WINDOW_EVENT_HELPER
|
||||
#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.
|
||||
* @param out int32_t aNumValues The number of row sizes specified.
|
||||
|
@ -144,6 +133,10 @@ protected:
|
|||
|
||||
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:
|
||||
nsresult ParseRowCol(const nsAString& aValue,
|
||||
int32_t& aNumSpecs,
|
||||
|
|
|
@ -153,55 +153,50 @@ HTMLIFrameElement::GetAttributeMappingFunction() const
|
|||
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
|
||||
HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
if (aName == nsGkAtoms::sandbox &&
|
||||
aNameSpaceID == kNameSpaceID_None && mFrameLoader) {
|
||||
// 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());
|
||||
AfterMaybeChangeAttr(aNameSpaceID, aName, aNotify);
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::sandbox) {
|
||||
if (mFrameLoader) {
|
||||
// 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,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLIFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
||||
bool aNotify)
|
||||
HTMLIFrameElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
// Invoke on the superclass.
|
||||
nsresult rv = nsGenericHTMLFrameElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::srcdoc) {
|
||||
// Fall back to the src attribute, if any
|
||||
LoadSrc();
|
||||
return nsGenericHTMLFrameElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -47,21 +47,6 @@ public:
|
|||
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
|
||||
bool aPreallocateChildren) 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();
|
||||
|
||||
// Web IDL binding methods
|
||||
|
@ -198,11 +183,30 @@ protected:
|
|||
|
||||
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:
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
GenericSpecifiedValues* aGenericData);
|
||||
|
||||
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
|
||||
|
|
|
@ -70,21 +70,6 @@ HTMLLegendElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|||
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
|
||||
HTMLLegendElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
|
|
@ -42,16 +42,6 @@ public:
|
|||
nsAttrValue& aResult) override;
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
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,
|
||||
bool aPreallocateChildren) const override;
|
||||
|
|
|
@ -4190,80 +4190,76 @@ int32_t HTMLMediaElement::TabIndexDefault()
|
|||
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
|
||||
HTMLMediaElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
|
||||
mSrcMediaSource = nullptr;
|
||||
if (aValue) {
|
||||
nsString srcStr = aValue->GetStringValue();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NewURIFromString(srcStr, getter_AddRefs(uri));
|
||||
if (uri && IsMediaSourceURI(uri)) {
|
||||
nsresult rv =
|
||||
NS_GetSourceForMediaSourceURI(uri, getter_AddRefs(mSrcMediaSource));
|
||||
if (NS_FAILED(rv)) {
|
||||
nsAutoString spec;
|
||||
GetCurrentSrc(spec);
|
||||
const char16_t* params[] = { spec.get() };
|
||||
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::src) {
|
||||
mSrcMediaSource = nullptr;
|
||||
if (aValue) {
|
||||
nsString srcStr = aValue->GetStringValue();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NewURIFromString(srcStr, getter_AddRefs(uri));
|
||||
if (uri && IsMediaSourceURI(uri)) {
|
||||
nsresult rv =
|
||||
NS_GetSourceForMediaSourceURI(uri, getter_AddRefs(mSrcMediaSource));
|
||||
if (NS_FAILED(rv)) {
|
||||
nsAutoString spec;
|
||||
GetCurrentSrc(spec);
|
||||
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,
|
||||
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,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandlers)
|
||||
|
|
|
@ -126,22 +126,6 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
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,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -1315,6 +1299,14 @@ protected:
|
|||
// suspend-video-decoder is disabled.
|
||||
void MarkAsTainted();
|
||||
|
||||
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.
|
||||
// At most one of mDecoder and mSrcStream can be non-null.
|
||||
RefPtr<MediaDecoder> mDecoder;
|
||||
|
@ -1722,6 +1714,16 @@ public:
|
|||
uint32_t mCount;
|
||||
};
|
||||
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);
|
||||
|
||||
// Total time a video has spent playing.
|
||||
TimeDurationAccumulator mPlayTime;
|
||||
|
||||
|
|
|
@ -291,46 +291,46 @@ HTMLObjectElement::UnbindFromTree(bool aDeep,
|
|||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
HTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
|
||||
nsIAtom *aPrefix, const nsAString &aValue,
|
||||
bool aNotify)
|
||||
HTMLObjectElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 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 &&
|
||||
aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data &&
|
||||
!BlockEmbedOrObjectContentLoading()) {
|
||||
return LoadObject(aNotify, true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return nsGenericHTMLFormElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
||||
bool aNotify)
|
||||
HTMLObjectElement::OnAttrSetButNotChanged(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID,
|
||||
aAttribute, aNotify);
|
||||
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// See comment in SetAttr
|
||||
if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren &&
|
||||
aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data &&
|
||||
!BlockEmbedOrObjectContentLoading()) {
|
||||
return LoadObject(aNotify, true);
|
||||
return nsGenericHTMLFormElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
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 && !BlockEmbedOrObjectContentLoading()) {
|
||||
return LoadObject(aNotify, true);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -59,11 +59,6 @@ public:
|
|||
bool aCompileEventHandlers) override;
|
||||
virtual void UnbindFromTree(bool aDeep = true,
|
||||
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 IMEState GetDesiredIMEState() override;
|
||||
|
@ -252,6 +247,14 @@ protected:
|
|||
// Override for nsImageLoadingContent.
|
||||
nsIContent* AsContent() override { return this; }
|
||||
|
||||
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:
|
||||
/**
|
||||
* Returns if the element is currently focusable regardless of it's tabindex
|
||||
|
@ -271,6 +274,18 @@ private:
|
|||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
GenericSpecifiedValues* aGenericData);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
|
|
|
@ -1301,9 +1301,22 @@ HTMLSelectElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
const nsAttrValueOrString* aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
if (aNotify && aName == nsGkAtoms::disabled &&
|
||||
aNameSpaceID == kNameSpaceID_None) {
|
||||
mDisabledChanged = true;
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::disabled) {
|
||||
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,
|
||||
|
@ -1324,6 +1337,12 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
// Clear the cached @autocomplete attribute and autocompleteInfo state.
|
||||
mAutocompleteAttrState = nsContentUtils::eAutocompleteAttrState_Unknown;
|
||||
mAutocompleteInfoState = 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1332,37 +1351,6 @@ HTMLSelectElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
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
|
||||
HTMLSelectElement::DoneAddingChildren(bool aHaveNotified)
|
||||
{
|
||||
|
|
|
@ -391,8 +391,6 @@ public:
|
|||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue,
|
||||
bool aNotify) override;
|
||||
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
||||
bool aNotify) override;
|
||||
|
||||
virtual void DoneAddingChildren(bool aHaveNotified) override;
|
||||
virtual bool IsDoneAddingChildren() override {
|
||||
|
|
|
@ -230,52 +230,33 @@ SetBaseTargetUsingFirstBaseWithTarget(nsIDocument* aDocument,
|
|||
}
|
||||
|
||||
nsresult
|
||||
HTMLSharedElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify)
|
||||
HTMLSharedElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
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 (aNamespaceID == kNameSpaceID_None) {
|
||||
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) {
|
||||
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 NS_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -59,17 +59,6 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
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,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -182,6 +171,11 @@ protected:
|
|||
virtual ~HTMLSharedElement();
|
||||
|
||||
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
|
||||
|
|
|
@ -161,27 +161,54 @@ HTMLSharedObjectElement::UnbindFromTree(bool aDeep,
|
|||
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
|
||||
HTMLSharedObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName,
|
||||
nsIAtom *aPrefix, const nsAString &aValue,
|
||||
bool aNotify)
|
||||
HTMLSharedObjectElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
|
||||
nsIAtom* aName,
|
||||
const nsAttrValueOrString& aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// 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 &&
|
||||
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()
|
||||
&& !BlockEmbedOrObjectContentLoading()) {
|
||||
return LoadObject(aNotify, true);
|
||||
return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLSharedObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
|
||||
nsIAtom* aName,
|
||||
bool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
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 &&
|
||||
!BlockEmbedOrObjectContentLoading()) {
|
||||
nsresult rv = LoadObject(aNotify, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -57,9 +57,6 @@ public:
|
|||
bool aCompileEventHandlers) override;
|
||||
virtual void UnbindFromTree(bool aDeep = true,
|
||||
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 IMEState GetDesiredIMEState() override;
|
||||
|
@ -206,6 +203,14 @@ protected:
|
|||
// Override for nsImageLoadingContent.
|
||||
nsIContent* AsContent() override { return this; }
|
||||
|
||||
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:
|
||||
virtual ~HTMLSharedObjectElement();
|
||||
|
||||
|
@ -226,6 +231,17 @@ private:
|
|||
|
||||
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
||||
GenericSpecifiedValues* aGenericData);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -304,55 +304,6 @@ nsGenericHTMLFrameElement::UnbindFromTree(bool aDeep, bool 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
|
||||
nsGenericHTMLFrameElement::MapScrollingAttribute(const nsAttrValue* aValue)
|
||||
{
|
||||
|
@ -385,39 +336,88 @@ nsGenericHTMLFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
|||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
if (aName == nsGkAtoms::scrolling && aNameSpaceID == kNameSpaceID_None) {
|
||||
if (mFrameLoader) {
|
||||
nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
|
||||
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(docshell);
|
||||
if (scrollable) {
|
||||
int32_t cur;
|
||||
scrollable->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, &cur);
|
||||
int32_t val = MapScrollingAttribute(aValue);
|
||||
if (cur != val) {
|
||||
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);
|
||||
if (aValue) {
|
||||
nsAttrValueOrString value(aValue);
|
||||
AfterMaybeChangeAttr(aNameSpaceID, aName, &value, aNotify);
|
||||
} else {
|
||||
AfterMaybeChangeAttr(aNameSpaceID, aName, nullptr, aNotify);
|
||||
}
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::scrolling) {
|
||||
if (mFrameLoader) {
|
||||
nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
|
||||
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(docshell);
|
||||
if (scrollable) {
|
||||
int32_t cur;
|
||||
scrollable->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, &cur);
|
||||
int32_t val = MapScrollingAttribute(aValue);
|
||||
if (cur != val) {
|
||||
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,
|
||||
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
|
||||
nsGenericHTMLFrameElement::DestroyContent()
|
||||
{
|
||||
|
|
|
@ -53,20 +53,6 @@ public:
|
|||
bool aCompileEventHandlers) override;
|
||||
virtual void UnbindFromTree(bool aDeep = true,
|
||||
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;
|
||||
|
||||
nsresult CopyInnerTo(mozilla::dom::Element* aDest, bool aPreallocateChildren);
|
||||
|
@ -114,6 +100,14 @@ protected:
|
|||
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
|
||||
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;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mOpenerWindow;
|
||||
|
||||
|
@ -136,6 +130,18 @@ protected:
|
|||
|
||||
private:
|
||||
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
|
||||
|
|
|
@ -1068,50 +1068,27 @@ nsMathMLElement::GetHrefURI() const
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsMathMLElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
bool aNotify)
|
||||
nsMathMLElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue,
|
||||
const nsAttrValue* aOldValue, bool aNotify)
|
||||
{
|
||||
nsresult rv = nsMathMLElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, 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
|
||||
// It is important that this be done after the attribute is set/unset.
|
||||
// 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 (aName == nsGkAtoms::href &&
|
||||
(aNameSpaceID == kNameSpaceID_None ||
|
||||
aNameSpaceID == kNameSpaceID_XLink)) {
|
||||
if (aNameSpaceID == kNameSpaceID_XLink) {
|
||||
if (aValue && aNameSpaceID == kNameSpaceID_XLink) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
return nsMathMLElementBase::AfterSetAttr(aNameSpaceID, aName, aValue,
|
||||
aOldValue, aNotify);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
|
|
@ -94,16 +94,6 @@ public:
|
|||
virtual bool IsLink(nsIURI** aURI) const override;
|
||||
virtual void GetLinkTarget(nsAString& aTarget) 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; }
|
||||
|
||||
|
@ -118,6 +108,11 @@ protected:
|
|||
|
||||
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:
|
||||
bool mIncrementScriptLevel;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/dom/XBLChildrenElement.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "mozilla/dom/NodeListBinding.h"
|
||||
#include "nsAttrValueOrString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -27,35 +28,24 @@ NS_INTERFACE_MAP_END_INHERITING(Element)
|
|||
NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
|
||||
|
||||
nsresult
|
||||
XBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
|
||||
bool aNotify)
|
||||
XBLChildrenElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue,
|
||||
bool aNotify)
|
||||
{
|
||||
if (aAttribute == nsGkAtoms::includes &&
|
||||
aNameSpaceID == kNameSpaceID_None) {
|
||||
mIncludes.Clear();
|
||||
}
|
||||
|
||||
return Element::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
|
||||
}
|
||||
|
||||
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()));
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::includes) {
|
||||
mIncludes.Clear();
|
||||
if (aValue) {
|
||||
nsCharSeparatedTokenizer tok(aValue->String(), '|',
|
||||
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||
while (tok.hasMoreTokens()) {
|
||||
mIncludes.AppendElement(NS_Atomize(tok.nextToken()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsXMLElement::ParseAttribute(aNamespaceID, aAttribute,
|
||||
aValue, aResult);
|
||||
return nsXMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -38,14 +38,6 @@ public:
|
|||
|
||||
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)
|
||||
{
|
||||
mInsertedChildren.AppendElement(aChild);
|
||||
|
@ -147,6 +139,9 @@ public:
|
|||
|
||||
protected:
|
||||
~XBLChildrenElement();
|
||||
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValueOrString* aValue,
|
||||
bool aNotify) override;
|
||||
|
||||
private:
|
||||
nsTArray<nsIContent*> mInsertedChildren; // WEAK
|
||||
|
|
Загрузка…
Ссылка в новой задаче