Merge mozilla-central to autoland

This commit is contained in:
arthur.iakab 2018-08-07 12:39:49 +03:00
Родитель f31071f798 d39e02bf00
Коммит c8d3fc41b5
23 изменённых файлов: 353 добавлений и 665 удалений

Просмотреть файл

@ -13,7 +13,7 @@ var EXPORTED_SYMBOLS = ["LightweightThemeChildHelper"];
*/
var LightweightThemeChildHelper = {
listener: null,
whitelist: [],
whitelist: null,
/**
* Listen to theme updates for the current process
@ -40,9 +40,10 @@ var LightweightThemeChildHelper = {
_updateProcess(changedKeys) {
const windowEnumerator = Services.ww.getWindowEnumerator();
while (windowEnumerator.hasMoreElements()) {
const window = windowEnumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
const tabChildGlobal = window.docShell.messageManager;
const {chromeOuterWindowID, content} = tabChildGlobal;
const {
chromeOuterWindowID,
content,
} = windowEnumerator.getNext().docShell.messageManager;
if (changedKeys.includes(`theme/${chromeOuterWindowID}`) &&
content && this.whitelist.has(content.document.documentURI)) {
this.update(chromeOuterWindowID, content);

Просмотреть файл

@ -255,36 +255,6 @@ Attr::IsNodeOfType(uint32_t aFlags) const
return false;
}
uint32_t
Attr::GetChildCount() const
{
return 0;
}
nsIContent *
Attr::GetChildAt_Deprecated(uint32_t aIndex) const
{
return nullptr;
}
int32_t
Attr::ComputeIndexOf(const nsINode* aPossibleChild) const
{
return -1;
}
nsresult
Attr::InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
Attr::RemoveChildNode(nsIContent* aKid, bool aNotify)
{
}
void
Attr::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{

Просмотреть файл

@ -70,12 +70,6 @@ public:
// nsINode interface
virtual bool IsNodeOfType(uint32_t aFlags) const override;
virtual uint32_t GetChildCount() const override;
virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
bool aPreallocateChildren) const override;
virtual already_AddRefed<nsIURI> GetBaseURI(bool aTryUseXHRDocBaseURI = false) const override;

Просмотреть файл

@ -99,33 +99,6 @@ public:
virtual void SetNodeValueInternal(const nsAString& aNodeValue,
ErrorResult& aError) override;
// nsINode methods
uint32_t GetChildCount() const final
{
return 0;
}
nsIContent* GetChildAt_Deprecated(uint32_t aIndex) const final
{
return nullptr;
}
int32_t ComputeIndexOf(const nsINode* aPossibleChild) const final
{
return -1;
}
nsresult InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify) final
{
return NS_OK;
}
void RemoveChildNode(nsIContent* aKid, bool aNotify) final
{
}
void GetTextContentInternal(nsAString& aTextContent, OOMReporter&) final
{
GetNodeValue(aTextContent);

Просмотреть файл

@ -181,9 +181,9 @@ template<int a, int b> struct Check##type##Size \
Check##type##Size<sizeof(type), opt_size + EXTRA_DOM_ELEMENT_BYTES> g##type##CES;
// Note that mozjemalloc uses a 16 byte quantum, so 128 is a bin/bucket size.
ASSERT_ELEMENT_SIZE(Element, 120);
ASSERT_ELEMENT_SIZE(HTMLDivElement, 120);
ASSERT_ELEMENT_SIZE(HTMLSpanElement, 120);
ASSERT_ELEMENT_SIZE(Element, 128);
ASSERT_ELEMENT_SIZE(HTMLDivElement, 128);
ASSERT_ELEMENT_SIZE(HTMLSpanElement, 128);
#undef ASSERT_ELEMENT_SIZE
#undef EXTRA_DOM_ELEMENT_BYTES

Просмотреть файл

@ -1208,27 +1208,6 @@ nsIContent::SetXBLInsertionPoint(nsIContent* aContent)
}
}
nsresult
FragmentOrElement::InsertChildBefore(nsIContent* aKid,
nsIContent* aBeforeThis,
bool aNotify)
{
MOZ_ASSERT(aKid, "null ptr");
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
MOZ_ASSERT(index >= 0);
return doInsertChildAt(aKid, index, aNotify, mAttrsAndChildren);
}
void
FragmentOrElement::RemoveChildNode(nsIContent* aKid, bool aNotify)
{
// Let's keep the node alive.
nsCOMPtr<nsIContent> kungFuDeathGrip = aKid;
doRemoveChildAt(ComputeIndexOf(aKid), aNotify, aKid, mAttrsAndChildren);
}
void
FragmentOrElement::GetTextContentInternal(nsAString& aTextContent,
OOMReporter& aError)
@ -1349,24 +1328,20 @@ public:
return;
}
FragmentOrElement* container = static_cast<FragmentOrElement*>(aNode);
uint32_t childCount = container->mAttrsAndChildren.ChildCount();
if (childCount) {
if (container->HasChildren()) {
// Invalidate cached array of child nodes
container->InvalidateChildNodes();
while (childCount-- > 0) {
while (container->HasChildren()) {
// Hold a strong ref to the node when we remove it, because we may be
// the last reference to it. We need to call TakeChildAt() and
// update mFirstChild before calling UnbindFromTree, since this last
// can notify various observers and they should really see consistent
// the last reference to it. We need to call DisconnectChild()
// before calling UnbindFromTree, since this last can notify various
// observers and they should really see consistent
// tree state.
// If this code changes, change the corresponding code in
// FragmentOrElement's and nsDocument's unlink impls.
nsCOMPtr<nsIContent> child =
container->mAttrsAndChildren.TakeChildAt(childCount);
if (childCount == 0) {
container->mFirstChild = nullptr;
}
nsCOMPtr<nsIContent> child = container->GetLastChild();
container->DisconnectChild(child);
UnbindSubtree(child);
child->UnbindFromTree();
}
@ -1471,26 +1446,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
// Unlink child content (and unbind our subtree).
if (tmp->UnoptimizableCCNode() || !nsCCUncollectableMarker::sGeneration) {
uint32_t childCount = tmp->mAttrsAndChildren.ChildCount();
if (childCount) {
// Don't allow script to run while we're unbinding everything.
nsAutoScriptBlocker scriptBlocker;
while (childCount-- > 0) {
// Hold a strong ref to the node when we remove it, because we may be
// the last reference to it. We need to call TakeChildAt() and
// update mFirstChild before calling UnbindFromTree, since this last
// can notify various observers and they should really see consistent
// tree state.
// If this code changes, change the corresponding code in nsDocument's
// unlink impl and ContentUnbinder::UnbindSubtree.
nsCOMPtr<nsIContent> child = tmp->mAttrsAndChildren.TakeChildAt(childCount);
if (childCount == 0) {
tmp->mFirstChild = nullptr;
}
child->UnbindFromTree();
}
// Don't allow script to run while we're unbinding everything.
nsAutoScriptBlocker scriptBlocker;
while (tmp->HasChildren()) {
// Hold a strong ref to the node when we remove it, because we may be
// the last reference to it.
// If this code changes, change the corresponding code in nsDocument's
// unlink impl and ContentUnbinder::UnbindSubtree.
nsCOMPtr<nsIContent> child = tmp->GetLastChild();
tmp->DisconnectChild(child);
child->UnbindFromTree();
}
} else if (!tmp->GetParent() && tmp->mAttrsAndChildren.ChildCount()) {
} else if (!tmp->GetParent() && tmp->HasChildren()) {
ContentUnbinder::Append(tmp);
} /* else {
The subtree root will end up to a ContentUnbinder, and that will
@ -2049,7 +2016,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
}
}
// Traverse attribute names and child content.
// Traverse attribute names.
{
uint32_t i;
uint32_t attrs = tmp->mAttrsAndChildren.AttrCount();
@ -2062,12 +2029,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
NS_CYCLE_COLLECTION_PARTICIPANT(NodeInfo));
}
}
uint32_t kids = tmp->mAttrsAndChildren.ChildCount();
for (i = 0; i < kids; i++) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAttrsAndChildren[i]");
cb.NoteXPCOMChild(tmp->mAttrsAndChildren.GetSafeChildAt(i));
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -2128,24 +2089,6 @@ FragmentOrElement::ThreadSafeTextIsOnlyWhitespace() const
return false;
}
uint32_t
FragmentOrElement::GetChildCount() const
{
return mAttrsAndChildren.ChildCount();
}
nsIContent *
FragmentOrElement::GetChildAt_Deprecated(uint32_t aIndex) const
{
return mAttrsAndChildren.GetSafeChildAt(aIndex);
}
int32_t
FragmentOrElement::ComputeIndexOf(const nsINode* aPossibleChild) const
{
return mAttrsAndChildren.IndexOfChild(aPossibleChild);
}
static inline bool
IsVoidTag(nsAtom* aTag)
{

Просмотреть файл

@ -93,12 +93,6 @@ public:
NS_DECL_ADDSIZEOFEXCLUDINGTHIS
// nsINode interface methods
virtual uint32_t GetChildCount() const override;
virtual nsIContent *GetChildAt_Deprecated(uint32_t aIndex) const override;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const override;
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) override;
virtual void GetTextContentInternal(nsAString& aTextContent,
mozilla::OOMReporter& aError) override;
virtual void SetTextContentInternal(const nsAString& aTextContent,

Просмотреть файл

@ -107,189 +107,6 @@ nsAttrAndChildArray::~nsAttrAndChildArray()
free(mImpl);
}
nsIContent*
nsAttrAndChildArray::GetSafeChildAt(uint32_t aPos) const
{
if (aPos < ChildCount()) {
return ChildAt(aPos);
}
return nullptr;
}
nsIContent * const *
nsAttrAndChildArray::GetChildArray(uint32_t* aChildCount) const
{
*aChildCount = ChildCount();
if (!*aChildCount) {
return nullptr;
}
return reinterpret_cast<nsIContent**>(mImpl->mBuffer + AttrSlotsSize());
}
nsresult
nsAttrAndChildArray::InsertChildAt(nsIContent* aChild, uint32_t aPos)
{
NS_ASSERTION(aChild, "nullchild");
NS_ASSERTION(aPos <= ChildCount(), "out-of-bounds");
uint32_t offset = AttrSlotsSize();
uint32_t childCount = ChildCount();
NS_ENSURE_TRUE(childCount < ATTRCHILD_ARRAY_MAX_CHILD_COUNT,
NS_ERROR_FAILURE);
// First try to fit new child in existing childlist
if (mImpl && offset + childCount < mImpl->mBufferSize) {
void** pos = mImpl->mBuffer + offset + aPos;
if (childCount != aPos) {
memmove(pos + 1, pos, (childCount - aPos) * sizeof(nsIContent*));
}
SetChildAtPos(pos, aChild, aPos, childCount);
SetChildCount(childCount + 1);
return NS_OK;
}
// Try to fit new child in existing buffer by compressing attrslots
if (offset && !mImpl->mBuffer[offset - ATTRSIZE]) {
// Compress away all empty slots while we're at it. This might not be the
// optimal thing to do.
uint32_t attrCount = NonMappedAttrCount();
void** newStart = mImpl->mBuffer + attrCount * ATTRSIZE;
void** oldStart = mImpl->mBuffer + offset;
memmove(newStart, oldStart, aPos * sizeof(nsIContent*));
memmove(&newStart[aPos + 1], &oldStart[aPos],
(childCount - aPos) * sizeof(nsIContent*));
SetChildAtPos(newStart + aPos, aChild, aPos, childCount);
SetAttrSlotAndChildCount(attrCount, childCount + 1);
return NS_OK;
}
// We can't fit in current buffer, Realloc time!
if (!GrowBy(1)) {
return NS_ERROR_OUT_OF_MEMORY;
}
void** pos = mImpl->mBuffer + offset + aPos;
if (childCount != aPos) {
memmove(pos + 1, pos, (childCount - aPos) * sizeof(nsIContent*));
}
SetChildAtPos(pos, aChild, aPos, childCount);
SetChildCount(childCount + 1);
return NS_OK;
}
void
nsAttrAndChildArray::RemoveChildAt(uint32_t aPos)
{
// Just store the return value of TakeChildAt in an nsCOMPtr to
// trigger a release.
nsCOMPtr<nsIContent> child = TakeChildAt(aPos);
}
already_AddRefed<nsIContent>
nsAttrAndChildArray::TakeChildAt(uint32_t aPos)
{
NS_ASSERTION(aPos < ChildCount(), "out-of-bounds");
uint32_t childCount = ChildCount();
void** pos = mImpl->mBuffer + AttrSlotsSize() + aPos;
nsIContent* child = static_cast<nsIContent*>(*pos);
if (child->mPreviousSibling) {
child->mPreviousSibling->mNextSibling = child->mNextSibling;
}
if (child->mNextSibling) {
child->mNextSibling->mPreviousSibling = child->mPreviousSibling;
}
child->mPreviousSibling = child->mNextSibling = nullptr;
memmove(pos, pos + 1, (childCount - aPos - 1) * sizeof(nsIContent*));
SetChildCount(childCount - 1);
return dont_AddRef(child);
}
int32_t
nsAttrAndChildArray::IndexOfChild(const nsINode* aPossibleChild) const
{
if (!mImpl) {
return -1;
}
void** children = mImpl->mBuffer + AttrSlotsSize();
// Use signed here since we compare count to cursor which has to be signed
int32_t i, count = ChildCount();
if (count >= CACHE_CHILD_LIMIT) {
int32_t cursor = GetIndexFromCache(this);
// Need to compare to count here since we may have removed children since
// the index was added to the cache.
// We're also relying on that GetIndexFromCache returns -1 if no cached
// index was found.
if (cursor >= count) {
cursor = -1;
}
// Seek outward from the last found index. |inc| will change sign every
// run through the loop. |sign| just exists to make sure the absolute
// value of |inc| increases each time through.
int32_t inc = 1, sign = 1;
while (cursor >= 0 && cursor < count) {
if (children[cursor] == aPossibleChild) {
AddIndexToCache(this, cursor);
return cursor;
}
cursor += inc;
inc = -inc - sign;
sign = -sign;
}
// We ran into one 'edge'. Add inc to cursor once more to get back to
// the 'side' where we still need to search, then step in the |sign|
// direction.
cursor += inc;
if (sign > 0) {
for (; cursor < count; ++cursor) {
if (children[cursor] == aPossibleChild) {
AddIndexToCache(this, cursor);
return static_cast<int32_t>(cursor);
}
}
}
else {
for (; cursor >= 0; --cursor) {
if (children[cursor] == aPossibleChild) {
AddIndexToCache(this, cursor);
return static_cast<int32_t>(cursor);
}
}
}
// The child wasn't even in the remaining children
return -1;
}
for (i = 0; i < count; ++i) {
if (children[i] == aPossibleChild) {
return static_cast<int32_t>(i);
}
}
return -1;
}
uint32_t
nsAttrAndChildArray::AttrCount() const
{
@ -652,17 +469,13 @@ nsAttrAndChildArray::Compact()
// First compress away empty attrslots
uint32_t slotCount = AttrSlotCount();
uint32_t attrCount = NonMappedAttrCount();
uint32_t childCount = ChildCount();
if (attrCount < slotCount) {
memmove(mImpl->mBuffer + attrCount * ATTRSIZE,
mImpl->mBuffer + slotCount * ATTRSIZE,
childCount * sizeof(nsIContent*));
SetAttrSlotCount(attrCount);
}
// Then resize or free buffer
uint32_t newSize = attrCount * ATTRSIZE + childCount;
uint32_t newSize = attrCount * ATTRSIZE;
if (!newSize && !mImpl->mMappedAttrs) {
free(mImpl);
mImpl = nullptr;
@ -691,28 +504,6 @@ nsAttrAndChildArray::Clear()
ATTRS(mImpl)[i].~InternalAttr();
}
nsAutoScriptBlocker scriptBlocker;
uint32_t end = slotCount * ATTRSIZE + ChildCount();
for (i = slotCount * ATTRSIZE; i < end; ++i) {
nsIContent* child = static_cast<nsIContent*>(mImpl->mBuffer[i]);
// making this false so tree teardown doesn't end up being
// O(N*D) (number of nodes times average depth of tree).
child->UnbindFromTree(false); // XXX is it better to let the owner do this?
// Make sure to unlink our kids from each other, since someone
// else could stil be holding references to some of them.
// XXXbz We probably can't push this assignment down into the |aNullParent|
// case of UnbindFromTree because we still need the assignment in
// RemoveChildAt. In particular, ContentRemoved fires between
// RemoveChildAt and UnbindFromTree, and in ContentRemoved the sibling
// chain needs to be correct. Though maybe we could set the prev and next
// to point to each other but keep the kid being removed pointing to them
// through ContentRemoved so consumers can find where it used to be in the
// list?
child->mPreviousSibling = child->mNextSibling = nullptr;
NS_RELEASE(child);
}
SetAttrSlotAndChildCount(0, 0);
}
@ -816,12 +607,8 @@ nsresult nsAttrAndChildArray::EnsureCapacityToClone(const nsAttrAndChildArray& a
MOZ_ASSERT(!mImpl, "nsAttrAndChildArray::EnsureCapacityToClone requires the array be empty when called");
uint32_t attrCount = aOther.NonMappedAttrCount();
uint32_t childCount = 0;
if (aAllocateChildren) {
childCount = aOther.ChildCount();
}
if (attrCount == 0 && childCount == 0) {
if (attrCount == 0) {
return NS_OK;
}
@ -829,7 +616,6 @@ nsresult nsAttrAndChildArray::EnsureCapacityToClone(const nsAttrAndChildArray& a
// have already allocated an nsAttrAndChildArray of this size.
uint32_t size = attrCount;
size *= ATTRSIZE;
size += childCount;
uint32_t totalSize = size;
totalSize += NS_IMPL_EXTRA_SIZE;
@ -910,12 +696,10 @@ bool
nsAttrAndChildArray::AddAttrSlot()
{
uint32_t slotCount = AttrSlotCount();
uint32_t childCount = ChildCount();
CheckedUint32 size = slotCount;
size += 1;
size *= ATTRSIZE;
size += childCount;
if (!size.isValid()) {
return false;
}
@ -928,38 +712,12 @@ nsAttrAndChildArray::AddAttrSlot()
void** offset = mImpl->mBuffer + slotCount * ATTRSIZE;
if (childCount > 0) {
memmove(&ATTRS(mImpl)[slotCount + 1], &ATTRS(mImpl)[slotCount],
childCount * sizeof(nsIContent*));
}
SetAttrSlotCount(slotCount + 1);
memset(static_cast<void*>(offset), 0, sizeof(InternalAttr));
return true;
}
inline void
nsAttrAndChildArray::SetChildAtPos(void** aPos, nsIContent* aChild,
uint32_t aIndex, uint32_t aChildCount)
{
MOZ_ASSERT(!aChild->GetNextSibling(), "aChild with next sibling?");
MOZ_ASSERT(!aChild->GetPreviousSibling(), "aChild with prev sibling?");
*aPos = aChild;
NS_ADDREF(aChild);
if (aIndex != 0) {
nsIContent* previous = static_cast<nsIContent*>(*(aPos - 1));
aChild->mPreviousSibling = previous;
previous->mNextSibling = aChild;
}
if (aIndex != aChildCount) {
nsIContent* next = static_cast<nsIContent*>(*(aPos + 1));
aChild->mNextSibling = next;
next->mPreviousSibling = aChild;
}
}
size_t
nsAttrAndChildArray::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{

Просмотреть файл

@ -52,24 +52,6 @@ public:
nsAttrAndChildArray();
~nsAttrAndChildArray();
uint32_t ChildCount() const
{
return mImpl ? (mImpl->mAttrAndChildCount >> ATTRCHILD_ARRAY_ATTR_SLOTS_BITS) : 0;
}
nsIContent* ChildAt(uint32_t aPos) const
{
NS_ASSERTION(aPos < ChildCount(), "out-of-bounds access in nsAttrAndChildArray");
return reinterpret_cast<nsIContent*>(mImpl->mBuffer[AttrSlotsSize() + aPos]);
}
nsIContent* GetSafeChildAt(uint32_t aPos) const;
nsIContent * const * GetChildArray(uint32_t* aChildCount) const;
nsresult InsertChildAt(nsIContent* aChild, uint32_t aPos);
void RemoveChildAt(uint32_t aPos);
// Like RemoveChildAt but hands the reference to the child being
// removed back to the caller instead of just releasing it.
already_AddRefed<nsIContent> TakeChildAt(uint32_t aPos);
int32_t IndexOfChild(const nsINode* aPossibleChild) const;
bool HasAttrs() const
{
return MappedAttrCount() || (AttrSlotCount() && AttrSlotIsTaken(0));
@ -222,14 +204,6 @@ private:
bool GrowBy(uint32_t aGrowSize);
bool AddAttrSlot();
/**
* Set *aPos to aChild and update sibling pointers as needed. aIndex is the
* index at which aChild is actually being inserted. aChildCount is the
* number of kids we had before the insertion.
*/
inline void SetChildAtPos(void** aPos, nsIContent* aChild, uint32_t aIndex,
uint32_t aChildCount);
/**
* Guts of SetMappedAttrStyleSheet for the rare case when we have mapped attrs
*/

Просмотреть файл

@ -1696,11 +1696,10 @@ nsDocument::~nsDocument()
// Invalidate cached array of child nodes
InvalidateChildNodes();
for (uint32_t indx = mChildren.ChildCount(); indx-- != 0; ) {
mChildren.ChildAt(indx)->UnbindFromTree();
mChildren.RemoveChildAt(indx);
}
mFirstChild = nullptr;
// We should not have child nodes when destructor is called,
// since child nodes keep their owner document alive.
MOZ_ASSERT(!HasChildren());
mCachedRootElement = nullptr;
for (auto& sheets : mAdditionalSheets) {
@ -1866,12 +1865,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
tmp->mExternalResourceMap.Traverse(&cb);
// Traverse the mChildren nsAttrAndChildArray.
for (int32_t indx = int32_t(tmp->mChildren.ChildCount()); indx > 0; --indx) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildren[i]");
cb.NoteXPCOMChild(tmp->mChildren.ChildAt(indx - 1));
}
// Traverse all nsIDocument pointer members.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSecurityInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDisplayDocument)
@ -1987,25 +1980,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
nsINode::Unlink(tmp);
// Unlink the mChildren nsAttrAndChildArray.
uint32_t childCount = tmp->mChildren.ChildCount();
if (childCount) {
while (childCount-- > 0) {
// Hold a strong ref to the node when we remove it, because we may be
// the last reference to it. We need to call TakeChildAt() and
// update mFirstChild before calling UnbindFromTree, since this last
// can notify various observers and they should really see consistent
// tree state.
// If this code changes, change the corresponding code in
// FragmentOrElement's unlink impl and ContentUnbinder::UnbindSubtree.
nsCOMPtr<nsIContent> child = tmp->mChildren.TakeChildAt(childCount);
if (childCount == 0) {
tmp->mFirstChild = nullptr;
}
child->UnbindFromTree();
}
while (tmp->HasChildren()) {
// Hold a strong ref to the node when we remove it, because we may be
// the last reference to it.
// If this code changes, change the corresponding code in nsDocument's
// unlink impl and ContentUnbinder::UnbindSubtree.
nsCOMPtr<nsIContent> child = tmp->GetLastChild();
tmp->DisconnectChild(child);
child->UnbindFromTree();
}
tmp->mFirstChild = nullptr;
tmp->UnlinkOriginalDocumentIfStatic();
@ -2253,22 +2236,16 @@ nsIDocument::ResetToURI(nsIURI* aURI,
bool oldVal = mInUnlinkOrDeletion;
mInUnlinkOrDeletion = true;
uint32_t count = mChildren.ChildCount();
{ // Scope for update
MOZ_AUTO_DOC_UPDATE(this, true);
// Invalidate cached array of child nodes
InvalidateChildNodes();
for (int32_t i = int32_t(count) - 1; i >= 0; i--) {
nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
while (HasChildren()) {
nsCOMPtr<nsIContent> content = GetLastChild();
nsIContent* previousSibling = content->GetPreviousSibling();
if (nsINode::GetFirstChild() == content) {
mFirstChild = content->GetNextSibling();
}
mChildren.RemoveChildAt(i);
DisconnectChild(content);
if (content == mCachedRootElement) {
// Immediately clear mCachedRootElement, now that it's been removed
// from mChildren, so that GetRootElement() will stop returning this
@ -4143,10 +4120,7 @@ nsIDocument::InsertChildBefore(nsIContent* aKid,
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
MOZ_ASSERT(index >= 0);
return doInsertChildAt(aKid, index, aNotify, mChildren);
return nsINode::InsertChildBefore(aKid, aBeforeThis, aNotify);
}
void
@ -4159,13 +4133,13 @@ nsIDocument::RemoveChildNode(nsIContent* aKid, bool aNotify)
// Preemptively clear mCachedRootElement, since we may be about to remove it
// from our child list, and we don't want to return this maybe-obsolete value
// from any GetRootElement() calls that happen inside of doRemoveChildAt().
// (NOTE: for this to be useful, doRemoveChildAt() must NOT trigger any
// from any GetRootElement() calls that happen inside of RemoveChildNode().
// (NOTE: for this to be useful, RemoveChildNode() must NOT trigger any
// GetRootElement() calls until after it's removed the child from mChildren.
// Any call before that point would restore this soon-to-be-obsolete cached
// answer, and our clearing here would be fruitless.)
mCachedRootElement = nullptr;
doRemoveChildAt(ComputeIndexOf(aKid), aNotify, aKid, mChildren);
nsINode::RemoveChildNode(aKid, aNotify);
MOZ_ASSERT(mCachedRootElement != aKid,
"Stale pointer in mCachedRootElement, after we tried to clear it "
"(maybe somebody called GetRootElement() too early?)");
@ -8771,10 +8745,6 @@ nsDocument::CloneDocHelper(nsDocument* clone, bool aPreallocateChildren) const
clone->mXMLDeclarationBits = mXMLDeclarationBits;
clone->mBaseTarget = mBaseTarget;
// Preallocate attributes and child arrays
rv = clone->mChildren.EnsureCapacityToClone(mChildren, aPreallocateChildren);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

Просмотреть файл

@ -532,21 +532,6 @@ public:
// nsINode
bool IsNodeOfType(uint32_t aFlags) const final;
nsIContent* GetChildAt_Deprecated(uint32_t aIndex) const final
{
return mChildren.GetSafeChildAt(aIndex);
}
int32_t ComputeIndexOf(const nsINode* aPossibleChild) const final
{
return mChildren.IndexOfChild(aPossibleChild);
}
uint32_t GetChildCount() const final
{
return mChildren.ChildCount();
}
nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) override;
void RemoveChildNode(nsIContent* aKid, bool aNotify) final;

Просмотреть файл

@ -150,6 +150,21 @@ nsINode::nsSlots::Unlink()
//----------------------------------------------------------------------
#ifdef MOZILLA_INTERNAL_API
nsINode::nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: mNodeInfo(aNodeInfo)
, mParent(nullptr)
#ifndef BOOL_FLAGS_ON_WRAPPER_CACHE
, mBoolFlags(0)
#endif
, mChildCount(0)
, mPreviousOrLastSibling(nullptr)
, mSubtreeRoot(this)
, mSlots(nullptr)
{
}
#endif
nsINode::~nsINode()
{
MOZ_ASSERT(!HasSlots(), "nsNodeUtils::LastRelease was not called?");
@ -415,6 +430,12 @@ nsINode::ChildNodes()
return slots->mChildNodes;
}
nsIContent*
nsINode::GetLastChild() const
{
return mFirstChild ? mFirstChild->mPreviousOrLastSibling : nullptr;
}
void
nsINode::InvalidateChildNodes()
{
@ -1208,6 +1229,8 @@ nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNodeInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFirstChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNextSibling)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
nsSlots *slots = tmp->GetExistingSlots();
@ -1335,9 +1358,13 @@ ReparentWrappersInSubtree(nsIContent* aRoot)
}
nsresult
nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
bool aNotify, nsAttrAndChildArray& aChildArray)
{
nsINode::InsertChildBefore(nsIContent* aKid, nsIContent* aChildToInsertBefore,
bool aNotify)
{
if (!IsContainerNode()) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
MOZ_ASSERT(!aKid->GetParentNode(), "Inserting node that already has parent");
MOZ_ASSERT(!IsAttr());
@ -1373,31 +1400,24 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
}
}
uint32_t childCount = aChildArray.ChildCount();
NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
bool isAppend = (aIndex == childCount);
nsresult rv = aChildArray.InsertChildAt(aKid, aIndex);
NS_ENSURE_SUCCESS(rv, rv);
if (aIndex == 0) {
mFirstChild = aKid;
if (!aChildToInsertBefore) {
AppendChildToChildList(aKid);
} else {
InsertChildToChildList(aKid, aChildToInsertBefore);
}
nsIContent* parent = IsContent() ? AsContent() : nullptr;
bool wasInXBLScope = ShouldUseXBLScope(aKid);
rv = aKid->BindToTree(doc, parent,
parent ? parent->GetBindingParent() : nullptr);
nsresult rv = aKid->BindToTree(doc, parent,
parent ? parent->GetBindingParent() : nullptr);
if (NS_SUCCEEDED(rv) && !wasInXBLScope && ShouldUseXBLScope(aKid)) {
MOZ_ASSERT(ShouldUseXBLScope(this),
"Why does the kid need to use an XBL scope?");
rv = ReparentWrappersInSubtree(aKid);
}
if (NS_FAILED(rv)) {
if (GetFirstChild() == aKid) {
mFirstChild = aKid->GetNextSibling();
}
aChildArray.RemoveChildAt(aIndex);
DisconnectChild(aKid);
aKid->UnbindFromTree();
return rv;
}
@ -1411,7 +1431,7 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
if (aNotify) {
// Note that we always want to call ContentInserted when things are added
// as kids to documents
if (parent && isAppend) {
if (parent && !aChildToInsertBefore) {
nsNodeUtils::ContentAppended(parent, aKid);
} else {
nsNodeUtils::ContentInserted(this, aKid);
@ -1430,6 +1450,127 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
return NS_OK;
}
nsIContent*
nsINode::GetPreviousSibling() const
{
// Do not expose circular linked list
if (mPreviousOrLastSibling && !mPreviousOrLastSibling->mNextSibling) {
return nullptr;
}
return mPreviousOrLastSibling;
}
void
nsINode::AppendChildToChildList(nsIContent* aKid)
{
MOZ_ASSERT(aKid);
MOZ_ASSERT(!aKid->mNextSibling);
if (mFirstChild) {
nsIContent* lastChild = GetLastChild();
lastChild->mNextSibling = aKid;
aKid->mPreviousOrLastSibling = lastChild;
} else {
mFirstChild = aKid;
}
// Maintain link to the last child
mFirstChild->mPreviousOrLastSibling = aKid;
++mChildCount;
}
void
nsINode::InsertChildToChildList(nsIContent* aKid, nsIContent* aNextSibling)
{
MOZ_ASSERT(aKid);
MOZ_ASSERT(aNextSibling);
nsIContent* previousSibling = aNextSibling->mPreviousOrLastSibling;
aNextSibling->mPreviousOrLastSibling = aKid;
aKid->mPreviousOrLastSibling = previousSibling;
aKid->mNextSibling = aNextSibling;
if (aNextSibling == mFirstChild) {
MOZ_ASSERT(!previousSibling->mNextSibling);
mFirstChild = aKid;
} else {
previousSibling->mNextSibling = aKid;
}
++mChildCount;
}
void
nsINode::DisconnectChild(nsIContent* aKid)
{
MOZ_ASSERT(aKid);
MOZ_ASSERT(GetChildCount() > 0);
nsIContent* previousSibling = aKid->GetPreviousSibling();
nsCOMPtr<nsIContent> ref = aKid;
if (aKid->mNextSibling) {
aKid->mNextSibling->mPreviousOrLastSibling = aKid->mPreviousOrLastSibling;
} else {
// aKid is the last child in the list
mFirstChild->mPreviousOrLastSibling = aKid->mPreviousOrLastSibling;
}
aKid->mPreviousOrLastSibling = nullptr;
if (previousSibling) {
previousSibling->mNextSibling = aKid->mNextSibling.forget();
} else {
// aKid is the first child in the list
mFirstChild = aKid->mNextSibling.forget();
}
--mChildCount;
}
nsIContent*
nsINode::GetChildAt_Deprecated(uint32_t aIndex) const
{
if (aIndex >= GetChildCount()) {
return nullptr;
}
nsIContent* child = mFirstChild;
while (aIndex--) {
child = child->GetNextSibling();
}
return child;
}
int32_t
nsINode::ComputeIndexOf(const nsINode* aChild) const
{
if (!aChild) {
return -1;
}
if (aChild->GetParentNode() != this) {
return -1;
}
if (aChild == GetLastChild()) {
return GetChildCount() - 1;
}
int32_t index = 0;
nsINode* current = mFirstChild;
while (current) {
MOZ_ASSERT(current->GetParentNode() == this);
if (current == aChild) {
return index;
}
current = current->GetNextSibling();
++index;
}
return -1;
}
Element*
nsINode::GetPreviousElementSibling() const
{
@ -1756,7 +1897,7 @@ nsINode::Prepend(const Sequence<OwningNodeOrString>& aNodes,
return;
}
nsCOMPtr<nsINode> refNode = mFirstChild;
nsCOMPtr<nsIContent> refNode = mFirstChild;;
InsertBefore(*node, refNode, aRv);
}
@ -1774,17 +1915,14 @@ nsINode::Append(const Sequence<OwningNodeOrString>& aNodes,
}
void
nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
nsIContent* aKid, nsAttrAndChildArray& aChildArray)
nsINode::RemoveChildNode(nsIContent* aKid, bool aNotify)
{
// NOTE: This function must not trigger any calls to
// nsIDocument::GetRootElement() calls until *after* it has removed aKid from
// aChildArray. Any calls before then could potentially restore a stale
// value for our cached root element, per note in
// nsDocument::RemoveChildNode().
MOZ_ASSERT(aKid && aKid->GetParentNode() == this &&
aKid == GetChildAt_Deprecated(aIndex) &&
ComputeIndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
MOZ_ASSERT(aKid && aKid->GetParentNode() == this, "Bogus aKid");
MOZ_ASSERT(!IsAttr());
nsMutationGuard::DidMutate();
@ -1792,11 +1930,9 @@ nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
nsIContent* previousSibling = aKid->GetPreviousSibling();
if (GetFirstChild() == aKid) {
mFirstChild = aKid->GetNextSibling();
}
aChildArray.RemoveChildAt(aIndex);
// Since aKid is use also after DisconnectChild, ensure it stays alive.
nsCOMPtr<nsIContent> kungfuDeathGrip = aKid;
DisconnectChild(aKid);
// Invalidate cached array of child nodes
InvalidateChildNodes();
@ -2434,8 +2570,8 @@ nsINode::AddSizeOfExcludingThis(nsWindowSizes& aSizes, size_t* aNodeSize) const
// - mSlots
//
// The following members are not measured:
// - mParent, mNextSibling, mPreviousSibling, mFirstChild: because they're
// non-owning
// - mParent, mNextSibling, mPreviousOrLastSibling, mFirstChild: because they're
// non-owning, from "exclusive ownership" point of view.
}
void

Просмотреть файл

@ -370,19 +370,7 @@ public:
friend class nsAttrAndChildArray;
#ifdef MOZILLA_INTERNAL_API
explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: mNodeInfo(aNodeInfo)
, mParent(nullptr)
#ifndef BOOL_FLAGS_ON_WRAPPER_CACHE
, mBoolFlags(0)
#endif
, mNextSibling(nullptr)
, mPreviousSibling(nullptr)
, mFirstChild(nullptr)
, mSubtreeRoot(this)
, mSlots(nullptr)
{
}
explicit nsINode(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
#endif
virtual ~nsINode();
@ -582,7 +570,10 @@ public:
* Get the number of children
* @return the number of children
*/
virtual uint32_t GetChildCount() const = 0;
uint32_t GetChildCount() const
{
return mChildCount;
}
/**
* NOTE: this function is going to be removed soon (hopefully!) Don't use it
@ -592,7 +583,7 @@ public:
* @param aIndex the index of the child to get
* @return the child, or null if index out of bounds
*/
virtual nsIContent* GetChildAt_Deprecated(uint32_t aIndex) const = 0;
nsIContent* GetChildAt_Deprecated(uint32_t aIndex) const;
/**
* Get the index of a child within this content
@ -602,7 +593,7 @@ public:
* If the return value is not -1, then calling GetChildAt_Deprecated() with
* that value will return aPossibleChild.
*/
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const = 0;
virtual int32_t ComputeIndexOf(const nsINode* aPossibleChild) const;
/**
* Returns the "node document" of this node.
@ -827,7 +818,7 @@ public:
* @throws NS_ERROR_OUT_OF_MEMORY in some cases (from BindToTree).
*/
virtual nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
bool aNotify) = 0;
bool aNotify);
/**
* Append a content node to the end of the child list. This method handles
@ -861,7 +852,7 @@ public:
* nsIContent, and |this| for nsIDocument) that the remove has
* occurred
*/
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify) = 0;
virtual void RemoveChildNode(nsIContent* aKid, bool aNotify);
/**
* Get a property associated with this node.
@ -1296,14 +1287,14 @@ public:
nsIContent* GetSelectionRootContent(nsIPresShell* aPresShell);
nsINodeList* ChildNodes();
nsIContent* GetFirstChild() const { return mFirstChild; }
nsIContent* GetLastChild() const
{
uint32_t count = GetChildCount();
return count > 0 ? GetChildAt_Deprecated(count - 1) : nullptr;
nsIContent* GetFirstChild() const
{
return mFirstChild;
}
nsIContent* GetLastChild() const;
/**
* Implementation is in nsIDocument.h, because it needs to cast from
* nsIDocument* to nsINode*.
@ -1373,6 +1364,10 @@ protected:
// should really only be called for elements and document fragments.
mozilla::dom::Element* GetElementById(const nsAString& aId);
void AppendChildToChildList(nsIContent* aKid);
void InsertChildToChildList(nsIContent* aKid, nsIContent* aNextSibling);
void DisconnectChild(nsIContent* aKid);
public:
void LookupPrefix(const nsAString& aNamespace, nsAString& aResult);
bool IsDefaultNamespace(const nsAString& aNamespaceURI)
@ -1385,7 +1380,7 @@ public:
nsAString& aNamespaceURI);
nsIContent* GetNextSibling() const { return mNextSibling; }
nsIContent* GetPreviousSibling() const { return mPreviousSibling; }
nsIContent* GetPreviousSibling() const;
/**
* Get the next node in the pre-order tree traversal of the DOM. If
@ -1991,33 +1986,6 @@ protected:
*/
virtual mozilla::dom::Element* GetNameSpaceElement() = 0;
/**
* Most of the implementation of the nsINode RemoveChildAt method.
* Should only be called on document, element, and document fragment
* nodes. The aChildArray passed in should be the one for |this|.
*
* @param aIndex The index to remove at.
* @param aNotify Whether to notify.
* @param aKid The kid at aIndex. Must not be null.
* @param aChildArray The child array to work with.
* @param aMutationEvent whether to fire a mutation event for this removal.
*/
void doRemoveChildAt(uint32_t aIndex, bool aNotify, nsIContent* aKid,
nsAttrAndChildArray& aChildArray);
/**
* Most of the implementation of the nsINode InsertChildAt_Deprecated method.
* Should only be called on document, element, and document fragment
* nodes. The aChildArray passed in should be the one for |this|.
*
* @param aKid The child to insert.
* @param aIndex The index to insert at.
* @param aNotify Whether to notify.
* @param aChildArray The child array to work with
*/
nsresult doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
bool aNotify, nsAttrAndChildArray& aChildArray);
/**
* Parse the given selector string into a servo SelectorList.
*
@ -2065,16 +2033,17 @@ private:
uint32_t mBoolFlags;
#endif
//NOTE, there are 32 bits left here, at least in 64 bit builds.
uint32_t mChildCount;
protected:
// These references are non-owning and safe, as they are managed by
// nsAttrAndChildArray.
nsIContent* MOZ_NON_OWNING_REF mNextSibling;
nsIContent* MOZ_NON_OWNING_REF mPreviousSibling;
// This reference is non-owning and safe, since in the case of documents,
// it is set to null when the document gets destroyed, and in the case of
// other nodes, the children keep the parents alive.
nsIContent* MOZ_NON_OWNING_REF mFirstChild;
// mNextSibling and mFirstChild are strong references while
// mPreviousOrLastSibling is a weak ref. |mFirstChild->mPreviousOrLastSibling|
// points to the last child node.
nsCOMPtr<nsIContent> mFirstChild;
nsCOMPtr<nsIContent> mNextSibling;
nsIContent* MOZ_NON_OWNING_REF mPreviousOrLastSibling;
union {
// Pointer to our primary frame. Might be null.

Просмотреть файл

@ -69,7 +69,7 @@ SVGTests::IsConditionalProcessingAttribute(const nsAtom* aAttribute) const
int32_t
SVGTests::GetBestLanguagePreferenceRank(const nsAString& aAcceptLangs) const
{
const nsDefaultStringComparator defaultComparator;
const nsCaseInsensitiveStringComparator caseInsensitiveComparator;
if (!mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
return -2;
@ -82,12 +82,13 @@ SVGTests::GetBestLanguagePreferenceRank(const nsAString& aAcceptLangs) const
int32_t index = 0;
while (languageTokenizer.hasMoreTokens()) {
const nsAString& languageToken = languageTokenizer.nextToken();
bool exactMatch = (languageToken == mStringListAttributes[LANGUAGE][i]);
bool exactMatch = languageToken.Equals(mStringListAttributes[LANGUAGE][i],
caseInsensitiveComparator);
bool prefixOnlyMatch =
!exactMatch &&
nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
languageTokenizer.nextToken(),
defaultComparator);
caseInsensitiveComparator);
if (index == 0 && exactMatch) {
// best possible match
return 0;
@ -155,14 +156,14 @@ SVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const
return false;
}
const nsDefaultStringComparator defaultComparator;
const nsCaseInsensitiveStringComparator caseInsensitiveComparator;
for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
nsCharSeparatedTokenizer languageTokenizer(acceptLangs, ',');
while (languageTokenizer.hasMoreTokens()) {
if (nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
languageTokenizer.nextToken(),
defaultComparator)) {
caseInsensitiveComparator)) {
return true;
}
}

Просмотреть файл

@ -16,6 +16,8 @@
#include "mozilla/MathAlgorithms.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/layers/CompositorOptions.h"
#include "mozilla/Range.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/widget/CompositorWidget.h"
#include "mozilla/widget/GtkCompositorWidget.h"
#include "mozilla/Unused.h"
@ -108,6 +110,7 @@ GLXLibrary::EnsureInitialized()
SYMBOL(MakeCurrent),
SYMBOL(SwapBuffers),
SYMBOL(QueryVersion),
SYMBOL(GetConfig),
SYMBOL(GetCurrentContext),
SYMBOL(WaitGL),
SYMBOL(WaitX),
@ -888,28 +891,76 @@ bool
GLContextGLX::FindVisual(Display* display, int screen, bool useWebRender,
bool useAlpha, int* const out_visualId)
{
int attribs[] = {
LOCAL_GLX_RGBA,
LOCAL_GLX_DOUBLEBUFFER,
LOCAL_GLX_RED_SIZE, 8,
LOCAL_GLX_GREEN_SIZE, 8,
LOCAL_GLX_BLUE_SIZE, 8,
LOCAL_GLX_ALPHA_SIZE, useAlpha ? 8 : 0,
LOCAL_GLX_DEPTH_SIZE, useWebRender ? 24 : 0,
LOCAL_GL_NONE
};
if (!sGLXLibrary.EnsureInitialized()) {
return false;
}
XVisualInfo* visuals = sGLXLibrary.fChooseVisual(display, screen, attribs);
if (!visuals) {
XVisualInfo visualTemplate;
visualTemplate.screen = screen;
// Get all visuals of screen
int visualsLen = 0;
XVisualInfo* xVisuals = XGetVisualInfo(display, VisualScreenMask, &visualTemplate, &visualsLen);
if (!xVisuals) {
return false;
}
const Range<XVisualInfo> visualInfos(xVisuals, visualsLen);
auto cleanupVisuals = MakeScopeExit([&] {
XFree(xVisuals);
});
// Get default visual info
Visual* defaultVisual = DefaultVisual(display, screen);
const auto defaultVisualInfo = [&]() -> const XVisualInfo* {
for (const auto& cur : visualInfos) {
if (cur.visual == defaultVisual) {
return &cur;
}
}
return nullptr;
}();
if (!defaultVisualInfo) {
MOZ_ASSERT(false);
return false;
}
*out_visualId = visuals[0].visualid;
return true;
const int bpp = useAlpha ? 32 : 24;
const int alphaSize = useAlpha ? 8 : 0;
const int depthSize = useWebRender ? 24 : 0;
for (auto& cur : visualInfos) {
const auto fnConfigMatches = [&](const int pname, const int expected) {
int actual;
if (sGLXLibrary.fGetConfig(display, &cur, pname, &actual)) {
return false;
}
return actual == expected;
};
// Check if visual is compatible.
if (cur.depth != bpp ||
cur.c_class != defaultVisualInfo->c_class) {
continue;
}
// Check if visual is compatible to GL requests.
if (fnConfigMatches(LOCAL_GLX_USE_GL, 1) &&
fnConfigMatches(LOCAL_GLX_DOUBLEBUFFER, 1) &&
fnConfigMatches(LOCAL_GLX_RED_SIZE, 8) &&
fnConfigMatches(LOCAL_GLX_GREEN_SIZE, 8) &&
fnConfigMatches(LOCAL_GLX_BLUE_SIZE, 8) &&
fnConfigMatches(LOCAL_GLX_ALPHA_SIZE, alphaSize) &&
fnConfigMatches(LOCAL_GLX_DEPTH_SIZE, depthSize))
{
*out_visualId = cur.visualid;
return true;
}
}
return false;
}
bool
@ -918,9 +969,19 @@ GLContextGLX::FindFBConfigForWindow(Display* display, int screen, Window window,
GLXFBConfig* const out_config, int* const out_visid,
bool aWebRender)
{
// XXX the visual ID is almost certainly the LOCAL_GLX_FBCONFIG_ID, so
// we could probably do this first and replace the glXGetFBConfigs
// with glXChooseConfigs. Docs are sparklingly clear as always.
XWindowAttributes windowAttrs;
if (!XGetWindowAttributes(display, window, &windowAttrs)) {
NS_WARNING("[GLX] XGetWindowAttributes() failed");
return false;
}
ScopedXFree<GLXFBConfig>& cfgs = *out_scopedConfigArr;
int numConfigs;
const int webrenderAttribs[] = {
LOCAL_GLX_ALPHA_SIZE, windowAttrs.depth == 32 ? 8 : 0,
LOCAL_GLX_DEPTH_SIZE, 24,
LOCAL_GLX_DOUBLEBUFFER, True,
0
@ -943,14 +1004,6 @@ GLContextGLX::FindFBConfigForWindow(Display* display, int screen, Window window,
}
NS_ASSERTION(numConfigs > 0, "No FBConfigs found!");
// XXX the visual ID is almost certainly the LOCAL_GLX_FBCONFIG_ID, so
// we could probably do this first and replace the glXGetFBConfigs
// with glXChooseConfigs. Docs are sparklingly clear as always.
XWindowAttributes windowAttrs;
if (!XGetWindowAttributes(display, window, &windowAttrs)) {
NS_WARNING("[GLX] XGetWindowAttributes() failed");
return false;
}
const VisualID windowVisualID = XVisualIDFromVisual(windowAttrs.visual);
#ifdef DEBUG
printf("[GLX] window %lx has VisualID 0x%lx\n", window, windowVisualID);

Просмотреть файл

@ -81,6 +81,9 @@ public:
Bool fMakeCurrent(Display* display, GLXDrawable drawable, GLXContext context) const
WRAP( fMakeCurrent(display, drawable, context) )
XVisualInfo* fGetConfig(Display* display, XVisualInfo* info, int attrib, int* value) const
WRAP( fGetConfig(display, info, attrib, value) )
GLXContext fGetCurrentContext() const
WRAP( fGetCurrentContext() )
@ -179,6 +182,7 @@ private:
struct {
void (GLAPIENTRY *fDestroyContext) (Display*, GLXContext);
Bool (GLAPIENTRY *fMakeCurrent) (Display*, GLXDrawable, GLXContext);
XVisualInfo* (GLAPIENTRY *fGetConfig) (Display*, XVisualInfo*, int, int*);
GLXContext (GLAPIENTRY *fGetCurrentContext) ();
void* (GLAPIENTRY *fGetProcAddress) (const char*);
GLXFBConfig* (GLAPIENTRY *fChooseFBConfig) (Display*, int, const int*, int*);

Просмотреть файл

@ -107,9 +107,6 @@ RasterImage::~RasterImage()
// Record Telemetry.
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_COUNT, mDecodeCount);
if (mAnimationState) {
Telemetry::Accumulate(Telemetry::IMAGE_ANIMATED_DECODE_COUNT, mDecodeCount);
}
}
nsresult
@ -1512,11 +1509,6 @@ RasterImage::Draw(gfxContext* aContext,
TimeDuration drawLatency = TimeStamp::Now() - mDrawStartTime;
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_ON_DRAW_LATENCY,
int32_t(drawLatency.ToMicroseconds()));
if (mAnimationState) {
Telemetry::Accumulate(Telemetry::IMAGE_ANIMATED_DECODE_ON_DRAW_LATENCY,
int32_t(drawLatency.ToMicroseconds()));
}
mDrawStartTime = TimeStamp();
}
@ -1771,11 +1763,6 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME,
int32_t(aTelemetry.mDecodeTime.ToMicroseconds()));
if (mAnimationState) {
Telemetry::Accumulate(Telemetry::IMAGE_ANIMATED_DECODE_TIME,
int32_t(aTelemetry.mDecodeTime.ToMicroseconds()));
}
if (aTelemetry.mSpeedHistogram && aTelemetry.mBytesDecoded) {
Telemetry::Accumulate(*aTelemetry.mSpeedHistogram, aTelemetry.Speed());
}

Просмотреть файл

@ -146,6 +146,12 @@ Gecko_GetLastChild(RawGeckoNodeBorrowed aNode)
return aNode->GetLastChild();
}
RawGeckoNodeBorrowedOrNull
Gecko_GetPreviousSibling(RawGeckoNodeBorrowed aNode)
{
return aNode->GetPreviousSibling();
}
RawGeckoNodeBorrowedOrNull
Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed aNode)
{

Просмотреть файл

@ -145,6 +145,7 @@ void Gecko_Snapshot_DebugListAttributes(const ServoElementSnapshot*, nsCString*)
bool Gecko_IsSignificantChild(RawGeckoNodeBorrowed node, bool whitespace_is_significant);
RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetPreviousSibling(RawGeckoNodeBorrowed node);
RawGeckoNodeBorrowedOrNull Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed node);
RawGeckoElementBorrowedOrNull Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrowed element, bool is_before);
nsTArray<nsIContent*>* Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed element);

Просмотреть файл

@ -1996,7 +1996,7 @@ nsHttpHandler::PrefsChanged(const char *pref)
}
}
if (PREF_CHANGED(HTTP_PREF("spdy.hpack-default-buffer"))) {
if (PREF_CHANGED(HTTP_PREF("spdy.default-hpack-buffer"))) {
rv = Preferences::GetInt(HTTP_PREF("spdy.default-hpack-buffer"), &val);
if (NS_SUCCEEDED(rv)) {
mDefaultHpackBuffer = val;

Просмотреть файл

@ -30,7 +30,7 @@ use gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
use gecko::snapshot_helpers;
use gecko_bindings::bindings;
use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme};
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetNextStyleChild};
use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetPreviousSibling, Gecko_GetNextStyleChild};
use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags};
use gecko_bindings::bindings::Gecko_ClassOrClassList;
use gecko_bindings::bindings::Gecko_ElementHasAnimations;
@ -375,7 +375,11 @@ impl<'ln> TNode for GeckoNode<'ln> {
#[inline]
fn first_child(&self) -> Option<Self> {
unsafe { self.0.mFirstChild.as_ref().map(GeckoNode::from_content) }
unsafe {
self.0
.mFirstChild.raw::<nsIContent>()
.as_ref()
.map(GeckoNode::from_content) }
}
#[inline]
@ -385,17 +389,16 @@ impl<'ln> TNode for GeckoNode<'ln> {
#[inline]
fn prev_sibling(&self) -> Option<Self> {
unsafe {
self.0
.mPreviousSibling
.as_ref()
.map(GeckoNode::from_content)
}
unsafe { Gecko_GetPreviousSibling(self.0).map(GeckoNode) }
}
#[inline]
fn next_sibling(&self) -> Option<Self> {
unsafe { self.0.mNextSibling.as_ref().map(GeckoNode::from_content) }
unsafe {
self.0
.mNextSibling.raw::<nsIContent>()
.as_ref()
.map(GeckoNode::from_content) }
}
#[inline]

Просмотреть файл

@ -35,17 +35,15 @@ skip-if = appname == "thunderbird" || os == "android" # Containers are not expos
[test_ext_debugging_utils.js]
[test_ext_dns.js]
[test_ext_downloads.js]
skip-if = appname == "thunderbird"
[test_ext_downloads_download.js]
fail-if = appname == "thunderbird"
skip-if = os == "android"
skip-if = appname == "thunderbird" || os == "android"
[test_ext_downloads_misc.js]
fail-if = appname == "thunderbird"
skip-if = os == "android" || (os=='linux' && bits==32) # linux32: bug 1324870
skip-if = appname == "thunderbird" || os == "android" || (os=='linux' && bits==32) # linux32: bug 1324870
[test_ext_downloads_private.js]
skip-if = appname == "thunderbird" || os == "android"
[test_ext_downloads_search.js]
fail-if = appname == "thunderbird"
skip-if = os == "android"
skip-if = appname == "thunderbird" || os == "android"
[test_ext_error_location.js]
[test_ext_eventpage_warning.js]
[test_ext_experiments.js]

Просмотреть файл

@ -1236,17 +1236,6 @@
"n_buckets": 100,
"description": "Time spent decoding an image (us)"
},
"IMAGE_ANIMATED_DECODE_TIME": {
"record_in_processes": ["main", "content"],
"alert_emails": ["gfx-telemetry-alerts@mozilla.com"],
"bug_numbers": [1347302],
"expires_in_version": "57",
"kind": "exponential",
"low": 50,
"high": 50000000,
"n_buckets": 100,
"description": "Time spent decoding an animated image (us)"
},
"IMAGE_DECODE_ON_DRAW_LATENCY": {
"record_in_processes": ["main", "content"],
"alert_emails": ["gfx-telemetry-alerts@mozilla.com"],
@ -1257,17 +1246,6 @@
"n_buckets": 100,
"description": "Time from starting a decode to it showing up on the screen (us)"
},
"IMAGE_ANIMATED_DECODE_ON_DRAW_LATENCY": {
"record_in_processes": ["main", "content"],
"alert_emails": ["gfx-telemetry-alerts@mozilla.com"],
"bug_numbers": [1347302],
"expires_in_version": "57",
"kind": "exponential",
"low": 50,
"high": 50000000,
"n_buckets": 100,
"description": "Time from starting a decode of an animated image to it showing up on the screen (us)"
},
"IMAGE_DECODE_CHUNKS": {
"record_in_processes": ["main", "content"],
"alert_emails": ["gfx-telemetry-alerts@mozilla.com"],
@ -1286,16 +1264,6 @@
"n_buckets": 50,
"description": "Decode count"
},
"IMAGE_ANIMATED_DECODE_COUNT": {
"record_in_processes": ["main", "content"],
"alert_emails": ["gfx-telemetry-alerts@mozilla.com"],
"bug_numbers": [1347302],
"expires_in_version": "57",
"kind": "exponential",
"high": 500,
"n_buckets": 50,
"description": "Decode count of animated images"
},
"IMAGE_DECODE_SPEED_JPEG": {
"record_in_processes": ["main", "content"],
"alert_emails": ["gfx-telemetry-alerts@mozilla.com"],