зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland
This commit is contained in:
Коммит
c8d3fc41b5
|
@ -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"],
|
||||
|
|
Загрузка…
Ссылка в новой задаче