зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1422653: Compute whether XBL is involved in ChildIterator lazily. r=mats
The only thing that cares about it is the frame constructor, it's a shame that everyone else (in particular, the style system) needs to pay this extra walk over the DOM. MozReview-Commit-ID: F7S5zx9KMlp
This commit is contained in:
Родитель
bd1d30c860
Коммит
c3209ce172
|
@ -124,6 +124,7 @@ void
|
||||||
FlattenedChildIterator::Init(bool aIgnoreXBL)
|
FlattenedChildIterator::Init(bool aIgnoreXBL)
|
||||||
{
|
{
|
||||||
if (aIgnoreXBL) {
|
if (aIgnoreXBL) {
|
||||||
|
mXBLInvolved = Some(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +133,7 @@ FlattenedChildIterator::Init(bool aIgnoreXBL)
|
||||||
if (mParent->IsElement()) {
|
if (mParent->IsElement()) {
|
||||||
if (ShadowRoot* shadow = mParent->AsElement()->GetShadowRoot()) {
|
if (ShadowRoot* shadow = mParent->AsElement()->GetShadowRoot()) {
|
||||||
mParent = shadow;
|
mParent = shadow;
|
||||||
mXBLInvolved = true;
|
mXBLInvolved = Some(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,25 +144,31 @@ FlattenedChildIterator::Init(bool aIgnoreXBL)
|
||||||
if (binding) {
|
if (binding) {
|
||||||
MOZ_ASSERT(binding->GetAnonymousContent());
|
MOZ_ASSERT(binding->GetAnonymousContent());
|
||||||
mParent = binding->GetAnonymousContent();
|
mParent = binding->GetAnonymousContent();
|
||||||
mXBLInvolved = true;
|
mXBLInvolved = Some(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FlattenedChildIterator::ComputeWhetherXBLIsInvolved() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mXBLInvolved.isNothing());
|
||||||
|
// We set mXBLInvolved to true if either the node we're iterating has a
|
||||||
|
// binding with content attached to it (in which case it is handled in Init),
|
||||||
|
// or the node is generated XBL content and has an <xbl:children> child.
|
||||||
|
if (!mParent->GetBindingParent()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We set mXBLInvolved to true if either:
|
for (nsIContent* child = mParent->GetFirstChild();
|
||||||
// - The node we're iterating has a binding with content attached to it.
|
child;
|
||||||
// - The node is generated XBL content and has an <xbl:children> child.
|
child = child->GetNextSibling()) {
|
||||||
//
|
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
|
||||||
// FIXME(emilio): This is very slow :(
|
MOZ_ASSERT(child->GetBindingParent());
|
||||||
if (!mXBLInvolved && mParent->GetBindingParent()) {
|
return true;
|
||||||
for (nsIContent* child = mParent->GetFirstChild();
|
|
||||||
child;
|
|
||||||
child = child->GetNextSibling()) {
|
|
||||||
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
|
|
||||||
MOZ_ASSERT(child->GetBindingParent());
|
|
||||||
mXBLInvolved = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -134,7 +134,6 @@ public:
|
||||||
explicit FlattenedChildIterator(const nsIContent* aParent,
|
explicit FlattenedChildIterator(const nsIContent* aParent,
|
||||||
bool aStartAtBeginning = true)
|
bool aStartAtBeginning = true)
|
||||||
: ExplicitChildIterator(aParent, aStartAtBeginning)
|
: ExplicitChildIterator(aParent, aStartAtBeginning)
|
||||||
, mXBLInvolved(false)
|
|
||||||
, mOriginalContent(aParent)
|
, mOriginalContent(aParent)
|
||||||
{
|
{
|
||||||
Init(false);
|
Init(false);
|
||||||
|
@ -142,20 +141,30 @@ public:
|
||||||
|
|
||||||
FlattenedChildIterator(FlattenedChildIterator&& aOther)
|
FlattenedChildIterator(FlattenedChildIterator&& aOther)
|
||||||
: ExplicitChildIterator(Move(aOther))
|
: ExplicitChildIterator(Move(aOther))
|
||||||
, mXBLInvolved(aOther.mXBLInvolved)
|
|
||||||
, mOriginalContent(aOther.mOriginalContent)
|
, mOriginalContent(aOther.mOriginalContent)
|
||||||
|
, mXBLInvolved(aOther.mXBLInvolved)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FlattenedChildIterator(const FlattenedChildIterator& aOther)
|
FlattenedChildIterator(const FlattenedChildIterator& aOther)
|
||||||
: ExplicitChildIterator(aOther)
|
: ExplicitChildIterator(aOther)
|
||||||
, mXBLInvolved(aOther.mXBLInvolved)
|
|
||||||
, mOriginalContent(aOther.mOriginalContent)
|
, mOriginalContent(aOther.mOriginalContent)
|
||||||
|
, mXBLInvolved(aOther.mXBLInvolved)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool XBLInvolved() { return mXBLInvolved; }
|
bool XBLInvolved() {
|
||||||
|
if (mXBLInvolved.isNothing()) {
|
||||||
|
mXBLInvolved = Some(ComputeWhetherXBLIsInvolved());
|
||||||
|
}
|
||||||
|
return *mXBLInvolved;
|
||||||
|
}
|
||||||
|
|
||||||
const nsIContent* Parent() const { return mOriginalContent; }
|
const nsIContent* Parent() const { return mOriginalContent; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ComputeWhetherXBLIsInvolved() const;
|
||||||
|
|
||||||
|
void Init(bool aIgnoreXBL);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* This constructor is a hack to help AllChildrenIterator which sometimes
|
* This constructor is a hack to help AllChildrenIterator which sometimes
|
||||||
|
@ -164,20 +173,20 @@ protected:
|
||||||
FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags,
|
FlattenedChildIterator(const nsIContent* aParent, uint32_t aFlags,
|
||||||
bool aStartAtBeginning = true)
|
bool aStartAtBeginning = true)
|
||||||
: ExplicitChildIterator(aParent, aStartAtBeginning)
|
: ExplicitChildIterator(aParent, aStartAtBeginning)
|
||||||
, mXBLInvolved(false)
|
|
||||||
, mOriginalContent(aParent)
|
, mOriginalContent(aParent)
|
||||||
{
|
{
|
||||||
bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
|
bool ignoreXBL = aFlags & nsIContent::eAllButXBL;
|
||||||
Init(ignoreXBL);
|
Init(ignoreXBL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(bool aIgnoreXBL);
|
|
||||||
|
|
||||||
// For certain optimizations, nsCSSFrameConstructor needs to know if the
|
|
||||||
// child list of the element that we're iterating matches its .childNodes.
|
|
||||||
bool mXBLInvolved;
|
|
||||||
|
|
||||||
const nsIContent* mOriginalContent;
|
const nsIContent* mOriginalContent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// For certain optimizations, nsCSSFrameConstructor needs to know if the child
|
||||||
|
// list of the element that we're iterating matches its .childNodes.
|
||||||
|
//
|
||||||
|
// This is lazily computed when asked for it.
|
||||||
|
Maybe<bool> mXBLInvolved;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Загрузка…
Ссылка в новой задаче