mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-02-20 20:29:15 +00:00
#387: pulled nsGenConList.* with relevant deps up to mozilla-central
This commit is contained in:
parent
922a327382
commit
b1831fc750
@ -186,11 +186,7 @@ nsCounterList::RecalcAll()
|
|||||||
{
|
{
|
||||||
mDirty = false;
|
mDirty = false;
|
||||||
|
|
||||||
nsCounterNode *node = First();
|
for (nsCounterNode* node = First(); node; node = Next(node)) {
|
||||||
if (!node)
|
|
||||||
return;
|
|
||||||
|
|
||||||
do {
|
|
||||||
SetScope(node);
|
SetScope(node);
|
||||||
node->Calc(this);
|
node->Calc(this);
|
||||||
|
|
||||||
@ -205,7 +201,7 @@ nsCounterList::RecalcAll()
|
|||||||
useNode->mText->SetData(text);
|
useNode->mText->SetData(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((node = Next(node)) != First());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCounterManager::nsCounterManager()
|
nsCounterManager::nsCounterManager()
|
||||||
@ -291,21 +287,17 @@ nsCounterManager::SetAllCounterStylesDirty()
|
|||||||
{
|
{
|
||||||
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
|
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
|
||||||
nsCounterList* list = iter.UserData();
|
nsCounterList* list = iter.UserData();
|
||||||
nsCounterNode* first = list->First();
|
bool changed = false;
|
||||||
if (first) {
|
for (nsCounterNode* node = list->First(); node; node = list->Next(node)) {
|
||||||
bool changed = false;
|
if (node->mType == nsCounterNode::USE) {
|
||||||
nsCounterNode* node = first;
|
node->UseNode()->SetCounterStyleDirty();
|
||||||
do {
|
changed = true;
|
||||||
if (node->mType == nsCounterNode::USE) {
|
|
||||||
node->UseNode()->SetCounterStyleDirty();
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
} while ((node = list->Next(node)) != first);
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
list->SetDirty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
list->SetDirty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,32 +319,29 @@ nsCounterManager::DestroyNodesFor(nsIFrame *aFrame)
|
|||||||
void
|
void
|
||||||
nsCounterManager::Dump()
|
nsCounterManager::Dump()
|
||||||
{
|
{
|
||||||
printf("\n\nCounter Manager Lists:\n");
|
printf("\n\nCounter Manager Lists:\n");
|
||||||
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
|
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
|
||||||
printf("Counter named \"%s\":\n",
|
printf("Counter named \"%s\":\n",
|
||||||
NS_ConvertUTF16toUTF8(iter.Key()).get());
|
NS_ConvertUTF16toUTF8(iter.Key()).get());
|
||||||
|
|
||||||
nsCounterList* list = iter.UserData();
|
nsCounterList* list = iter.UserData();
|
||||||
nsCounterNode* node = list->First();
|
int32_t i = 0;
|
||||||
if (node) {
|
for (nsCounterNode* node = list->First(); node; node = list->Next(node)) {
|
||||||
int32_t i = 0;
|
const char* types[] = { "RESET", "INCREMENT", "USE" };
|
||||||
do {
|
printf(" Node #%d @%p frame=%p index=%d type=%s valAfter=%d\n"
|
||||||
const char* types[] = { "RESET", "INCREMENT", "USE" };
|
" scope-start=%p scope-prev=%p",
|
||||||
printf(" Node #%d @%p frame=%p index=%d type=%s valAfter=%d\n"
|
i++, (void*)node, (void*)node->mPseudoFrame,
|
||||||
" scope-start=%p scope-prev=%p",
|
node->mContentIndex, types[node->mType],
|
||||||
i++, (void*)node, (void*)node->mPseudoFrame,
|
node->mValueAfter, (void*)node->mScopeStart,
|
||||||
node->mContentIndex, types[node->mType],
|
(void*)node->mScopePrev);
|
||||||
node->mValueAfter, (void*)node->mScopeStart,
|
if (node->mType == nsCounterNode::USE) {
|
||||||
(void*)node->mScopePrev);
|
nsAutoString text;
|
||||||
if (node->mType == nsCounterNode::USE) {
|
node->UseNode()->GetText(text);
|
||||||
nsAutoString text;
|
printf(" text=%s", NS_ConvertUTF16toUTF8(text).get());
|
||||||
node->UseNode()->GetText(text);
|
}
|
||||||
printf(" text=%s", NS_ConvertUTF16toUTF8(text).get());
|
printf("\n");
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
} while ((node = list->Next(node)) != list->First());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
printf("\n\n");
|
}
|
||||||
|
printf("\n\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -187,7 +187,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsCounterNode* First() {
|
nsCounterNode* First() {
|
||||||
return static_cast<nsCounterNode*>(mFirstNode);
|
return static_cast<nsCounterNode*>(mList.getFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsCounterNode* Next(nsCounterNode* aNode) {
|
static nsCounterNode* Next(nsCounterNode* aNode) {
|
||||||
|
@ -13,55 +13,39 @@
|
|||||||
void
|
void
|
||||||
nsGenConList::Clear()
|
nsGenConList::Clear()
|
||||||
{
|
{
|
||||||
//Delete entire list
|
// Delete entire list.
|
||||||
if (!mFirstNode)
|
mNodes.Clear();
|
||||||
return;
|
while (nsGenConNode* node = mList.popFirst()) {
|
||||||
for (nsGenConNode *node = Next(mFirstNode); node != mFirstNode;
|
|
||||||
node = Next(mFirstNode))
|
|
||||||
{
|
|
||||||
Remove(node);
|
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
delete mFirstNode;
|
|
||||||
|
|
||||||
mFirstNode = nullptr;
|
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
|
mLastInserted = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsGenConList::DestroyNodesFor(nsIFrame* aFrame)
|
nsGenConList::DestroyNodesFor(nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
if (!mFirstNode)
|
// This algorithm relies on the invariant that nodes of a frame are
|
||||||
return false; // list empty
|
// put contiguously in the linked list. This is guaranteed because
|
||||||
nsGenConNode* node;
|
// each frame is mapped to only one (nsIContent, pseudoType) pair,
|
||||||
bool destroyed = false;
|
// and the nodes in the linked list are put in the tree order based
|
||||||
while (mFirstNode->mPseudoFrame == aFrame) {
|
// on that pair and offset inside frame.
|
||||||
destroyed = true;
|
nsGenConNode* node = mNodes.GetAndRemove(aFrame).valueOr(nullptr);
|
||||||
node = Next(mFirstNode);
|
if (!node) {
|
||||||
bool isLastNode = node == mFirstNode; // before they're dangling
|
return false;
|
||||||
Remove(mFirstNode);
|
|
||||||
delete mFirstNode;
|
|
||||||
if (isLastNode) {
|
|
||||||
mFirstNode = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mFirstNode = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
node = Next(mFirstNode);
|
MOZ_ASSERT(node->mPseudoFrame == aFrame);
|
||||||
while (node != mFirstNode) {
|
|
||||||
if (node->mPseudoFrame == aFrame) {
|
while (node && node->mPseudoFrame == aFrame) {
|
||||||
destroyed = true;
|
nsGenConNode* nextNode = Next(node);
|
||||||
nsGenConNode *nextNode = Next(node);
|
Destroy(node);
|
||||||
Remove(node);
|
node = nextNode;
|
||||||
delete node;
|
|
||||||
node = nextNode;
|
|
||||||
} else {
|
|
||||||
node = Next(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return destroyed;
|
|
||||||
|
// Modification of the list invalidates the cached pointer.
|
||||||
|
mLastInserted = nullptr;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,62 +102,101 @@ nsGenConList::NodeAfter(const nsGenConNode* aNode1, const nsGenConNode* aNode2)
|
|||||||
// XXX Switch to the frame version of DoCompareTreePosition?
|
// XXX Switch to the frame version of DoCompareTreePosition?
|
||||||
int32_t cmp = nsLayoutUtils::DoCompareTreePosition(content1, content2,
|
int32_t cmp = nsLayoutUtils::DoCompareTreePosition(content1, content2,
|
||||||
pseudoType1, -pseudoType2);
|
pseudoType1, -pseudoType2);
|
||||||
NS_ASSERTION(cmp != 0, "same content, different frames");
|
MOZ_ASSERT(cmp != 0, "same content, different frames");
|
||||||
return cmp > 0;
|
return cmp > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsGenConList::Insert(nsGenConNode* aNode)
|
nsGenConList::Insert(nsGenConNode* aNode)
|
||||||
{
|
{
|
||||||
if (mFirstNode) {
|
// Check for append.
|
||||||
// Check for append.
|
if (mList.isEmpty() || NodeAfter(aNode, mList.getLast())) {
|
||||||
if (NodeAfter(aNode, Prev(mFirstNode))) {
|
mList.insertBack(aNode);
|
||||||
PR_INSERT_BEFORE(aNode, mFirstNode);
|
} else if (mLastInserted && mLastInserted != mList.getLast() &&
|
||||||
}
|
NodeAfter(aNode, mLastInserted) &&
|
||||||
else {
|
NodeAfter(Next(mLastInserted), aNode)) {
|
||||||
// Binary search.
|
// Fast path for inserting many consecutive nodes in one place
|
||||||
|
mLastInserted->setNext(aNode);
|
||||||
|
} else {
|
||||||
|
// Binary search.
|
||||||
|
|
||||||
// the range of indices at which |aNode| could end up.
|
// the range of indices at which |aNode| could end up.
|
||||||
// (We already know it can't be at index mSize.)
|
// (We already know it can't be at index mSize.)
|
||||||
uint32_t first = 0, last = mSize - 1;
|
uint32_t first = 0, last = mSize - 1;
|
||||||
|
|
||||||
// A cursor to avoid walking more than the length of the list.
|
// A cursor to avoid walking more than the length of the list.
|
||||||
nsGenConNode *curNode = Prev(mFirstNode);
|
nsGenConNode* curNode = mList.getLast();
|
||||||
uint32_t curIndex = mSize - 1;
|
uint32_t curIndex = mSize - 1;
|
||||||
|
|
||||||
while (first != last) {
|
while (first != last) {
|
||||||
uint32_t test = (first + last) / 2;
|
uint32_t test = (first + last) / 2;
|
||||||
if (last == curIndex) {
|
if (last == curIndex) {
|
||||||
for ( ; curIndex != test; --curIndex)
|
for ( ; curIndex != test; --curIndex)
|
||||||
curNode = Prev(curNode);
|
curNode = Prev(curNode);
|
||||||
} else {
|
} else {
|
||||||
for ( ; curIndex != test; ++curIndex)
|
for ( ; curIndex != test; ++curIndex)
|
||||||
curNode = Next(curNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NodeAfter(aNode, curNode)) {
|
|
||||||
first = test + 1;
|
|
||||||
// if we exit the loop, we need curNode to be right
|
|
||||||
++curIndex;
|
|
||||||
curNode = Next(curNode);
|
curNode = Next(curNode);
|
||||||
} else {
|
|
||||||
last = test;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PR_INSERT_BEFORE(aNode, curNode);
|
|
||||||
if (curNode == mFirstNode) {
|
if (NodeAfter(aNode, curNode)) {
|
||||||
mFirstNode = aNode;
|
first = test + 1;
|
||||||
|
// if we exit the loop, we need curNode to be right
|
||||||
|
++curIndex;
|
||||||
|
curNode = Next(curNode);
|
||||||
|
} else {
|
||||||
|
last = test;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
curNode->setPrevious(aNode);
|
||||||
else {
|
|
||||||
// initialize list with first node
|
|
||||||
PR_INIT_CLIST(aNode);
|
|
||||||
mFirstNode = aNode;
|
|
||||||
}
|
}
|
||||||
++mSize;
|
++mSize;
|
||||||
|
|
||||||
NS_ASSERTION(aNode == mFirstNode || NodeAfter(aNode, Prev(aNode)),
|
mLastInserted = aNode;
|
||||||
|
|
||||||
|
// Set the mapping only if it is the first node of the frame.
|
||||||
|
// The DEBUG blocks below are for ensuring the invariant required by
|
||||||
|
// nsGenConList::DestroyNodesFor. See comment there.
|
||||||
|
if (IsFirst(aNode) ||
|
||||||
|
Prev(aNode)->mPseudoFrame != aNode->mPseudoFrame) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (nsGenConNode* oldFrameFirstNode = mNodes.Get(aNode->mPseudoFrame)) {
|
||||||
|
MOZ_ASSERT(Next(aNode) == oldFrameFirstNode,
|
||||||
|
"oldFrameFirstNode should now be immediately after "
|
||||||
|
"the newly-inserted one.");
|
||||||
|
} else {
|
||||||
|
// If the node is not the only node in the list.
|
||||||
|
if (!IsFirst(aNode) || !IsLast(aNode)) {
|
||||||
|
nsGenConNode* nextNode = Next(aNode);
|
||||||
|
MOZ_ASSERT(!nextNode || nextNode->mPseudoFrame != aNode->mPseudoFrame,
|
||||||
|
"There shouldn't exist any node for this frame.");
|
||||||
|
// If the node is neither the first nor the last node
|
||||||
|
if (!IsFirst(aNode) && !IsLast(aNode)) {
|
||||||
|
MOZ_ASSERT(Prev(aNode)->mPseudoFrame != nextNode->mPseudoFrame,
|
||||||
|
"New node should not break contiguity of nodes of "
|
||||||
|
"the same frame.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
mNodes.Put(aNode->mPseudoFrame, aNode);
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
nsGenConNode* frameFirstNode = mNodes.Get(aNode->mPseudoFrame);
|
||||||
|
MOZ_ASSERT(frameFirstNode, "There should exist node map for the frame.");
|
||||||
|
for (nsGenConNode* curNode = Prev(aNode);
|
||||||
|
curNode != frameFirstNode; curNode = Prev(curNode)) {
|
||||||
|
MOZ_ASSERT(curNode->mPseudoFrame == aNode->mPseudoFrame,
|
||||||
|
"Every node between frameFirstNode and the new node inserted "
|
||||||
|
"should refer to the same frame.");
|
||||||
|
MOZ_ASSERT(!IsFirst(curNode),
|
||||||
|
"The newly-inserted node should be in a contiguous run after "
|
||||||
|
"frameFirstNode, thus frameFirstNode should be reached before "
|
||||||
|
"the first node of mList.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(IsFirst(aNode) || NodeAfter(aNode, Prev(aNode)),
|
||||||
"sorting error");
|
"sorting error");
|
||||||
NS_ASSERTION(IsLast(aNode) || NodeAfter(Next(aNode), aNode),
|
NS_ASSERTION(IsLast(aNode) || NodeAfter(Next(aNode), aNode),
|
||||||
"sorting error");
|
"sorting error");
|
||||||
|
@ -8,15 +8,15 @@
|
|||||||
#ifndef nsGenConList_h___
|
#ifndef nsGenConList_h___
|
||||||
#define nsGenConList_h___
|
#define nsGenConList_h___
|
||||||
|
|
||||||
|
#include "mozilla/LinkedList.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsStyleStruct.h"
|
#include "nsStyleStruct.h"
|
||||||
#include "prclist.h"
|
|
||||||
#include "nsCSSPseudoElements.h"
|
#include "nsCSSPseudoElements.h"
|
||||||
#include "nsTextNode.h"
|
#include "nsTextNode.h"
|
||||||
|
|
||||||
class nsGenConList;
|
class nsGenConList;
|
||||||
|
|
||||||
struct nsGenConNode : public PRCList {
|
struct nsGenConNode : public mozilla::LinkedListElement<nsGenConNode> {
|
||||||
// The wrapper frame for all of the pseudo-element's content. This
|
// The wrapper frame for all of the pseudo-element's content. This
|
||||||
// frame generally has useful style data and has the
|
// frame generally has useful style data and has the
|
||||||
// NS_FRAME_GENERATED_CONTENT bit set (so we use it to track removal),
|
// NS_FRAME_GENERATED_CONTENT bit set (so we use it to track removal),
|
||||||
@ -51,7 +51,7 @@ struct nsGenConNode : public PRCList {
|
|||||||
* @return true iff this marked the list dirty
|
* @return true iff this marked the list dirty
|
||||||
*/
|
*/
|
||||||
virtual bool InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame,
|
virtual bool InitTextFrame(nsGenConList* aList, nsIFrame* aPseudoFrame,
|
||||||
nsIFrame* aTextFrame)
|
nsIFrame* aTextFrame)
|
||||||
{
|
{
|
||||||
mPseudoFrame = aPseudoFrame;
|
mPseudoFrame = aPseudoFrame;
|
||||||
CheckFrameAssertions();
|
CheckFrameAssertions();
|
||||||
@ -82,28 +82,55 @@ protected:
|
|||||||
|
|
||||||
class nsGenConList {
|
class nsGenConList {
|
||||||
protected:
|
protected:
|
||||||
nsGenConNode* mFirstNode;
|
mozilla::LinkedList<nsGenConNode> mList;
|
||||||
uint32_t mSize;
|
uint32_t mSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsGenConList() : mFirstNode(nullptr), mSize(0) {}
|
nsGenConList() : mSize(0), mLastInserted(nullptr) {}
|
||||||
~nsGenConList() { Clear(); }
|
~nsGenConList() { Clear(); }
|
||||||
void Clear();
|
void Clear();
|
||||||
static nsGenConNode* Next(nsGenConNode* aNode) {
|
static nsGenConNode* Next(nsGenConNode* aNode) {
|
||||||
return static_cast<nsGenConNode*>(PR_NEXT_LINK(aNode));
|
MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
|
||||||
|
return aNode->getNext();
|
||||||
}
|
}
|
||||||
static nsGenConNode* Prev(nsGenConNode* aNode) {
|
static nsGenConNode* Prev(nsGenConNode* aNode) {
|
||||||
return static_cast<nsGenConNode*>(PR_PREV_LINK(aNode));
|
MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
|
||||||
|
return aNode->getPrevious();
|
||||||
}
|
}
|
||||||
void Insert(nsGenConNode* aNode);
|
void Insert(nsGenConNode* aNode);
|
||||||
// returns whether any nodes have been destroyed
|
|
||||||
bool DestroyNodesFor(nsIFrame* aFrame); //destroy all nodes with aFrame as parent
|
// Destroy all nodes with aFrame as parent. Returns true if some nodes
|
||||||
|
// have been destroyed; otherwise false.
|
||||||
|
bool DestroyNodesFor(nsIFrame* aFrame);
|
||||||
|
|
||||||
// Return true if |aNode1| is after |aNode2|.
|
// Return true if |aNode1| is after |aNode2|.
|
||||||
static bool NodeAfter(const nsGenConNode* aNode1,
|
static bool NodeAfter(const nsGenConNode* aNode1,
|
||||||
const nsGenConNode* aNode2);
|
const nsGenConNode* aNode2);
|
||||||
|
|
||||||
void Remove(nsGenConNode* aNode) { PR_REMOVE_LINK(aNode); mSize--; }
|
bool IsFirst(nsGenConNode* aNode) {
|
||||||
bool IsLast(nsGenConNode* aNode) { return (Next(aNode) == mFirstNode); }
|
MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
|
||||||
|
return aNode == mList.getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLast(nsGenConNode* aNode) {
|
||||||
|
MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
|
||||||
|
return aNode == mList.getLast();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Destroy(nsGenConNode* aNode)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aNode, "aNode cannot be nullptr!");
|
||||||
|
delete aNode;
|
||||||
|
mSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map from frame to the first nsGenConNode of it in the list.
|
||||||
|
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsGenConNode*> mNodes;
|
||||||
|
|
||||||
|
// A weak pointer to the node most recently inserted, used to avoid repeated
|
||||||
|
// list traversals in Insert().
|
||||||
|
nsGenConNode* mLastInserted;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsGenConList_h___ */
|
#endif /* nsGenConList_h___ */
|
||||||
|
@ -73,20 +73,13 @@ nsQuoteList::Calc(nsQuoteNode* aNode)
|
|||||||
void
|
void
|
||||||
nsQuoteList::RecalcAll()
|
nsQuoteList::RecalcAll()
|
||||||
{
|
{
|
||||||
nsQuoteNode *node = FirstNode();
|
for (nsQuoteNode* node = FirstNode(); node; node = Next(node)) {
|
||||||
if (!node)
|
|
||||||
return;
|
|
||||||
|
|
||||||
do {
|
|
||||||
int32_t oldDepth = node->mDepthBefore;
|
int32_t oldDepth = node->mDepthBefore;
|
||||||
Calc(node);
|
Calc(node);
|
||||||
|
|
||||||
if (node->mDepthBefore != oldDepth && node->mText && node->IsRealQuote())
|
if (node->mDepthBefore != oldDepth && node->mText && node->IsRealQuote())
|
||||||
node->mText->SetData(*node->Text());
|
node->mText->SetData(*node->Text());
|
||||||
|
}
|
||||||
// Next node
|
|
||||||
node = Next(node);
|
|
||||||
} while (node != FirstNode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -94,11 +87,7 @@ void
|
|||||||
nsQuoteList::PrintChain()
|
nsQuoteList::PrintChain()
|
||||||
{
|
{
|
||||||
printf("Chain: \n");
|
printf("Chain: \n");
|
||||||
if (!FirstNode()) {
|
for (nsQuoteNode* node = FirstNode(); node; node = Next(node)) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
nsQuoteNode* node = FirstNode();
|
|
||||||
do {
|
|
||||||
printf(" %p %d - ", static_cast<void*>(node), node->mDepthBefore);
|
printf(" %p %d - ", static_cast<void*>(node), node->mDepthBefore);
|
||||||
switch(node->mType) {
|
switch(node->mType) {
|
||||||
case (eStyleContentType_OpenQuote):
|
case (eStyleContentType_OpenQuote):
|
||||||
@ -123,7 +112,6 @@ nsQuoteList::PrintChain()
|
|||||||
printf(" \"%s\",", NS_ConvertUTF16toUTF8(data).get());
|
printf(" \"%s\",", NS_ConvertUTF16toUTF8(data).get());
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
node = Next(node);
|
}
|
||||||
} while (node != FirstNode());
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,7 +70,7 @@ struct nsQuoteNode : public nsGenConNode {
|
|||||||
|
|
||||||
class nsQuoteList : public nsGenConList {
|
class nsQuoteList : public nsGenConList {
|
||||||
private:
|
private:
|
||||||
nsQuoteNode* FirstNode() { return static_cast<nsQuoteNode*>(mFirstNode); }
|
nsQuoteNode* FirstNode() { return static_cast<nsQuoteNode*>(mList.getFirst()); }
|
||||||
public:
|
public:
|
||||||
// assign the correct |mDepthBefore| value to a node that has been inserted
|
// assign the correct |mDepthBefore| value to a node that has been inserted
|
||||||
// Should be called immediately after calling |Insert|.
|
// Should be called immediately after calling |Insert|.
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsBaseHashtable.h"
|
#include "nsBaseHashtable.h"
|
||||||
|
#include "mozilla/Maybe.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* templated hashtable class maps keys to simple datatypes.
|
* templated hashtable class maps keys to simple datatypes.
|
||||||
@ -22,12 +23,36 @@ template<class KeyClass, class DataType>
|
|||||||
class nsDataHashtable
|
class nsDataHashtable
|
||||||
: public nsBaseHashtable<KeyClass, DataType, DataType>
|
: public nsBaseHashtable<KeyClass, DataType, DataType>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
typedef nsBaseHashtable<KeyClass, DataType, DataType> BaseClass;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using typename BaseClass::KeyType;
|
||||||
|
using typename BaseClass::EntryType;
|
||||||
|
|
||||||
nsDataHashtable() {}
|
nsDataHashtable() {}
|
||||||
explicit nsDataHashtable(uint32_t aInitLength)
|
explicit nsDataHashtable(uint32_t aInitLength)
|
||||||
: nsBaseHashtable<KeyClass, DataType, DataType>(aInitLength)
|
: BaseClass(aInitLength)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the value for a key and remove the corresponding entry at
|
||||||
|
* the same time.
|
||||||
|
*
|
||||||
|
* @param aKey the key to retrieve and remove
|
||||||
|
* @return the found value, or Nothing if no entry was found with the
|
||||||
|
* given key.
|
||||||
|
*/
|
||||||
|
mozilla::Maybe<DataType> GetAndRemove(KeyType aKey)
|
||||||
|
{
|
||||||
|
mozilla::Maybe<DataType> value;
|
||||||
|
if (EntryType* ent = this->GetEntry(aKey)) {
|
||||||
|
value.emplace(mozilla::Move(ent->mData));
|
||||||
|
this->RemoveEntry(ent);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsDataHashtable_h__
|
#endif // nsDataHashtable_h__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user