Bug 358106: Make ranges use nsIMutationObserver rather than their own notification system. r/sr=jst

git-svn-id: svn://10.0.0.236/trunk@214666 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
cvshook%sicking.cc
2006-11-03 21:51:01 +00:00
parent de00af7251
commit 78a449be36
24 changed files with 243 additions and 791 deletions

View File

@@ -186,33 +186,8 @@ nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
PRBool nsContentUtils::sInitialized = PR_FALSE;
static PLDHashTable sRangeListsHash;
static PLDHashTable sEventListenerManagersHash;
class RangeListMapEntry : public PLDHashEntryHdr
{
public:
RangeListMapEntry(const void *aKey)
: mKey(aKey), mRangeList(nsnull)
{
}
~RangeListMapEntry()
{
delete mRangeList;
}
private:
const void *mKey; // must be first to look like PLDHashEntryStub
public:
// We want mRangeList to be an nsAutoVoidArray but we can't make an
// nsAutoVoidArray a direct member of RangeListMapEntry since it
// will be moved around in memory, and nsAutoVoidArray can't deal
// with that.
nsVoidArray *mRangeList;
};
class EventListenerManagerMapEntry : public PLDHashEntryHdr
{
public:
@@ -233,24 +208,6 @@ public:
nsCOMPtr<nsIEventListenerManager> mListenerManager;
};
PR_STATIC_CALLBACK(PRBool)
RangeListHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
// Initialize the entry with placement new
new (entry) RangeListMapEntry(key);
return PR_TRUE;
}
PR_STATIC_CALLBACK(void)
RangeListHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
RangeListMapEntry *r = NS_STATIC_CAST(RangeListMapEntry *, entry);
// Let the RangeListMapEntry clean itself up...
r->~RangeListMapEntry();
}
PR_STATIC_CALLBACK(PRBool)
EventListenerManagerHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
@@ -330,28 +287,6 @@ nsContentUtils::Init()
return NS_ERROR_OUT_OF_MEMORY;
}
if (!sRangeListsHash.ops) {
static PLDHashTableOps hash_table_ops =
{
PL_DHashAllocTable,
PL_DHashFreeTable,
PL_DHashGetKeyStub,
PL_DHashVoidPtrKeyStub,
PL_DHashMatchEntryStub,
PL_DHashMoveEntryStub,
RangeListHashClearEntry,
PL_DHashFinalizeStub,
RangeListHashInitEntry
};
if (!PL_DHashTableInit(&sRangeListsHash, &hash_table_ops, nsnull,
sizeof(RangeListMapEntry), 16)) {
sRangeListsHash.ops = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
}
if (!sEventListenerManagersHash.ops) {
static PLDHashTableOps hash_table_ops =
{
@@ -370,9 +305,6 @@ nsContentUtils::Init()
nsnull, sizeof(EventListenerManagerMapEntry), 16)) {
sEventListenerManagersHash.ops = nsnull;
PL_DHashTableFinish(&sRangeListsHash);
sRangeListsHash.ops = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
}
@@ -644,33 +576,6 @@ nsContentUtils::Shutdown()
sPtrsToPtrsToRelease = nsnull;
}
if (sRangeListsHash.ops) {
NS_ASSERTION(sRangeListsHash.entryCount == 0,
"Range list hash not empty at shutdown!");
// We're already being shut down and if there are entries left in
// this hash at this point it means we leaked nsGenericElements or
// nsGenericDOMDataNodes. Since we're already partly through the
// shutdown process it's too late to release what's held on to by
// this hash (since the teardown code relies on some things being
// around that aren't around any more) so we rather leak what's
// already leaked in stead of crashing trying to release what
// should've been released much earlier on.
// Copy the ops out of the hash table
PLDHashTableOps hash_table_ops = *sRangeListsHash.ops;
// Set the clearEntry hook to be a nop
hash_table_ops.clearEntry = NopClearEntry;
// Set the ops in the hash table to be the new ops
sRangeListsHash.ops = &hash_table_ops;
PL_DHashTableFinish(&sRangeListsHash);
sRangeListsHash.ops = nsnull;
}
if (sEventListenerManagersHash.ops) {
NS_ASSERTION(sEventListenerManagersHash.entryCount == 0,
"Event listener manager hash not empty at shutdown!");
@@ -3099,127 +3004,6 @@ nsContentUtils::RemoveListenerManager(nsINode *aNode)
}
}
/* static */
nsresult
nsContentUtils::AddToRangeList(nsINode *aNode, nsIRange *aRange,
PRBool *aCreated)
{
*aCreated = PR_FALSE;
if (!sRangeListsHash.ops) {
// We've already been shut down, don't bother adding a range...
return NS_OK;
}
RangeListMapEntry *entry =
NS_STATIC_CAST(RangeListMapEntry *,
PL_DHashTableOperate(&sRangeListsHash, aNode,
PL_DHASH_ADD));
if (!entry) {
return NS_ERROR_OUT_OF_MEMORY;
}
// lazy allocation of range list
if (!entry->mRangeList) {
entry->mRangeList = new nsAutoVoidArray();
if (!entry->mRangeList) {
PL_DHashTableRawRemove(&sRangeListsHash, entry);
return NS_ERROR_OUT_OF_MEMORY;
}
*aCreated = PR_TRUE;
}
else {
// Make sure we don't add a range that is already in the list!
PRInt32 i = entry->mRangeList->IndexOf(aRange);
if (i >= 0) {
// Range is already in the list, so there is nothing to do!
return NS_OK;
}
}
// dont need to addref - this call is made by the range object
// itself
PRBool rv = entry->mRangeList->AppendElement(aRange);
if (!rv) {
if (entry->mRangeList->Count() == 0) {
// Fresh entry, remove it from the hash...
PL_DHashTableRawRemove(&sRangeListsHash, entry);
}
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
/* static */
PRBool
nsContentUtils::RemoveFromRangeList(nsINode *aNode, nsIRange *aRange)
{
if (!sRangeListsHash.ops) {
// We've already been shut down, don't bother removing a range...
return PR_FALSE;
}
RangeListMapEntry *entry =
NS_STATIC_CAST(RangeListMapEntry *,
PL_DHashTableOperate(&sRangeListsHash, aNode,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
return PR_FALSE;
}
NS_ASSERTION(entry->mRangeList, "In the hash but without an object?");
// dont need to release - this call is made by the range object itself
entry->mRangeList->RemoveElement(aRange);
if (entry->mRangeList->Count() != 0) {
return PR_FALSE;
}
PL_DHashTableRawRemove(&sRangeListsHash, entry);
return PR_TRUE;
}
/* static */
const nsVoidArray*
nsContentUtils::LookupRangeList(const nsINode *aNode)
{
if (!sRangeListsHash.ops) {
// We've already been shut down, don't bother getting a range list...
return nsnull;
}
RangeListMapEntry *entry =
NS_STATIC_CAST(RangeListMapEntry *,
PL_DHashTableOperate(&sRangeListsHash, aNode,
PL_DHASH_LOOKUP));
return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry->mRangeList : nsnull;
}
/* static */
void
nsContentUtils::RemoveRangeList(nsINode *aNode)
{
if (sRangeListsHash.ops) {
PL_DHashTableOperate(&sRangeListsHash, aNode, PL_DHASH_REMOVE);
}
}
/* static */
PRBool
nsContentUtils::IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix,