summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/Document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/dom/Document.cpp')
-rw-r--r--Source/WebCore/dom/Document.cpp41
1 files changed, 23 insertions, 18 deletions
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index ab48ca382..3fa6b41ab 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -127,6 +127,7 @@
#include "PointerLockController.h"
#include "PopStateEvent.h"
#include "ProcessingInstruction.h"
+#include "QualifiedName.h"
#include "RegisteredEventListener.h"
#include "RenderArena.h"
#include "RenderNamedFlowThread.h"
@@ -5768,6 +5769,10 @@ void Document::setFullScreenRendererBackgroundColor(Color backgroundColor)
void Document::fullScreenChangeDelayTimerFired(Timer<Document>*)
{
+ // Since we dispatch events in this function, it's possible that the
+ // document will be detached and GC'd. We protect it here to make sure we
+ // can finish the function successfully.
+ RefPtr<Document> protectDocument(this);
Deque<RefPtr<Node> > changeQueue;
m_fullScreenChangeEventTargetQueue.swap(changeQueue);
@@ -5775,6 +5780,9 @@ void Document::fullScreenChangeDelayTimerFired(Timer<Document>*)
RefPtr<Node> node = changeQueue.takeFirst();
if (!node)
node = documentElement();
+ // The dispatchEvent below may have blown away our documentElement.
+ if (!node)
+ continue;
// If the element was removed from our tree, also message the documentElement. Since we may
// have a document hierarchy, check that node isn't in another document.
@@ -5791,6 +5799,9 @@ void Document::fullScreenChangeDelayTimerFired(Timer<Document>*)
RefPtr<Node> node = errorQueue.takeFirst();
if (!node)
node = documentElement();
+ // The dispatchEvent below may have blown away our documentElement.
+ if (!node)
+ continue;
// If the element was removed from our tree, also message the documentElement. Since we may
// have a document hierarchy, check that node isn't in another document.
@@ -6304,23 +6315,16 @@ PassRefPtr<UndoManager> Document::undoManager()
#endif
class ImmutableAttributeDataCacheKey {
- WTF_MAKE_FAST_ALLOCATED;
public:
- ImmutableAttributeDataCacheKey()
- : m_localName(0)
- , m_attributes(0)
- , m_attributeCount(0)
- { }
-
- ImmutableAttributeDataCacheKey(const AtomicString& localName, const Attribute* attributes, unsigned attributeCount)
- : m_localName(localName.impl())
+ ImmutableAttributeDataCacheKey(const QualifiedName& tagName, const Attribute* attributes, unsigned attributeCount)
+ : m_tagQName(tagName)
, m_attributes(attributes)
, m_attributeCount(attributeCount)
{ }
bool operator!=(const ImmutableAttributeDataCacheKey& other) const
{
- if (m_localName != other.m_localName)
+ if (m_tagQName != other.m_tagQName)
return true;
if (m_attributeCount != other.m_attributeCount)
return true;
@@ -6330,16 +6334,21 @@ public:
unsigned hash() const
{
unsigned attributeHash = StringHasher::hashMemory(m_attributes, m_attributeCount * sizeof(Attribute));
- return WTF::pairIntHash(m_localName->existingHash(), attributeHash);
+ return WTF::pairIntHash(m_tagQName.localName().impl()->existingHash(), attributeHash);
}
private:
- AtomicStringImpl* m_localName;
+ QualifiedName m_tagQName;
const Attribute* m_attributes;
unsigned m_attributeCount;
};
struct ImmutableAttributeDataCacheEntry {
+ ImmutableAttributeDataCacheEntry(const ImmutableAttributeDataCacheKey& k, PassRefPtr<ElementAttributeData> v)
+ : key(k)
+ , value(v)
+ { }
+
ImmutableAttributeDataCacheKey key;
RefPtr<ElementAttributeData> value;
};
@@ -6348,7 +6357,7 @@ PassRefPtr<ElementAttributeData> Document::cachedImmutableAttributeData(const El
{
ASSERT(!attributes.isEmpty());
- ImmutableAttributeDataCacheKey cacheKey(element->localName(), attributes.data(), attributes.size());
+ ImmutableAttributeDataCacheKey cacheKey(element->tagQName(), attributes.data(), attributes.size());
unsigned cacheHash = cacheKey.hash();
ImmutableAttributeDataCache::iterator cacheIterator = m_immutableAttributeDataCache.add(cacheHash, nullptr).iterator;
@@ -6364,11 +6373,7 @@ PassRefPtr<ElementAttributeData> Document::cachedImmutableAttributeData(const El
if (!cacheHash || cacheIterator->second)
return attributeData.release();
- OwnPtr<ImmutableAttributeDataCacheEntry> newEntry = adoptPtr(new ImmutableAttributeDataCacheEntry);
- newEntry->key = ImmutableAttributeDataCacheKey(element->localName(), const_cast<const ElementAttributeData*>(attributeData.get())->attributeItem(0), attributeData->length());
- newEntry->value = attributeData;
-
- cacheIterator->second = newEntry.release();
+ cacheIterator->second = adoptPtr(new ImmutableAttributeDataCacheEntry(ImmutableAttributeDataCacheKey(element->tagQName(), attributeData->immutableAttributeArray(), attributeData->length()), attributeData));
return attributeData.release();
}