зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1344398) for assertion failures at Element.cpp a=backout
Backed out changeset d0e5a5ba01b5 (bug 1344398) Backed out changeset d70f9de401d1 (bug 1344398) Backed out changeset 647d0bb3714d (bug 1344398) MozReview-Commit-ID: DTVWf28NcNb
This commit is contained in:
Родитель
b7eda53134
Коммит
8f6058b583
|
@ -1805,24 +1805,6 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
SetParentIsContent(false);
|
SetParentIsContent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
// If we can get access to the PresContext, then we sanity-check that
|
|
||||||
// we're not leaving behind a pointer to ourselves as the PresContext's
|
|
||||||
// cached provider of the viewport's scrollbar styles.
|
|
||||||
if (document) {
|
|
||||||
nsIPresShell* presShell = document->GetShell();
|
|
||||||
if (presShell) {
|
|
||||||
nsPresContext* presContext = presShell->GetPresContext();
|
|
||||||
if (presContext) {
|
|
||||||
MOZ_ASSERT(this !=
|
|
||||||
presContext->GetViewportScrollbarStylesOverrideNode(),
|
|
||||||
"Leaving behind a raw pointer to this node (as having "
|
|
||||||
"propagated scrollbar styles) - that's dangerous...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Ensure that CSS transitions don't continue on an element at a
|
// Ensure that CSS transitions don't continue on an element at a
|
||||||
// different place in the tree (even if reinserted before next
|
// different place in the tree (even if reinserted before next
|
||||||
// animation refresh).
|
// animation refresh).
|
||||||
|
|
|
@ -454,7 +454,7 @@ RestyleManager::ChangeHintToString(nsChangeHint aHint)
|
||||||
"NeutralChange", "InvalidateRenderingObservers",
|
"NeutralChange", "InvalidateRenderingObservers",
|
||||||
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
|
"ReflowChangesSizeOrPosition", "UpdateComputedBSize",
|
||||||
"UpdateUsesOpacity", "UpdateBackgroundPosition",
|
"UpdateUsesOpacity", "UpdateBackgroundPosition",
|
||||||
"AddOrRemoveTransform", "CSSOverflowChange",
|
"AddOrRemoveTransform"
|
||||||
};
|
};
|
||||||
static_assert(nsChangeHint_AllHints == (1 << ArrayLength(names)) - 1,
|
static_assert(nsChangeHint_AllHints == (1 << ArrayLength(names)) - 1,
|
||||||
"Name list doesn't match change hints.");
|
"Name list doesn't match change hints.");
|
||||||
|
@ -1348,62 +1348,6 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
||||||
FramePropertyTable* propTable = presContext->PropertyTable();
|
FramePropertyTable* propTable = presContext->PropertyTable();
|
||||||
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
|
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
|
||||||
|
|
||||||
// Handle nsChangeHint_CSSOverflowChange, by either updating the
|
|
||||||
// scrollbars on the viewport, or upgrading the change hint to frame-reconstruct.
|
|
||||||
for (nsStyleChangeData& data : aChangeList) {
|
|
||||||
if (data.mHint & nsChangeHint_CSSOverflowChange) {
|
|
||||||
data.mHint &= ~nsChangeHint_CSSOverflowChange;
|
|
||||||
bool doReconstruct = true; // assume the worst
|
|
||||||
|
|
||||||
// Only bother with this if we're html/body, since:
|
|
||||||
// (a) It'd be *expensive* to reframe these particular nodes. They're
|
|
||||||
// at the root, so reframing would mean rebuilding the world.
|
|
||||||
// (b) It's often *unnecessary* to reframe for "overflow" changes on
|
|
||||||
// these particular nodes. In general, the only reason we reframe
|
|
||||||
// for "overflow" changes is so we can construct (or destroy) a
|
|
||||||
// scrollframe & scrollbars -- and the html/body nodes often don't
|
|
||||||
// need their own scrollframe/scrollbars because they coopt the ones
|
|
||||||
// on the viewport (which always exist). So depending on whether
|
|
||||||
// that's happening, we can skip the reframe for these nodes.
|
|
||||||
if (data.mContent->IsAnyOfHTMLElements(nsGkAtoms::body,
|
|
||||||
nsGkAtoms::html)) {
|
|
||||||
// If the restyled element provided/provides the scrollbar styles for
|
|
||||||
// the viewport before and/or after this restyle, AND it's not coopting
|
|
||||||
// that responsibility from some other element (which would need
|
|
||||||
// reconstruction to make its own scrollframe now), THEN: we don't need
|
|
||||||
// to reconstruct - we can just reflow, because no scrollframe is being
|
|
||||||
// added/removed.
|
|
||||||
nsIContent* prevOverrideNode =
|
|
||||||
presContext->GetViewportScrollbarStylesOverrideNode();
|
|
||||||
nsIContent* newOverrideNode =
|
|
||||||
presContext->UpdateViewportScrollbarStylesOverride();
|
|
||||||
|
|
||||||
if (data.mContent == prevOverrideNode ||
|
|
||||||
data.mContent == newOverrideNode) {
|
|
||||||
// If we get here, the restyled element provided the scrollbar styles
|
|
||||||
// for viewport before this restyle, OR it will provide them after.
|
|
||||||
if (!prevOverrideNode || !newOverrideNode ||
|
|
||||||
prevOverrideNode == newOverrideNode) {
|
|
||||||
// If we get here, the restyled element is NOT replacing (or being
|
|
||||||
// replaced by) some other element as the viewport's
|
|
||||||
// scrollbar-styles provider. (If it were, we'd potentially need to
|
|
||||||
// reframe to create a dedicated scrollframe for whichever element
|
|
||||||
// is being booted from providing viewport scrollbar styles.)
|
|
||||||
//
|
|
||||||
// Under these conditions, we're OK to assume that this "overflow"
|
|
||||||
// change only impacts the root viewport's scrollframe, which
|
|
||||||
// already exists, so we can simply reflow instead of reframing.
|
|
||||||
data.mHint |= nsChangeHint_AllReflowHints;
|
|
||||||
doReconstruct = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doReconstruct) {
|
|
||||||
data.mHint |= nsChangeHint_ReconstructFrame;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure to not rebuild quote or counter lists while we're
|
// Make sure to not rebuild quote or counter lists while we're
|
||||||
// processing restyles
|
// processing restyles
|
||||||
frameConstructor->BeginUpdate();
|
frameConstructor->BeginUpdate();
|
||||||
|
|
|
@ -8488,19 +8488,11 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
|
||||||
ServoRestyleManager::ClearServoDataFromSubtree(aChild->AsElement());
|
ServoRestyleManager::ClearServoDataFromSubtree(aChild->AsElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPresContext* presContext = mPresShell->GetPresContext();
|
|
||||||
MOZ_ASSERT(presContext, "Our presShell should have a valid presContext");
|
|
||||||
|
|
||||||
if (aChild->IsHTMLElement(nsGkAtoms::body) ||
|
if (aChild->IsHTMLElement(nsGkAtoms::body) ||
|
||||||
(!aContainer && aChild->IsElement())) {
|
(!aContainer && aChild->IsElement())) {
|
||||||
// We might be removing the element that we propagated viewport scrollbar
|
// This might be the element we propagated viewport scrollbar
|
||||||
// styles from. Recompute those. (This clause covers two of the three
|
// styles from. Recompute those.
|
||||||
// possible scrollbar-propagation sources: the <body> [as aChild or a
|
mPresShell->GetPresContext()->UpdateViewportScrollbarStylesOverride();
|
||||||
// descendant] and the root node. The other possible scrollbar-propagation
|
|
||||||
// source is a fullscreen element, and we have code elsewhere to update
|
|
||||||
// scrollbars after fullscreen elements are removed -- specifically, it's
|
|
||||||
// part of the fullscreen cleanup code called by Element::UnbindFromTree.)
|
|
||||||
presContext->UpdateViewportScrollbarStylesOverride();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXXldb Do we need to re-resolve style to handle the CSS2 + combinator and
|
// XXXldb Do we need to re-resolve style to handle the CSS2 + combinator and
|
||||||
|
@ -8562,6 +8554,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
|
||||||
ClearDisplayContentsIn(aChild, aContainer);
|
ClearDisplayContentsIn(aChild, aContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsPresContext* presContext = mPresShell->GetPresContext();
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
|
if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling,
|
||||||
childFrame, CONTENT_REMOVED)) {
|
childFrame, CONTENT_REMOVED)) {
|
||||||
|
|
|
@ -222,16 +222,6 @@ enum nsChangeHint : uint32_t {
|
||||||
*/
|
*/
|
||||||
nsChangeHint_AddOrRemoveTransform = 1 << 27,
|
nsChangeHint_AddOrRemoveTransform = 1 << 27,
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that the overflow-x and/or overflow-y property changed.
|
|
||||||
*
|
|
||||||
* In most cases, this is equivalent to nsChangeHint_ReconstructFrame. But
|
|
||||||
* in some special cases where the change is really targeting the viewport's
|
|
||||||
* scrollframe, this is instead equivalent to nsChangeHint_AllReflowHints
|
|
||||||
* (because the viewport always has an associated scrollframe).
|
|
||||||
*/
|
|
||||||
nsChangeHint_CSSOverflowChange = 1 << 28,
|
|
||||||
|
|
||||||
// IMPORTANT NOTE: When adding a new hint, you will need to add it to
|
// IMPORTANT NOTE: When adding a new hint, you will need to add it to
|
||||||
// one of:
|
// one of:
|
||||||
//
|
//
|
||||||
|
@ -247,7 +237,7 @@ enum nsChangeHint : uint32_t {
|
||||||
/**
|
/**
|
||||||
* Dummy hint value for all hints. It exists for compile time check.
|
* Dummy hint value for all hints. It exists for compile time check.
|
||||||
*/
|
*/
|
||||||
nsChangeHint_AllHints = (1 << 29) - 1,
|
nsChangeHint_AllHints = (1 << 28) - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Redefine these operators to return nothing. This will catch any use
|
// Redefine these operators to return nothing. This will catch any use
|
||||||
|
@ -336,7 +326,6 @@ inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight)
|
||||||
#define nsChangeHint_Hints_NeverHandledForDescendants ( \
|
#define nsChangeHint_Hints_NeverHandledForDescendants ( \
|
||||||
nsChangeHint_BorderStyleNoneChange | \
|
nsChangeHint_BorderStyleNoneChange | \
|
||||||
nsChangeHint_ChildrenOnlyTransform | \
|
nsChangeHint_ChildrenOnlyTransform | \
|
||||||
nsChangeHint_CSSOverflowChange | \
|
|
||||||
nsChangeHint_InvalidateRenderingObservers | \
|
nsChangeHint_InvalidateRenderingObservers | \
|
||||||
nsChangeHint_RecomputePosition | \
|
nsChangeHint_RecomputePosition | \
|
||||||
nsChangeHint_UpdateBackgroundPosition | \
|
nsChangeHint_UpdateBackgroundPosition | \
|
||||||
|
|
|
@ -231,7 +231,6 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType)
|
||||||
mFocusBackgroundColor(mBackgroundColor),
|
mFocusBackgroundColor(mBackgroundColor),
|
||||||
mFocusTextColor(mDefaultColor),
|
mFocusTextColor(mDefaultColor),
|
||||||
mBodyTextColor(mDefaultColor),
|
mBodyTextColor(mDefaultColor),
|
||||||
mViewportScrollbarOverrideNode(nullptr),
|
|
||||||
mViewportStyleScrollbar(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
|
mViewportStyleScrollbar(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
|
||||||
mFocusRingWidth(1),
|
mFocusRingWidth(1),
|
||||||
mExistThrottledUpdates(false),
|
mExistThrottledUpdates(false),
|
||||||
|
@ -1497,10 +1496,10 @@ nsPresContext::UpdateViewportScrollbarStylesOverride()
|
||||||
// Start off with our default styles, and then update them as needed.
|
// Start off with our default styles, and then update them as needed.
|
||||||
mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO,
|
mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO,
|
||||||
NS_STYLE_OVERFLOW_AUTO);
|
NS_STYLE_OVERFLOW_AUTO);
|
||||||
mViewportScrollbarOverrideNode = nullptr;
|
nsIContent* propagatedFrom = nullptr;
|
||||||
// Don't propagate the scrollbar state in printing or print preview.
|
// Don't propagate the scrollbar state in printing or print preview.
|
||||||
if (!IsPaginated()) {
|
if (!IsPaginated()) {
|
||||||
mViewportScrollbarOverrideNode =
|
propagatedFrom =
|
||||||
GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar);
|
GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1512,12 +1511,13 @@ nsPresContext::UpdateViewportScrollbarStylesOverride()
|
||||||
// the styles are from, so that the state of those elements is not
|
// the styles are from, so that the state of those elements is not
|
||||||
// affected across fullscreen change.
|
// affected across fullscreen change.
|
||||||
if (fullscreenElement != document->GetRootElement() &&
|
if (fullscreenElement != document->GetRootElement() &&
|
||||||
fullscreenElement != mViewportScrollbarOverrideNode) {
|
fullscreenElement != propagatedFrom) {
|
||||||
mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
|
mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
|
||||||
NS_STYLE_OVERFLOW_HIDDEN);
|
NS_STYLE_OVERFLOW_HIDDEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mViewportScrollbarOverrideNode;
|
|
||||||
|
return propagatedFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -737,18 +737,7 @@ public:
|
||||||
* it was propagated from.
|
* it was propagated from.
|
||||||
*/
|
*/
|
||||||
nsIContent* UpdateViewportScrollbarStylesOverride();
|
nsIContent* UpdateViewportScrollbarStylesOverride();
|
||||||
|
const ScrollbarStyles& GetViewportScrollbarStylesOverride()
|
||||||
/**
|
|
||||||
* Returns the cached result from the last call to
|
|
||||||
* UpdateViewportScrollbarStylesOverride() -- i.e. return the node
|
|
||||||
* whose scrollbar styles we have propagated to the viewport (or nullptr if
|
|
||||||
* there is no such node).
|
|
||||||
*/
|
|
||||||
nsIContent* GetViewportScrollbarStylesOverrideNode() const {
|
|
||||||
return mViewportScrollbarOverrideNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ScrollbarStyles& GetViewportScrollbarStylesOverride() const
|
|
||||||
{
|
{
|
||||||
return mViewportStyleScrollbar;
|
return mViewportStyleScrollbar;
|
||||||
}
|
}
|
||||||
|
@ -1396,16 +1385,7 @@ protected:
|
||||||
|
|
||||||
nscolor mBodyTextColor;
|
nscolor mBodyTextColor;
|
||||||
|
|
||||||
// This is a non-owning pointer. May be null. If non-null, it's guaranteed
|
|
||||||
// to be pointing to a node that's still alive, because we'll reset it in
|
|
||||||
// UpdateViewportScrollbarStylesOverride() as part of the cleanup code
|
|
||||||
// when this node is removed from the document. (For <body> and the root node,
|
|
||||||
// this call happens in nsCSSFrameConstructor::ContentRemoved(). For
|
|
||||||
// fullscreen elements, it happens in the fullscreen-specific cleanup
|
|
||||||
// invoked by Element::UnbindFromTree().)
|
|
||||||
nsIContent* MOZ_NON_OWNING_REF mViewportScrollbarOverrideNode;
|
|
||||||
ScrollbarStyles mViewportStyleScrollbar;
|
ScrollbarStyles mViewportStyleScrollbar;
|
||||||
|
|
||||||
uint8_t mFocusRingWidth;
|
uint8_t mFocusRingWidth;
|
||||||
|
|
||||||
bool mExistThrottledUpdates;
|
bool mExistThrottledUpdates;
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Reference case with body and html *independently* scrollable.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with body and html *independently* scrollable,
|
|
||||||
with body's "overflow" set dynamically.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.body.style.overflow = "scroll";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,23 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with body and html *independently* scrollable,
|
|
||||||
with html's "overflow" set dynamically.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.documentElement.style.overflow = "scroll";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,19 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with body and html *independently* scrollable,
|
|
||||||
with both html & body's "overflow" set dynamically.
|
|
||||||
</title>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.documentElement.style.overflow = "scroll";
|
|
||||||
document.body.style.overflow = "scroll";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Reference case with the root viewport scrollable, via styles on html node.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with only one of [html,body] being scrollable,
|
|
||||||
after body's "overflow" is reset dynamically.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.body.style.overflow = "visible";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with only one of [html,body] being scrollable,
|
|
||||||
after html's "overflow" is reset dynamically.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.documentElement.style.overflow = "visible";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,24 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with only one of [html,body] being scrollable,
|
|
||||||
with their "overflow" styles being dynamically swapped.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.documentElement.style.overflow = "visible";
|
|
||||||
document.body.style.overflow = "scroll";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,24 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html class="reftest-wait">
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with only one of [html,body] being scrollable,
|
|
||||||
with their "overflow" styles being dynamically swapped.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function doTest() {
|
|
||||||
document.documentElement.style.overflow = "scroll";
|
|
||||||
document.body.style.overflow = "visible";
|
|
||||||
document.documentElement.removeAttribute("class");
|
|
||||||
}
|
|
||||||
window.addEventListener("MozReftestInvalidate", doTest);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,15 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>
|
|
||||||
Testcase with the root viewport scrollable, via styles on body node.
|
|
||||||
</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -86,13 +86,3 @@ fuzzy-if(asyncPan&&!layersGPUAccelerated,102,2420) == frame-scrolling-attr-2.htm
|
||||||
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
|
== fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
|
||||||
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
|
== fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999
|
||||||
!= fractional-scroll-area-invalidation.html about:blank
|
!= fractional-scroll-area-invalidation.html about:blank
|
||||||
|
|
||||||
# Tests for "overflow" styles that may be propagated to the viewport:
|
|
||||||
== propagated-overflow-style-1a.html propagated-overflow-style-1-ref.html
|
|
||||||
== propagated-overflow-style-1b.html propagated-overflow-style-1-ref.html
|
|
||||||
== propagated-overflow-style-1c.html propagated-overflow-style-1-ref.html
|
|
||||||
== propagated-overflow-style-2a.html propagated-overflow-style-2-ref.html
|
|
||||||
== propagated-overflow-style-2b.html propagated-overflow-style-2-ref.html
|
|
||||||
== propagated-overflow-style-2c.html propagated-overflow-style-2-ref.html
|
|
||||||
== propagated-overflow-style-2d.html propagated-overflow-style-2-ref.html
|
|
||||||
== propagated-overflow-style-2e.html propagated-overflow-style-2-ref.html
|
|
||||||
|
|
|
@ -3488,6 +3488,8 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
|
||||||
|| mDisplay != aNewData.mDisplay
|
|| mDisplay != aNewData.mDisplay
|
||||||
|| mContain != aNewData.mContain
|
|| mContain != aNewData.mContain
|
||||||
|| (mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None)
|
|| (mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None)
|
||||||
|
|| mOverflowX != aNewData.mOverflowX
|
||||||
|
|| mOverflowY != aNewData.mOverflowY
|
||||||
|| mScrollBehavior != aNewData.mScrollBehavior
|
|| mScrollBehavior != aNewData.mScrollBehavior
|
||||||
|| mScrollSnapTypeX != aNewData.mScrollSnapTypeX
|
|| mScrollSnapTypeX != aNewData.mScrollSnapTypeX
|
||||||
|| mScrollSnapTypeY != aNewData.mScrollSnapTypeY
|
|| mScrollSnapTypeY != aNewData.mScrollSnapTypeY
|
||||||
|
@ -3499,11 +3501,6 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const
|
||||||
hint |= nsChangeHint_ReconstructFrame;
|
hint |= nsChangeHint_ReconstructFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mOverflowX != aNewData.mOverflowX
|
|
||||||
|| mOverflowY != aNewData.mOverflowY) {
|
|
||||||
hint |= nsChangeHint_CSSOverflowChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY,
|
/* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY,
|
||||||
* mScrollSnapPointsX, mScrollSnapPointsY, or mScrollSnapDestination are
|
* mScrollSnapPointsX, mScrollSnapPointsY, or mScrollSnapDestination are
|
||||||
* changed, nsChangeHint_NeutralChange is not sufficient to enter
|
* changed, nsChangeHint_NeutralChange is not sufficient to enter
|
||||||
|
|
|
@ -95,90 +95,6 @@ const gTestcases = [
|
||||||
expectReflow: true,
|
expectReflow: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// * Changing 'overflow' on <body> should cause reflow,
|
|
||||||
// but not frame reconstruction
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
/* beforeStyle: implicitly 'overflow:visible' */
|
|
||||||
afterStyle: "overflow: hidden",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
/* beforeStyle: implicitly 'overflow:visible' */
|
|
||||||
afterStyle: "overflow: scroll",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
beforeStyle: "overflow: hidden",
|
|
||||||
afterStyle: "overflow: auto",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
beforeStyle: "overflow: hidden",
|
|
||||||
afterStyle: "overflow: scroll",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
beforeStyle: "overflow: hidden",
|
|
||||||
afterStyle: "overflow: visible",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
beforeStyle: "overflow: auto",
|
|
||||||
afterStyle: "overflow: hidden",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.body,
|
|
||||||
beforeStyle: "overflow: visible",
|
|
||||||
afterStyle: "overflow: hidden",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
// * Changing 'overflow' on <html> should cause reflow,
|
|
||||||
// but not frame reconstruction
|
|
||||||
{
|
|
||||||
elem: document.documentElement,
|
|
||||||
/* beforeStyle: implicitly 'overflow:visible' */
|
|
||||||
afterStyle: "overflow: auto",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
elem: document.documentElement,
|
|
||||||
beforeStyle: "overflow: visible",
|
|
||||||
afterStyle: "overflow: auto",
|
|
||||||
expectConstruction: false,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
// * Setting 'overflow' on arbitrary node should cause reflow as well as
|
|
||||||
// frame reconstruction
|
|
||||||
{
|
|
||||||
/* beforeStyle: implicitly 'overflow:visible' */
|
|
||||||
afterStyle: "overflow: auto",
|
|
||||||
expectConstruction: true,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
beforeStyle: "overflow: auto",
|
|
||||||
afterStyle: "overflow: visible",
|
|
||||||
expectConstruction: true,
|
|
||||||
expectReflow: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
// * Changing 'display' should cause frame construction and reflow.
|
// * Changing 'display' should cause frame construction and reflow.
|
||||||
{
|
{
|
||||||
beforeStyle: "display: inline",
|
beforeStyle: "display: inline",
|
||||||
|
@ -219,35 +135,23 @@ function runOneTest(aTestcase)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out which element we'll be tweaking (defaulting to gElem)
|
|
||||||
let elem = aTestcase.elem ?
|
|
||||||
aTestcase.elem : gElem;
|
|
||||||
|
|
||||||
// Verify that 'style' attribute is unset (avoid causing ourselves trouble):
|
|
||||||
if (elem.hasAttribute("style")) {
|
|
||||||
ok(false,
|
|
||||||
"test element has 'style' attribute already set! We're going to stomp " +
|
|
||||||
"on whatever's there when we clean up...");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the "before" style, and compose the first part of the message
|
// Set the "before" style, and compose the first part of the message
|
||||||
// to be used in our "is"/"isnot" invocations:
|
// to be used in our "is"/"isnot" invocations:
|
||||||
let msgPrefix = "Changing style ";
|
let msgPrefix = "Changing style ";
|
||||||
if (aTestcase.beforeStyle) {
|
if (aTestcase.beforeStyle) {
|
||||||
elem.setAttribute("style", aTestcase.beforeStyle);
|
gElem.setAttribute("style", aTestcase.beforeStyle);
|
||||||
msgPrefix += "from '" + aTestcase.beforeStyle + "' ";
|
msgPrefix += "from '" + aTestcase.beforeStyle + "' ";
|
||||||
}
|
}
|
||||||
msgPrefix += "to '" + aTestcase.afterStyle + "' ";
|
msgPrefix += "to '" + aTestcase.afterStyle + "' ";
|
||||||
msgPrefix += "on " + elem.nodeName + " ";
|
|
||||||
|
|
||||||
// Establish initial counts:
|
// Establish initial counts:
|
||||||
let unusedVal = elem.offsetHeight; // flush layout
|
let unusedVal = gElem.offsetHeight; // flush layout
|
||||||
let origFramesConstructed = gUtils.framesConstructed;
|
let origFramesConstructed = gUtils.framesConstructed;
|
||||||
let origFramesReflowed = gUtils.framesReflowed;
|
let origFramesReflowed = gUtils.framesReflowed;
|
||||||
|
|
||||||
// Make the change and flush:
|
// Make the change and flush:
|
||||||
elem.setAttribute("style", aTestcase.afterStyle);
|
gElem.setAttribute("style", aTestcase.afterStyle);
|
||||||
unusedVal = elem.offsetHeight; // flush layout
|
unusedVal = gElem.offsetHeight; // flush layout
|
||||||
|
|
||||||
// Make our is/isnot assertions about whether things should have changed:
|
// Make our is/isnot assertions about whether things should have changed:
|
||||||
checkFinalCount(gUtils.framesConstructed, origFramesConstructed,
|
checkFinalCount(gUtils.framesConstructed, origFramesConstructed,
|
||||||
|
@ -258,7 +162,7 @@ function runOneTest(aTestcase)
|
||||||
"reflow");
|
"reflow");
|
||||||
|
|
||||||
// Clean up!
|
// Clean up!
|
||||||
elem.removeAttribute("style");
|
gElem.removeAttribute("style");
|
||||||
}
|
}
|
||||||
|
|
||||||
gTestcases.forEach(runOneTest);
|
gTestcases.forEach(runOneTest);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче