summaryrefslogtreecommitdiff
path: root/dom
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2022-01-07 20:09:13 +0000
committerMoonchild <moonchild@palemoon.org>2022-04-08 00:27:44 +0200
commit834ded7d18cf9acbb7d975fe22f2dea4f1f4c57d (patch)
tree508919b16a468d692cd144d6b87a80b9dcfc0840 /dom
parentc61754591470ec30534d824c57f5c868bbfd7a22 (diff)
downloaduxp-834ded7d18cf9acbb7d975fe22f2dea4f1f4c57d.tar.gz
Issue #1852 - Undo Stylo nonsense that breaks body and frame margins.
This restores support for using HTML tag styling of margins on the body. Reftests post bug still pass for dynamic changes, so does the newly-added test for body margins and frames that tests the old styling method. This also removes the reftest list for stylo testing for obvious reasons.
Diffstat (limited to 'dom')
-rw-r--r--dom/base/nsAttrAndChildArray.cpp13
-rw-r--r--dom/base/nsAttrAndChildArray.h6
-rw-r--r--dom/base/nsFrameLoader.cpp3
-rw-r--r--dom/base/nsMappedAttributes.cpp12
-rw-r--r--dom/html/HTMLBodyElement.cpp238
-rw-r--r--dom/html/HTMLBodyElement.h38
-rw-r--r--dom/html/HTMLTableCellElement.cpp14
-rw-r--r--dom/html/HTMLTableCellElement.h2
-rw-r--r--dom/html/HTMLTableElement.cpp27
-rw-r--r--dom/html/HTMLTableElement.h4
-rw-r--r--dom/html/reftests/reftest-stylo.list73
-rw-r--r--dom/html/test/body-margin-test/child.html4
-rw-r--r--dom/html/test/body-margin-test/fruit.jpgbin0 -> 79942 bytes
-rw-r--r--dom/html/test/body-margin-test/test-body.html9
-rw-r--r--dom/html/test/body-margin-test/test-frame.html11
15 files changed, 283 insertions, 171 deletions
diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp
index 7ec5cebf01..23b0bf7e95 100644
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -718,19 +718,10 @@ nsAttrAndChildArray::MappedAttrCount() const
return mImpl && mImpl->mMappedAttrs ? (uint32_t)mImpl->mMappedAttrs->Count() : 0;
}
-nsresult
-nsAttrAndChildArray::ForceMapped(nsMappedAttributeElement* aContent, nsIDocument* aDocument)
-{
- nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet();
- RefPtr<nsMappedAttributes> mapped = GetModifiableMapped(aContent, sheet, false, 0);
- return MakeMappedUnique(mapped);
-}
-
nsMappedAttributes*
nsAttrAndChildArray::GetModifiableMapped(nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
- bool aWillAddAttr,
- int32_t aAttrCount)
+ bool aWillAddAttr)
{
if (mImpl && mImpl->mMappedAttrs) {
return mImpl->mMappedAttrs->Clone(aWillAddAttr);
@@ -740,7 +731,7 @@ nsAttrAndChildArray::GetModifiableMapped(nsMappedAttributeElement* aContent,
nsMapRuleToAttributesFunc mapRuleFunc =
aContent->GetAttributeMappingFunction();
- return new (aAttrCount) nsMappedAttributes(aSheet, mapRuleFunc);
+ return new nsMappedAttributes(aSheet, mapRuleFunc);
}
nsresult
diff --git a/dom/base/nsAttrAndChildArray.h b/dom/base/nsAttrAndChildArray.h
index af12fba47b..0a6db7a5f3 100644
--- a/dom/base/nsAttrAndChildArray.h
+++ b/dom/base/nsAttrAndChildArray.h
@@ -144,9 +144,6 @@ public:
return MappedAttrCount();
}
- // Force this to have mapped attributes, even if those attributes are empty.
- nsresult ForceMapped(nsMappedAttributeElement* aContent, nsIDocument* aDocument);
-
private:
nsAttrAndChildArray(const nsAttrAndChildArray& aOther) = delete;
nsAttrAndChildArray& operator=(const nsAttrAndChildArray& aOther) = delete;
@@ -160,8 +157,7 @@ private:
nsMappedAttributes*
GetModifiableMapped(nsMappedAttributeElement* aContent,
nsHTMLStyleSheet* aSheet,
- bool aWillAddAttr,
- int32_t aAttrCount = 1);
+ bool aWillAddAttr);
nsresult MakeMappedUnique(nsMappedAttributes* aAttributes);
uint32_t AttrSlotsSize() const
diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp
index 58b7a93361..6e92f3da20 100644
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -56,7 +56,6 @@
#include "nsGlobalWindow.h"
#include "nsPIWindowRoot.h"
#include "nsLayoutUtils.h"
-#include "nsMappedAttributes.h"
#include "nsView.h"
#include "GroupedSHistory.h"
#include "PartialSHistory.h"
@@ -934,8 +933,6 @@ nsFrameLoader::MarginsChanged(uint32_t aMarginWidth,
RefPtr<nsPresContext> presContext;
mDocShell->GetPresContext(getter_AddRefs(presContext));
if (presContext)
- // rebuild, because now the same nsMappedAttributes* will produce
- // a different style
presContext->RebuildAllStyleData(nsChangeHint(0), eRestyle_Subtree);
}
diff --git a/dom/base/nsMappedAttributes.cpp b/dom/base/nsMappedAttributes.cpp
index 825409adc4..949297c489 100644
--- a/dom/base/nsMappedAttributes.cpp
+++ b/dom/base/nsMappedAttributes.cpp
@@ -61,17 +61,11 @@ nsMappedAttributes::Clone(bool aWillAddAttr)
void* nsMappedAttributes::operator new(size_t aSize, uint32_t aAttrCount) CPP_THROW_NEW
{
- size_t size = aSize + aAttrCount * sizeof(InternalAttr);
+ NS_ASSERTION(aAttrCount > 0, "zero-attribute nsMappedAttributes requested");
// aSize will include the mAttrs buffer so subtract that.
- // We don't want to under-allocate, however, so do not subtract
- // if we have zero attributes. The zero attribute case only happens
- // for <body>'s mapped attributes
- if (aAttrCount != 0) {
- size -= sizeof(void*[1]);
- }
-
- void* newAttrs = ::operator new(size);
+ void* newAttrs = ::operator new(aSize - sizeof(void*[1]) +
+ aAttrCount * sizeof(InternalAttr));
#ifdef DEBUG
static_cast<nsMappedAttributes*>(newAttrs)->mBufferSize = aAttrCount;
diff --git a/dom/html/HTMLBodyElement.cpp b/dom/html/HTMLBodyElement.cpp
index d030b69d7b..a91dccfb50 100644
--- a/dom/html/HTMLBodyElement.cpp
+++ b/dom/html/HTMLBodyElement.cpp
@@ -27,8 +27,180 @@ namespace dom {
//----------------------------------------------------------------------
+BodyRule::BodyRule(HTMLBodyElement* aPart)
+ : mPart(aPart)
+{
+}
+
+BodyRule::~BodyRule()
+{
+}
+
+NS_IMPL_ISUPPORTS(BodyRule, nsIStyleRule)
+
+/* virtual */ void
+BodyRule::MapRuleInfoInto(nsRuleData* aData)
+{
+ if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) || !mPart)
+ return; // We only care about margins.
+
+ int32_t bodyMarginWidth = -1;
+ int32_t bodyMarginHeight = -1;
+ int32_t bodyTopMargin = -1;
+ int32_t bodyBottomMargin = -1;
+ int32_t bodyLeftMargin = -1;
+ int32_t bodyRightMargin = -1;
+
+ // check the mode (fortunately, the ruleData has a presContext for us to use!)
+ NS_ASSERTION(aData->mPresContext, "null presContext in ruleNode was unexpected");
+ nsCompatibility mode = aData->mPresContext->CompatibilityMode();
+
+
+ const nsAttrValue* value;
+ if (mPart->GetAttrCount() > 0) {
+ // if marginwidth/marginheight are set, reflect them as 'margin'
+ value = mPart->GetParsedAttr(nsGkAtoms::marginwidth);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ bodyMarginWidth = value->GetIntegerValue();
+ if (bodyMarginWidth < 0) bodyMarginWidth = 0;
+ nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+ if (marginLeft->GetUnit() == eCSSUnit_Null)
+ marginLeft->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel);
+ nsCSSValue* marginRight = aData->ValueForMarginRight();
+ if (marginRight->GetUnit() == eCSSUnit_Null)
+ marginRight->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel);
+ }
+
+ value = mPart->GetParsedAttr(nsGkAtoms::marginheight);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ bodyMarginHeight = value->GetIntegerValue();
+ if (bodyMarginHeight < 0) bodyMarginHeight = 0;
+ nsCSSValue* marginTop = aData->ValueForMarginTop();
+ if (marginTop->GetUnit() == eCSSUnit_Null)
+ marginTop->SetFloatValue((float)bodyMarginHeight, eCSSUnit_Pixel);
+ nsCSSValue* marginBottom = aData->ValueForMarginBottom();
+ if (marginBottom->GetUnit() == eCSSUnit_Null)
+ marginBottom->SetFloatValue((float)bodyMarginHeight, eCSSUnit_Pixel);
+ }
+
+ // topmargin (IE-attribute)
+ value = mPart->GetParsedAttr(nsGkAtoms::topmargin);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ bodyTopMargin = value->GetIntegerValue();
+ if (bodyTopMargin < 0) bodyTopMargin = 0;
+ nsCSSValue* marginTop = aData->ValueForMarginTop();
+ if (marginTop->GetUnit() == eCSSUnit_Null)
+ marginTop->SetFloatValue((float)bodyTopMargin, eCSSUnit_Pixel);
+ }
+
+ // bottommargin (IE-attribute)
+ value = mPart->GetParsedAttr(nsGkAtoms::bottommargin);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ bodyBottomMargin = value->GetIntegerValue();
+ if (bodyBottomMargin < 0) bodyBottomMargin = 0;
+ nsCSSValue* marginBottom = aData->ValueForMarginBottom();
+ if (marginBottom->GetUnit() == eCSSUnit_Null)
+ marginBottom->SetFloatValue((float)bodyBottomMargin, eCSSUnit_Pixel);
+ }
+
+ // leftmargin (IE-attribute)
+ value = mPart->GetParsedAttr(nsGkAtoms::leftmargin);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ bodyLeftMargin = value->GetIntegerValue();
+ if (bodyLeftMargin < 0) bodyLeftMargin = 0;
+ nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+ if (marginLeft->GetUnit() == eCSSUnit_Null)
+ marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel);
+ }
+
+ // rightmargin (IE-attribute)
+ value = mPart->GetParsedAttr(nsGkAtoms::rightmargin);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ bodyRightMargin = value->GetIntegerValue();
+ if (bodyRightMargin < 0) bodyRightMargin = 0;
+ nsCSSValue* marginRight = aData->ValueForMarginRight();
+ if (marginRight->GetUnit() == eCSSUnit_Null)
+ marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel);
+ }
+
+ }
+
+ // if marginwidth or marginheight is set in the <frame> and not set in the <body>
+ // reflect them as margin in the <body>
+ if (bodyMarginWidth == -1 || bodyMarginHeight == -1) {
+ nsCOMPtr<nsIDocShell> docShell(aData->mPresContext->GetDocShell());
+ if (docShell) {
+ nscoord frameMarginWidth=-1; // default value
+ nscoord frameMarginHeight=-1; // default value
+ docShell->GetMarginWidth(&frameMarginWidth); // -1 indicates not set
+ docShell->GetMarginHeight(&frameMarginHeight);
+ if ((frameMarginWidth >= 0) && (bodyMarginWidth == -1)) { // set in <frame> & not in <body>
+ if (eCompatibility_NavQuirks == mode) {
+ if ((bodyMarginHeight == -1) && (0 > frameMarginHeight)) // nav quirk
+ frameMarginHeight = 0;
+ }
+ }
+ if ((frameMarginHeight >= 0) && (bodyMarginHeight == -1)) { // set in <frame> & not in <body>
+ if (eCompatibility_NavQuirks == mode) {
+ if ((bodyMarginWidth == -1) && (0 > frameMarginWidth)) // nav quirk
+ frameMarginWidth = 0;
+ }
+ }
+
+ if ((bodyMarginWidth == -1) && (frameMarginWidth >= 0)) {
+ nsCSSValue* marginLeft = aData->ValueForMarginLeft();
+ if (marginLeft->GetUnit() == eCSSUnit_Null)
+ marginLeft->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel);
+ nsCSSValue* marginRight = aData->ValueForMarginRight();
+ if (marginRight->GetUnit() == eCSSUnit_Null)
+ marginRight->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel);
+ }
+
+ if ((bodyMarginHeight == -1) && (frameMarginHeight >= 0)) {
+ nsCSSValue* marginTop = aData->ValueForMarginTop();
+ if (marginTop->GetUnit() == eCSSUnit_Null)
+ marginTop->SetFloatValue((float)frameMarginHeight, eCSSUnit_Pixel);
+ nsCSSValue* marginBottom = aData->ValueForMarginBottom();
+ if (marginBottom->GetUnit() == eCSSUnit_Null)
+ marginBottom->SetFloatValue((float)frameMarginHeight, eCSSUnit_Pixel);
+ }
+ }
+ }
+}
+
+/* virtual */ bool
+BodyRule::MightMapInheritedStyleData()
+{
+ return false;
+}
+
+/* virtual */ bool
+BodyRule::GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
+ nsCSSValue* aValue)
+{
+ MOZ_ASSERT(false, "GetDiscretelyAnimatedCSSValue is not implemented yet");
+ return false;
+}
+
+#ifdef DEBUG
+/* virtual */ void
+BodyRule::List(FILE* out, int32_t aIndent) const
+{
+ nsAutoCString indent;
+ for (int32_t index = aIndent; --index >= 0; ) {
+ indent.AppendLiteral(" ");
+ }
+ fprintf_stderr(out, "%s[body rule] {}\n", indent.get());
+}
+#endif
+
+//----------------------------------------------------------------------
+
HTMLBodyElement::~HTMLBodyElement()
{
+ if (mContentStyleRule) {
+ mContentStyleRule->mPart = nullptr;
+ }
}
JSObject*
@@ -176,6 +348,17 @@ HTMLBodyElement::ParseAttribute(int32_t aNamespaceID,
}
void
+HTMLBodyElement::UnbindFromTree(bool aDeep, bool aNullParent)
+{
+ if (mContentStyleRule) {
+ mContentStyleRule->mPart = nullptr;
+ mContentStyleRule = nullptr;
+ }
+
+ nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
+}
+
+void
HTMLBodyElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
@@ -230,6 +413,22 @@ HTMLBodyElement::GetAttributeMappingFunction() const
return &MapAttributesIntoRule;
}
+NS_IMETHODIMP
+HTMLBodyElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
+{
+ nsGenericHTMLElement::WalkContentStyleRules(aRuleWalker);
+
+ if (!mContentStyleRule && IsInUncomposedDoc()) {
+ // XXXbz should this use OwnerDoc() or GetComposedDoc()?
+ // sXBL/XBL2 issue!
+ mContentStyleRule = new BodyRule(this);
+ }
+ if (aRuleWalker && mContentStyleRule) {
+ aRuleWalker->Forward(mContentStyleRule);
+ }
+ return NS_OK;
+}
+
NS_IMETHODIMP_(bool)
HTMLBodyElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{
@@ -238,12 +437,12 @@ HTMLBodyElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{ &nsGkAtoms::vlink },
{ &nsGkAtoms::alink },
{ &nsGkAtoms::text },
+ // These aren't mapped through attribute mapping, but they are
+ // mapped through a style rule, so it is attribute dependent style.
+ // XXXldb But we don't actually replace the body rule when we have
+ // dynamic changes...
{ &nsGkAtoms::marginwidth },
{ &nsGkAtoms::marginheight },
- { &nsGkAtoms::topmargin },
- { &nsGkAtoms::rightmargin },
- { &nsGkAtoms::bottommargin },
- { &nsGkAtoms::leftmargin },
{ nullptr },
};
@@ -292,37 +491,6 @@ HTMLBodyElement::IsEventAttributeName(nsIAtom *aName)
EventNameType_HTMLBodyOrFramesetOnly);
}
-nsresult
-HTMLBodyElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
- nsIContent* aBindingParent,
- bool aCompileEventHandlers)
-{
- nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
- aBindingParent,
- aCompileEventHandlers);
- NS_ENSURE_SUCCESS(rv, rv);
- return mAttrsAndChildren.ForceMapped(this, OwnerDoc());
-}
-
-nsresult
-HTMLBodyElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
- const nsAttrValue* aValue,
- const nsAttrValue* aOldValue, bool aNotify)
-{
- nsresult rv = nsGenericHTMLElement::AfterSetAttr(aNameSpaceID,
- aName, aValue, aOldValue,
- aNotify);
- NS_ENSURE_SUCCESS(rv, rv);
- // if the last mapped attribute was removed, don't clear the
- // nsMappedAttributes, our style can still depend on the containing frame element
- if (!aValue && IsAttributeMapped(aName)) {
- nsresult rv = mAttrsAndChildren.ForceMapped(this, OwnerDoc());
- NS_ENSURE_SUCCESS(rv, rv);
- }
-
- return NS_OK;
-}
-
#define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
// nsGenericHTMLElement::GetOnError returns
// already_AddRefed<EventHandlerNonNull> while other getters return
diff --git a/dom/html/HTMLBodyElement.h b/dom/html/HTMLBodyElement.h
index c637731a02..858bc691a9 100644
--- a/dom/html/HTMLBodyElement.h
+++ b/dom/html/HTMLBodyElement.h
@@ -14,6 +14,28 @@ namespace mozilla {
namespace dom {
class OnBeforeUnloadEventHandlerNonNull;
+class HTMLBodyElement;
+
+class BodyRule: public nsIStyleRule
+{
+ virtual ~BodyRule();
+
+public:
+ explicit BodyRule(HTMLBodyElement* aPart);
+
+ NS_DECL_ISUPPORTS
+
+ // nsIStyleRule interface
+ virtual void MapRuleInfoInto(nsRuleData* aRuleData) override;
+ virtual bool MightMapInheritedStyleData() override;
+ virtual bool GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty,
+ nsCSSValue* aValue) override;
+#ifdef DEBUG
+ virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
+#endif
+
+ HTMLBodyElement* mPart; // not ref-counted, cleared by content
+};
class HTMLBodyElement final : public nsGenericHTMLElement,
public nsIDOMHTMLBodyElement
@@ -102,29 +124,23 @@ public:
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult) override;
+ virtual void UnbindFromTree(bool aDeep = true,
+ bool aNullParent = true) override;
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
+ NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
virtual already_AddRefed<nsIEditor> GetAssociatedEditor() override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
virtual bool IsEventAttributeName(nsIAtom* aName) override;
- virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
- nsIContent* aBindingParent,
- bool aCompileEventHandlers) override;
- /**
- * Called when an attribute has just been changed
- */
- virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
- const nsAttrValue* aValue,
- const nsAttrValue* aOldValue,
- bool aNotify) override;
-
protected:
virtual ~HTMLBodyElement();
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
+ RefPtr<BodyRule> mContentStyleRule;
+
private:
static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData);
diff --git a/dom/html/HTMLTableCellElement.cpp b/dom/html/HTMLTableCellElement.cpp
index 2c795d2d49..41e202e8a5 100644
--- a/dom/html/HTMLTableCellElement.cpp
+++ b/dom/html/HTMLTableCellElement.cpp
@@ -106,7 +106,9 @@ HTMLTableCellElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
nsresult rv = nsGenericHTMLElement::WalkContentStyleRules(aRuleWalker);
NS_ENSURE_SUCCESS(rv, rv);
- if (nsMappedAttributes* tableInheritedAttributes = GetMappedAttributesInheritedFromTable()) {
+ if (HTMLTableElement* table = GetTable()) {
+ nsMappedAttributes* tableInheritedAttributes =
+ table->GetAttributesMappedForCell();
if (tableInheritedAttributes) {
aRuleWalker->Forward(tableInheritedAttributes);
}
@@ -114,16 +116,6 @@ HTMLTableCellElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
return NS_OK;
}
-nsMappedAttributes*
-HTMLTableCellElement::GetMappedAttributesInheritedFromTable() const
-{
- if (HTMLTableElement* table = GetTable()) {
- return table->GetAttributesMappedForCell();
- }
-
- return nullptr;
-}
-
NS_IMETHODIMP
HTMLTableCellElement::SetAbbr(const nsAString& aAbbr)
{
diff --git a/dom/html/HTMLTableCellElement.h b/dom/html/HTMLTableCellElement.h
index 10af61fc25..59634840e8 100644
--- a/dom/html/HTMLTableCellElement.h
+++ b/dom/html/HTMLTableCellElement.h
@@ -147,8 +147,6 @@ public:
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
- // Get mapped attributes of ancestor table, if any
- nsMappedAttributes* GetMappedAttributesInheritedFromTable() const;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp
index c33d8de772..a2a6937432 100644
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -321,7 +321,7 @@ TableRowsCollection::ParentDestroyed()
HTMLTableElement::HTMLTableElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
- mTableInheritedAttributes(nullptr)
+ mTableInheritedAttributes(TABLE_ATTRS_DIRTY)
{
SetHasWeirdParserInsertionMode();
}
@@ -911,15 +911,20 @@ MapInheritedTableAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsMappedAttributes*
HTMLTableElement::GetAttributesMappedForCell()
{
- return mTableInheritedAttributes;
+ if (mTableInheritedAttributes) {
+ if (mTableInheritedAttributes == TABLE_ATTRS_DIRTY)
+ BuildInheritedAttributes();
+ if (mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
+ return mTableInheritedAttributes;
+ }
+ return nullptr;
}
void
HTMLTableElement::BuildInheritedAttributes()
{
- NS_ASSERTION(!mTableInheritedAttributes,
+ NS_ASSERTION(mTableInheritedAttributes == TABLE_ATTRS_DIRTY,
"potential leak, plus waste of work");
- MOZ_ASSERT(NS_IsMainThread());
nsIDocument *document = GetComposedDoc();
nsHTMLStyleSheet* sheet = document ?
document->GetAttributeStyleSheet() : nullptr;
@@ -956,7 +961,10 @@ HTMLTableElement::BuildInheritedAttributes()
void
HTMLTableElement::ReleaseInheritedAttributes()
{
- NS_IF_RELEASE(mTableInheritedAttributes);
+ if (mTableInheritedAttributes &&
+ mTableInheritedAttributes != TABLE_ATTRS_DIRTY)
+ NS_RELEASE(mTableInheritedAttributes);
+ mTableInheritedAttributes = TABLE_ATTRS_DIRTY;
}
nsresult
@@ -965,12 +973,9 @@ HTMLTableElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
bool aCompileEventHandlers)
{
ReleaseInheritedAttributes();
- nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
- aBindingParent,
- aCompileEventHandlers);
- NS_ENSURE_SUCCESS(rv, rv);
- BuildInheritedAttributes();
- return NS_OK;
+ return nsGenericHTMLElement::BindToTree(aDocument, aParent,
+ aBindingParent,
+ aCompileEventHandlers);
}
void
diff --git a/dom/html/HTMLTableElement.h b/dom/html/HTMLTableElement.h
index 00faab0ec0..57bf8705e7 100644
--- a/dom/html/HTMLTableElement.h
+++ b/dom/html/HTMLTableElement.h
@@ -13,6 +13,8 @@
namespace mozilla {
namespace dom {
+#define TABLE_ATTRS_DIRTY ((nsMappedAttributes*)0x1)
+
class TableRowsCollection;
class HTMLTableElement final : public nsGenericHTMLElement
@@ -219,6 +221,8 @@ protected:
RefPtr<nsContentList> mTBodies;
RefPtr<TableRowsCollection> mRows;
+ // Sentinel value of TABLE_ATTRS_DIRTY indicates that this is dirty and needs
+ // to be recalculated.
nsMappedAttributes *mTableInheritedAttributes;
void BuildInheritedAttributes();
void ReleaseInheritedAttributes();
diff --git a/dom/html/reftests/reftest-stylo.list b/dom/html/reftests/reftest-stylo.list
deleted file mode 100644
index 570c073587..0000000000
--- a/dom/html/reftests/reftest-stylo.list
+++ /dev/null
@@ -1,73 +0,0 @@
-# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
-# autofocus attribute (we can't test with mochitests)
-# many stylo intermittents in files below
-# include autofocus/reftest-stylo.list
-# include toblob-todataurl/reftest-stylo.list
-
-skip-if(B2G) == 41464-1a.html 41464-1a.html
-skip-if(B2G) == 41464-1b.html 41464-1b.html
-== 52019-1.html 52019-1.html
-== 82711-1.html 82711-1.html
-== 82711-2.html 82711-2.html
-== 82711-1-ref.html 82711-1-ref.html
-random == 468263-1a.html 468263-1a.html
-random == 468263-1b.html 468263-1b.html
-random == 468263-1c.html 468263-1c.html
-random == 468263-1d.html 468263-1d.html
-random == 468263-2.html 468263-2.html
-random == 468263-2.html 468263-2.html
-== 484200-1.html 484200-1.html
-== 485377.html 485377.html
-== 557840.html 557840.html
-== 560059-video-dimensions.html 560059-video-dimensions.html
-== 573322-quirks.html 573322-quirks.html
-== 573322-no-quirks.html 573322-no-quirks.html
-# == 596455-1a.html 596455-1a.html
-== 596455-1b.html 596455-1b.html
-== 596455-2a.html 596455-2a.html
-== 596455-2b.html 596455-2b.html
-== 610935.html 610935.html
-== 649134-1.html 649134-1.html
-skip-if(Android||B2G) == 649134-2.html 649134-2.html
-
-== bug448564-1_malformed.html bug448564-1_malformed.html
-== bug448564-1_malformed.html bug448564-1_malformed.html
-
-== bug448564-4a.html bug448564-4a.html
-== bug502168-1_malformed.html bug502168-1_malformed.html
-
-random == responsive-image-load-shortcircuit.html responsive-image-load-shortcircuit.html
-
-# Test that image documents taken into account CSS properties like
-# image-orientation when determining the size of the image.
-# (Fuzzy necessary due to pixel-wise comparison of different JPEGs.
-# The vast majority of the fuzziness comes from Linux and WinXP.)
-skip == bug917595-iframe-1.html bug917595-iframe-1.html
-skip == bug917595-exif-rotated.jpg bug917595-exif-rotated.jpg
-# bug 1060869
-# Bug 1150490 disabling on Mulet as on B2G
-
-# Test support for SVG-as-image in <picture> elements.
-== bug1106522-1.html bug1106522-1.html
-== bug1106522-2.html bug1106522-2.html
-
-== href-attr-change-restyles.html href-attr-change-restyles.html
-== figure.html figure.html
-== pre-1.html pre-1.html
-== table-border-1.html table-border-1.html
-== table-border-2.html table-border-2.html
-== table-border-2.html table-border-2.html
-
-# Test imageset is using permissions.default.image
-pref(permissions.default.image,1) HTTP == bug1196784-with-srcset.html bug1196784-with-srcset.html
-pref(permissions.default.image,2) HTTP == bug1196784-with-srcset.html bug1196784-with-srcset.html
-
-# Test video with rotation information can be rotated.
-== bug1228601-video-rotation-90.html bug1228601-video-rotation-90.html
-
-# Test that dynamically setting body margin attributes updates style appropriately
-== body-topmargin-dynamic.html body-topmargin-dynamic.html
-
-# Test that dynamically removing a nonmargin mapped attribute does not
-# destroy margins inherited from the frame.
-== body-frame-margin-remove-other-pres-hint.html body-frame-margin-remove-other-pres-hint.html
diff --git a/dom/html/test/body-margin-test/child.html b/dom/html/test/body-margin-test/child.html
new file mode 100644
index 0000000000..751e1580bc
--- /dev/null
+++ b/dom/html/test/body-margin-test/child.html
@@ -0,0 +1,4 @@
+<HTML>
+<BODY BGCOLOR="#ffffff" TEXT="#000000">
+<A HREF="/internal-url-removed/" TARGET="_top"><IMG SRC="fruit.jpg" ALT="" BORDER=0 WIDTH="800" HEIGHT="600"></A>
+</BODY></HTML> \ No newline at end of file
diff --git a/dom/html/test/body-margin-test/fruit.jpg b/dom/html/test/body-margin-test/fruit.jpg
new file mode 100644
index 0000000000..d43db35e18
--- /dev/null
+++ b/dom/html/test/body-margin-test/fruit.jpg
Binary files differ
diff --git a/dom/html/test/body-margin-test/test-body.html b/dom/html/test/body-margin-test/test-body.html
new file mode 100644
index 0000000000..29f143313a
--- /dev/null
+++ b/dom/html/test/body-margin-test/test-body.html
@@ -0,0 +1,9 @@
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+ <HEAD>
+ </HEAD>
+<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#000099" TEXT="#000000" TOPMARGIN=0 BOTTOMMARGIN=0 LEFTMARGIN=0 RIGHTMARGIN=0 MARGINWIDTH=0 MARGINHEIGHT=0>
+<img src=fruit.jpg width="100%" height="100%">
+ </BODY>
+</HTML> \ No newline at end of file
diff --git a/dom/html/test/body-margin-test/test-frame.html b/dom/html/test/body-margin-test/test-frame.html
new file mode 100644
index 0000000000..27669ad82b
--- /dev/null
+++ b/dom/html/test/body-margin-test/test-frame.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+ <HEAD>
+ <TITLE>iframe now showing margin/padding in pale moon</TITLE>
+ </HEAD>
+
+<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#000099" TEXT="#000000" TOPMARGIN=0 BOTTOMMARGIN=0 LEFTMARGIN=0 RIGHTMARGIN=0 MARGINWIDTH=0 MARGINHEIGHT=0>
+
+ <IFRAME SRC=child.html MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=NO WIDTH=800 HEIGHT=600>
+ </BODY>
+</HTML>