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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user