зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1340723 part 3. Fix stylo to properly update styles on the anonymous blocks we create in a block-inside-inline situation when the style of the inline changes. r=emilio
MozReview-Commit-ID: JYz6g1ZJInT --HG-- extra : rebase_source : 356785e1de38745c9ca23a04ce58a1d53dce692b
This commit is contained in:
Родитель
e8c584ebb8
Коммит
799bc86f7c
|
@ -235,6 +235,9 @@ ServoRestyleManager::RecreateStyleContexts(Element* aElement,
|
|||
// XXX This could not always work as expected: there are kinds of content
|
||||
// with the first split and the last sharing style, but others not. We
|
||||
// should handle those properly.
|
||||
// XXXbz I think the UpdateStyleOfOwnedAnonBoxes call below handles _that_
|
||||
// right, but not other cases where we happen to have different styles on
|
||||
// different continuations... (e.g. first-line).
|
||||
for (nsIFrame* f = styleFrame; f;
|
||||
f = GetNextContinuationWithSameStyle(f, oldStyleContext)) {
|
||||
f->SetStyleContext(newContext);
|
||||
|
|
|
@ -12129,6 +12129,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
|
|||
|
||||
aFrameItems.AddChild(newFrame);
|
||||
|
||||
newFrame->AddStateBits(NS_FRAME_OWNS_ANON_BOXES);
|
||||
CreateIBSiblings(aState, newFrame, positioned, childItems, aFrameItems);
|
||||
|
||||
return newFrame;
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#include "nsDisplayList.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "SVGTextFrame.h"
|
||||
#include "nsStyleChangeList.h"
|
||||
#include "mozilla/StyleSetHandle.h"
|
||||
#include "mozilla/StyleSetHandleInlines.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef NOISY_PUSHING
|
||||
|
@ -1021,6 +1023,65 @@ nsInlineFrame::AccessibleType()
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsInlineFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
|
||||
nsStyleChangeList& aChangeList,
|
||||
nsChangeHint aHintForThisFrame)
|
||||
{
|
||||
MOZ_ASSERT(GetStateBits() & NS_FRAME_OWNS_ANON_BOXES,
|
||||
"Why did we get called?");
|
||||
MOZ_ASSERT(GetStateBits() & NS_FRAME_PART_OF_IBSPLIT,
|
||||
"Why did we have the NS_FRAME_OWNS_ANON_BOXES bit set?");
|
||||
// Note: this assert _looks_ expensive, but it's cheap in all the cases when
|
||||
// it passes!
|
||||
MOZ_ASSERT(nsLayoutUtils::FirstContinuationOrIBSplitSibling(this) == this,
|
||||
"Only the primary frame of the inline in a block-inside-inline "
|
||||
"split should have NS_FRAME_OWNS_ANON_BOXES");
|
||||
MOZ_ASSERT(mContent->GetPrimaryFrame() == this,
|
||||
"We should be the primary frame for our element");
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
// Get the FramePropertyTable up front, since we are likely to need it
|
||||
// multiple times. The other option would be to just call
|
||||
// nsIFrame::Properties() every time we need to do a lookup, but that does
|
||||
// more pointer-chasing.
|
||||
FramePropertyTable* propTable = presContext->PropertyTable();
|
||||
nsIFrame* blockFrame = propTable->Get(this, nsIFrame::IBSplitSibling());
|
||||
MOZ_ASSERT(blockFrame, "Why did we have an IB split?");
|
||||
|
||||
nsIAtom* pseudo = blockFrame->StyleContext()->GetPseudo();
|
||||
MOZ_ASSERT(pseudo == nsCSSAnonBoxes::mozAnonymousBlock ||
|
||||
pseudo == nsCSSAnonBoxes::mozAnonymousPositionedBlock,
|
||||
"Unexpected kind of style context");
|
||||
|
||||
// The anonymous block's style inherits from ours, and we already have our new
|
||||
// style context.
|
||||
RefPtr<nsStyleContext> newContext =
|
||||
aStyleSet.ResolveAnonymousBoxStyle(pseudo, StyleContext());
|
||||
|
||||
// We're guaranteed that newContext only differs from the old style context on
|
||||
// the block in things they might inherit from us. And changehint processing
|
||||
// guarantees walking the continuation and ib-sibling chains, so our existing
|
||||
// changehint beign in aChangeList is good enough. So we don't need to touch
|
||||
// aChangeList at all here.
|
||||
|
||||
while (blockFrame) {
|
||||
MOZ_ASSERT(!blockFrame->GetPrevContinuation(),
|
||||
"Must be first continuation");
|
||||
// We _could_ just walk along using GetNextContinuationWithSameStyle here,
|
||||
// but it would involve going back to the first continuation every so often,
|
||||
// which is a bit silly when we can just keep track of our first
|
||||
// continuations.
|
||||
for (nsIFrame* cont = blockFrame; cont; cont = cont->GetNextContinuation()) {
|
||||
cont->SetStyleContext(newContext);
|
||||
}
|
||||
|
||||
nsIFrame* nextInline = propTable->Get(blockFrame, nsIFrame::IBSplitSibling());
|
||||
MOZ_ASSERT(nextInline, "There is always a trailing inline in an IB split");
|
||||
blockFrame = propTable->Get(nextInline, nsIFrame::IBSplitSibling());
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// nsLineFrame implementation
|
||||
|
|
|
@ -116,6 +116,13 @@ public:
|
|||
: (!GetNextInFlow());
|
||||
}
|
||||
|
||||
// Update the style on the block wrappers around our non-inline-outside kids.
|
||||
// This will only be called when such wrappers in fact exist.
|
||||
virtual void DoUpdateStyleOfOwnedAnonBoxes(
|
||||
mozilla::ServoStyleSet& aStyleSet,
|
||||
nsStyleChangeList& aChangeList,
|
||||
nsChangeHint aHintForThisFrame) override;
|
||||
|
||||
protected:
|
||||
// Additional reflow state used during our reflow methods
|
||||
struct InlineReflowInput {
|
||||
|
|
|
@ -84,3 +84,5 @@ fails == float-inside-inline-between-blocks-1.html float-inside-inline-between-b
|
|||
== append-to-empty-trailing-inline-1.html append-to-empty-trailing-inline-1.html
|
||||
== append-to-nested-split-inline-1.html append-to-nested-split-inline-1.html
|
||||
== append-to-nested-split-inline-1-ref.html append-to-nested-split-inline-1-ref.html
|
||||
== relpos-inline-1a.html relpos-inline-1a.html
|
||||
== relpos-inline-1b.html relpos-inline-1b.html
|
||||
|
|
|
@ -83,3 +83,5 @@
|
|||
== append-to-empty-trailing-inline-1.html append-to-empty-trailing-inline-1-ref.html
|
||||
== append-to-nested-split-inline-1.html append-to-nested-split-inline-1-ref.html
|
||||
== append-to-nested-split-inline-1-ref.html append-to-nested-split-inline-1-noib-ref.html
|
||||
== relpos-inline-1a.html relpos-inline-1-ref.html
|
||||
== relpos-inline-1b.html relpos-inline-1-ref.html
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
span, div { position: relative; left: 200px }
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span>All text should be offset 200px.</span>
|
||||
<div>Some more text</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS 2.1 Test Suite: handling of blocks inside inlines</title>
|
||||
<link rel="author" title="Boris Zbarsky" href="mailto:bzbarsky@mit.edu" />
|
||||
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level"/>
|
||||
<meta name="flags" content="" />
|
||||
<style>
|
||||
span { position: relative; left: 200px }
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span style="position: relative; left: 200px">
|
||||
All text should be offset 200px.
|
||||
<div>Some more text</div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS 2.1 Test Suite: handling of blocks inside inlines</title>
|
||||
<link rel="author" title="Boris Zbarsky" href="mailto:bzbarsky@mit.edu" />
|
||||
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#anonymous-block-level"/>
|
||||
<meta name="flags" content="" />
|
||||
<style>
|
||||
span { position: relative }
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span style="position: relative; left: 100px">
|
||||
All text should be offset 200px.
|
||||
<div>Some more text</div>
|
||||
</span>
|
||||
<script>
|
||||
onload = function() {
|
||||
var s = document.querySelector("span");
|
||||
s.offsetWidth; // flush layout
|
||||
s.style.left = "200px";
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче