Commit 2114abd5 authored by ap@webkit.org's avatar ap@webkit.org

Reviewed by Sam Weinig.

        https://bugs.webkit.org/show_bug.cgi?id=21642
        Abstract out active object tracking

        * WebCore.xcodeproj/project.pbxproj:
        * bindings/js/JSDOMBinding.cpp:
        (WebCore::markActiveObjectsForDocument):
        * dom/ActiveDOMObject.cpp: Added.
        (WebCore::ActiveDOMObject::ActiveDOMObject):
        (WebCore::ActiveDOMObject::~ActiveDOMObject):
        (WebCore::ActiveDOMObject::contextDestroyed):
        (WebCore::ActiveDOMObject::stop):
        * dom/ActiveDOMObject.h: Added.
        (WebCore::ActiveDOMObject::document):
        (WebCore::ActiveDOMObject::hasPendingActivity):
        (WebCore::ActiveDOMObject::setPendingActivity):
        (WebCore::ActiveDOMObject::unsetPendingActivity):
        * dom/Document.cpp:
        (WebCore::Document::~Document):
        (WebCore::Document::stopActiveDOMObjects):
        (WebCore::Document::createdActiveDOMObject):
        (WebCore::Document::destroyedActiveDOMObject):
        * dom/Document.h:
        (WebCore::Document::activeDOMObjects):
        * dom/MessagePort.cpp:
        (WebCore::MessagePort::contextDestroyed):
        * dom/MessagePort.h:
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::stopLoading):
        * xml/XMLHttpRequest.cpp:
        (WebCore::XMLHttpRequest::XMLHttpRequest):
        (WebCore::XMLHttpRequest::~XMLHttpRequest):
        (WebCore::XMLHttpRequest::associatedFrame):
        (WebCore::XMLHttpRequest::responseXML):
        (WebCore::XMLHttpRequest::callReadyStateChangeListener):
        (WebCore::XMLHttpRequest::initSend):
        (WebCore::XMLHttpRequest::send):
        (WebCore::XMLHttpRequest::createRequest):
        (WebCore::XMLHttpRequest::makeSimpleCrossSiteAccessRequest):
        (WebCore::XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight):
        (WebCore::XMLHttpRequest::handleAsynchronousPreflightResult):
        (WebCore::XMLHttpRequest::loadRequestSynchronously):
        (WebCore::XMLHttpRequest::loadRequestAsynchronously):
        (WebCore::XMLHttpRequest::dropProtection):
        (WebCore::XMLHttpRequest::setRequestHeader):
        (WebCore::XMLHttpRequest::processSyncLoadResults):
        (WebCore::XMLHttpRequest::didFinishLoading):
        (WebCore::XMLHttpRequest::didFinishLoadingPreflight):
        (WebCore::XMLHttpRequest::willSendRequest):
        (WebCore::XMLHttpRequest::accessControlCheck):
        (WebCore::XMLHttpRequest::didReceiveResponsePreflight):
        (WebCore::XMLHttpRequest::stop):
        (WebCore::XMLHttpRequest::contextDestroyed):
        * xml/XMLHttpRequest.h:
        Move activity tracking to a new ActiveDOMObject class.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@37649 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent efaea23b
2008-10-17 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Sam Weinig.
https://bugs.webkit.org/show_bug.cgi?id=21642
Abstract out active object tracking
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSDOMBinding.cpp:
(WebCore::markActiveObjectsForDocument):
* dom/ActiveDOMObject.cpp: Added.
(WebCore::ActiveDOMObject::ActiveDOMObject):
(WebCore::ActiveDOMObject::~ActiveDOMObject):
(WebCore::ActiveDOMObject::contextDestroyed):
(WebCore::ActiveDOMObject::stop):
* dom/ActiveDOMObject.h: Added.
(WebCore::ActiveDOMObject::document):
(WebCore::ActiveDOMObject::hasPendingActivity):
(WebCore::ActiveDOMObject::setPendingActivity):
(WebCore::ActiveDOMObject::unsetPendingActivity):
* dom/Document.cpp:
(WebCore::Document::~Document):
(WebCore::Document::stopActiveDOMObjects):
(WebCore::Document::createdActiveDOMObject):
(WebCore::Document::destroyedActiveDOMObject):
* dom/Document.h:
(WebCore::Document::activeDOMObjects):
* dom/MessagePort.cpp:
(WebCore::MessagePort::contextDestroyed):
* dom/MessagePort.h:
* loader/FrameLoader.cpp:
(WebCore::FrameLoader::stopLoading):
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::XMLHttpRequest):
(WebCore::XMLHttpRequest::~XMLHttpRequest):
(WebCore::XMLHttpRequest::associatedFrame):
(WebCore::XMLHttpRequest::responseXML):
(WebCore::XMLHttpRequest::callReadyStateChangeListener):
(WebCore::XMLHttpRequest::initSend):
(WebCore::XMLHttpRequest::send):
(WebCore::XMLHttpRequest::createRequest):
(WebCore::XMLHttpRequest::makeSimpleCrossSiteAccessRequest):
(WebCore::XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight):
(WebCore::XMLHttpRequest::handleAsynchronousPreflightResult):
(WebCore::XMLHttpRequest::loadRequestSynchronously):
(WebCore::XMLHttpRequest::loadRequestAsynchronously):
(WebCore::XMLHttpRequest::dropProtection):
(WebCore::XMLHttpRequest::setRequestHeader):
(WebCore::XMLHttpRequest::processSyncLoadResults):
(WebCore::XMLHttpRequest::didFinishLoading):
(WebCore::XMLHttpRequest::didFinishLoadingPreflight):
(WebCore::XMLHttpRequest::willSendRequest):
(WebCore::XMLHttpRequest::accessControlCheck):
(WebCore::XMLHttpRequest::didReceiveResponsePreflight):
(WebCore::XMLHttpRequest::stop):
(WebCore::XMLHttpRequest::contextDestroyed):
* xml/XMLHttpRequest.h:
Move activity tracking to a new ActiveDOMObject class.
2008-10-16 David Hyatt <hyatt@apple.com>
Simplify styleForRenderer to avoid confusion. Callers in the SVG filter code thought "forRenderer" meant
......
......@@ -4153,6 +4153,8 @@
E1ADEDDB0E76BD93004A1A5E /* JSMessagePort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */; };
E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */; };
E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */ = {isa = PBXBuildFile; fileRef = E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */; };
E1C4DE690EA75C1E0023CCD6 /* ActiveDOMObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */; };
E1C4DE6E0EA75C650023CCD6 /* ActiveDOMObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */; };
E1E6EEA40B628DA8005F2F70 /* JSHTMLSelectElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1E6EEA30B628DA8005F2F70 /* JSHTMLSelectElement.cpp */; };
E1E6EEA80B628DB3005F2F70 /* JSHTMLSelectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E6EEA70B628DB3005F2F70 /* JSHTMLSelectElement.h */; };
E1EBBBD40AAC9B87001FE8E2 /* CSSCharsetRule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1EBBBD30AAC9B87001FE8E2 /* CSSCharsetRule.cpp */; };
......@@ -8721,6 +8723,8 @@
E1ADEDD90E76BD93004A1A5E /* JSMessagePort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessagePort.cpp; sourceTree = "<group>"; };
E1BE512B0CF6C512002EA959 /* XSLTUnicodeSort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XSLTUnicodeSort.cpp; sourceTree = "<group>"; };
E1BE512C0CF6C512002EA959 /* XSLTUnicodeSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XSLTUnicodeSort.h; sourceTree = "<group>"; };
E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActiveDOMObject.h; sourceTree = "<group>"; };
E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ActiveDOMObject.cpp; sourceTree = "<group>"; };
E1E6EEA30B628DA8005F2F70 /* JSHTMLSelectElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLSelectElement.cpp; sourceTree = "<group>"; };
E1E6EEA70B628DB3005F2F70 /* JSHTMLSelectElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = JSHTMLSelectElement.h; sourceTree = "<group>"; };
E1EBBBD30AAC9B87001FE8E2 /* CSSCharsetRule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSCharsetRule.cpp; sourceTree = "<group>"; };
......@@ -13672,6 +13676,8 @@
F523D32402DE4478018635CA /* dom */ = {
isa = PBXGroup;
children = (
E1C4DE6D0EA75C650023CCD6 /* ActiveDOMObject.cpp */,
E1C4DE680EA75C1E0023CCD6 /* ActiveDOMObject.h */,
A8C4A7FC09D563270003AC8D /* Attr.cpp */,
A8C4A7FB09D563270003AC8D /* Attr.h */,
93EEC1E509C2877700C515D1 /* Attr.idl */,
......@@ -15982,6 +15988,7 @@
1CF6BE150E9BB4670025E1CD /* ObjCNodeFilterCondition.h in Headers */,
A80D67080E9E9DEB00E420F0 /* GraphicsContextPlatformPrivateCG.h in Headers */,
939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
E1C4DE690EA75C1E0023CCD6 /* ActiveDOMObject.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -17849,6 +17856,7 @@
1CF6BE140E9BB4670025E1CD /* ObjCNodeFilterCondition.mm in Sources */,
BC80FA130EA287B000B0821D /* Length.cpp in Sources */,
939B02EE0EA2DBC400C54570 /* WidthIterator.cpp in Sources */,
E1C4DE6E0EA75C650023CCD6 /* ActiveDOMObject.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -26,6 +26,7 @@
#include "config.h"
#include "JSDOMBinding.h"
#include "ActiveDOMObject.h"
#include "DOMCoreException.h"
#include "Document.h"
#include "EventException.h"
......@@ -43,7 +44,6 @@
#include "MessagePort.h"
#include "RangeException.h"
#include "ScriptController.h"
#include "XMLHttpRequest.h"
#include "XMLHttpRequestException.h"
#include <kjs/PrototypeFunction.h>
......@@ -245,11 +245,11 @@ void markActiveObjectsForDocument(JSGlobalData& globalData, Document* doc)
// If an element has pending activity that may result in listeners being called
// (e.g. an XMLHttpRequest), we need to keep all JS wrappers alive.
const HashSet<XMLHttpRequest*>& xmlHttpRequests = doc->xmlHttpRequests();
HashSet<XMLHttpRequest*>::const_iterator requestsEnd = xmlHttpRequests.end();
for (HashSet<XMLHttpRequest*>::const_iterator iter = xmlHttpRequests.begin(); iter != requestsEnd; ++iter) {
if ((*iter)->hasPendingActivity()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, *iter);
const HashMap<ActiveDOMObject*, void*>& activeObjects = doc->activeDOMObjects();
HashMap<ActiveDOMObject*, void*>::const_iterator activeObjectsEnd = activeObjects.end();
for (HashMap<ActiveDOMObject*, void*>::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) {
if (iter->first->hasPendingActivity()) {
DOMObject* wrapper = getCachedDOMObjectWrapper(globalData, iter->second);
// An object with pending activity must have a wrapper to mark its listeners, so no null check.
if (!wrapper->marked())
wrapper->mark();
......
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include "ActiveDOMObject.h"
#include "Document.h"
namespace WebCore {
ActiveDOMObject::ActiveDOMObject(Document* document, void* upcastPointer)
: m_document(document)
, m_pendingActivityCount(0)
{
m_document->createdActiveDOMObject(this, upcastPointer);
}
ActiveDOMObject::~ActiveDOMObject()
{
if (m_document)
m_document->destroyedActiveDOMObject(this);
}
void ActiveDOMObject::contextDestroyed()
{
m_document = 0;
}
void ActiveDOMObject::stop()
{
}
} // namespace WebCore
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef ActiveDOMObject_h
#define ActiveDOMObject_h
#include <wtf/Assertions.h>
namespace WebCore {
class Document;
class ActiveDOMObject {
public:
ActiveDOMObject(Document*, void* upcastPointer);
Document* document() const { return m_document; }
bool hasPendingActivity() { return m_pendingActivityCount; }
virtual void contextDestroyed();
virtual void stop();
protected:
virtual ~ActiveDOMObject();
template<class T> void setPendingActivity(T* thisObject)
{
ASSERT(thisObject == this);
thisObject->ref();
m_pendingActivityCount++;
}
template<class T> void unsetPendingActivity(T* thisObject)
{
ASSERT(m_pendingActivityCount > 0);
--m_pendingActivityCount;
thisObject->deref();
}
private:
Document* m_document;
unsigned m_pendingActivityCount;
};
} // namespace WebCore
#endif // ActiveDOMObject_h
......@@ -426,7 +426,18 @@ Document::~Document()
removeAllEventListeners();
XMLHttpRequest::detachRequests(this);
HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end();
for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
ASSERT(iter->first->document() == this);
iter->first->contextDestroyed();
}
HashSet<MessagePort*>::iterator messagePortsEnd = m_messagePorts.end();
for (HashSet<MessagePort*>::iterator iter = m_messagePorts.begin(); iter != messagePortsEnd; ++iter) {
ASSERT((*iter)->document() == this);
(*iter)->contextDestroyed();
}
forgetAllDOMNodesForDocument(this);
if (m_docChanged && changedDocuments)
......@@ -469,18 +480,6 @@ Document::~Document()
if (m_styleSheets)
m_styleSheets->documentDestroyed();
HashSet<MessagePort*>::iterator messagePortsEnd = m_messagePorts.end();
for (HashSet<MessagePort*>::iterator iter = m_messagePorts.begin(); iter != m_messagePorts.end(); ++iter) {
ASSERT((*iter)->document() == this);
(*iter)->contextDestroyed();
if ((*iter)->entangledPort()) {
RefPtr<MessagePort> survivingPort = (*iter)->entangledPort();
(*iter)->unentangle();
if (survivingPort->document() != this) // Otherwise, survivingPort won't really survive.
survivingPort->queueCloseEvent();
}
}
m_document = 0;
}
......@@ -4406,16 +4405,26 @@ void Document::destroyedMessagePort(MessagePort* port)
m_messagePorts.remove(port);
}
void Document::createdXMLHttpRequest(XMLHttpRequest* request)
void Document::stopActiveDOMObjects()
{
HashMap<ActiveDOMObject*, void*>::iterator activeObjectsEnd = m_activeDOMObjects.end();
for (HashMap<ActiveDOMObject*, void*>::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
ASSERT(iter->first->document() == this);
iter->first->stop();
}
}
void Document::createdActiveDOMObject(ActiveDOMObject* object, void* upcastPointer)
{
ASSERT(request);
m_xmlHttpRequests.add(request);
ASSERT(object);
ASSERT(upcastPointer);
m_activeDOMObjects.add(object, upcastPointer);
}
void Document::destroyedXMLHttpRequest(XMLHttpRequest* request)
void Document::destroyedActiveDOMObject(ActiveDOMObject* object)
{
ASSERT(request);
m_xmlHttpRequests.remove(request);
ASSERT(object);
m_activeDOMObjects.remove(object);
}
void Document::initDNSPrefetch()
......
......@@ -48,6 +48,7 @@
namespace WebCore {
class ActiveDOMObject;
class AXObjectCache;
class Attr;
class Attribute;
......@@ -764,16 +765,19 @@ public:
CanvasRenderingContext2D* getCSSCanvasContext(const String& type, const String& name, int width, int height);
HTMLCanvasElement* getCSSCanvasElement(const String& name);
// Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
void stopActiveDOMObjects();
void createdActiveDOMObject(ActiveDOMObject*, void* upcastPointer);
void destroyedActiveDOMObject(ActiveDOMObject*);
const HashMap<ActiveDOMObject*, void*>& activeDOMObjects() const { return m_activeDOMObjects; }
// MessagePort is conceptually a kind of ActiveDOMObject, but it needs to be tracked separately for message dispatch, and for cross-heap GC support.
void processMessagePortMessagesSoon();
void dispatchMessagePortEvents();
void createdMessagePort(MessagePort*);
void destroyedMessagePort(MessagePort*);
const HashSet<MessagePort*>& messagePorts() const { return m_messagePorts; }
void createdXMLHttpRequest(XMLHttpRequest*);
void destroyedXMLHttpRequest(XMLHttpRequest*);
const HashSet<XMLHttpRequest*>& xmlHttpRequests() const { return m_xmlHttpRequests; }
bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
void initDNSPrefetch();
void parseDNSPrefetchControlHeader(const String&);
......@@ -934,7 +938,7 @@ private:
bool m_firedMessagePortTimer;
HashSet<MessagePort*> m_messagePorts;
HashSet<XMLHttpRequest*> m_xmlHttpRequests;
HashMap<ActiveDOMObject*, void*> m_activeDOMObjects;
public:
bool inPageCache();
......
......@@ -195,6 +195,17 @@ void MessagePort::unentangle()
m_entangledPort = 0;
}
void MessagePort::contextDestroyed()
{
if (m_entangledPort) {
RefPtr<MessagePort> survivingPort = m_entangledPort;
unentangle();
if (survivingPort->document() != document()) // Otherwise, survivingPort won't really survive.
survivingPort->queueCloseEvent();
}
m_document = 0;
}
void MessagePort::dispatchMessages()
{
// Messages for documents that are not fully active get dispatched too, but JSAbstractEventListener::handleEvent() doesn't call handlers for these.
......
......@@ -65,7 +65,7 @@ namespace WebCore {
static void entangle(MessagePort*, MessagePort*);
void unentangle();
void contextDestroyed() { m_document = 0; }
void contextDestroyed();
Document* document() { return m_document; }
virtual MessagePort* toMessagePort() { return this; }
......
......@@ -623,8 +623,8 @@ void FrameLoader::stopLoading(bool sendUnload)
if (Document* doc = m_frame->document()) {
if (DocLoader* docLoader = doc->docLoader())
cache()->loader()->cancelRequests(docLoader);
XMLHttpRequest::cancelRequests(doc);
doc->stopActiveDOMObjects();
#if ENABLE(DATABASE)
doc->stopDatabases();
......
......@@ -166,7 +166,7 @@ static bool isValidHeaderValue(const String& name)
}
XMLHttpRequest::XMLHttpRequest(Document* doc)
: m_doc(doc)
: ActiveDOMObject(doc, this)
, m_async(true)
, m_includeCredentials(false)
, m_state(UNSENT)
......@@ -177,28 +177,23 @@ XMLHttpRequest::XMLHttpRequest(Document* doc)
, m_uploadComplete(false)
, m_sameOriginRequest(true)
, m_inPreflight(false)
, m_pendingActivity(0)
, m_receivedLength(0)
, m_lastSendLineNumber(0)
{
ASSERT(m_doc);
m_doc->createdXMLHttpRequest(this);
ASSERT(document());
}
XMLHttpRequest::~XMLHttpRequest()
{
if (m_doc)
m_doc->destroyedXMLHttpRequest(this);
if (m_upload)
m_upload->disconnectXMLHttpRequest();
}
Frame* XMLHttpRequest::associatedFrame() const
{
if (!m_doc)
if (!document())
return 0;
return m_doc->frame();
return document()->frame();
}
XMLHttpRequest::State XMLHttpRequest::readyState() const
......@@ -221,7 +216,7 @@ Document* XMLHttpRequest::responseXML() const
// The W3C spec requires this.
m_responseXML = 0;
} else {
m_responseXML = m_doc->implementation()->createDocument(0);
m_responseXML = document()->implementation()->createDocument(0);
m_responseXML->open();
m_responseXML->setURL(m_url);
// FIXME: set Last-Modified and cookies (currently, those are only available for HTMLDocuments).
......@@ -305,7 +300,7 @@ void XMLHttpRequest::changeState(State newState)
void XMLHttpRequest::callReadyStateChangeListener()
{
if (!m_doc || !m_doc->frame())
if (!document() || !document()->frame())
return;
dispatchReadyStateChangeEvent();
......@@ -383,7 +378,7 @@ void XMLHttpRequest::open(const String& method, const KURL& url, bool async, con
bool XMLHttpRequest::initSend(ExceptionCode& ec)
{
if (!m_doc)
if (!document())
return false;
if (m_state != OPENED || m_loader) {
......@@ -411,7 +406,7 @@ void XMLHttpRequest::send(Document* document, ExceptionCode& ec)
String contentType = getRequestHeader("Content-Type");
if (contentType.isEmpty()) {
#if ENABLE(DASHBOARD_SUPPORT)
Settings* settings = m_doc->settings();
Settings* settings = document->settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode())
setRequestHeaderInternal("Content-Type", "application/x-www-form-urlencoded");
else
......@@ -443,7 +438,7 @@ void XMLHttpRequest::send(const String& body, ExceptionCode& ec)
String contentType = getRequestHeader("Content-Type");
if (contentType.isEmpty()) {
#if ENABLE(DASHBOARD_SUPPORT)
Settings* settings = m_doc->settings();
Settings* settings = document()->settings();
if (settings && settings->usesDashboardBackwardCompatibilityMode())
setRequestHeaderInternal("Content-Type", "application/x-www-form-urlencoded");
else
......@@ -482,7 +477,7 @@ void XMLHttpRequest::createRequest(ExceptionCode& ec)
m_upload->dispatchLoadStartEvent();
}
m_sameOriginRequest = m_doc->securityOrigin()->canRequest(m_url);
m_sameOriginRequest = document()->securityOrigin()->canRequest(m_url);
if (!m_sameOriginRequest) {
makeCrossSiteAccessRequest(ec);
......@@ -548,7 +543,7 @@ void XMLHttpRequest::makeSimpleCrossSiteAccessRequest(ExceptionCode& ec)
ResourceRequest request(url);
request.setHTTPMethod(m_method);
request.setAllowHTTPCookies(m_includeCredentials);
request.setHTTPOrigin(m_doc->securityOrigin()->toHTTPOrigin());
request.setHTTPOrigin(document()->securityOrigin()->toHTTPOrigin());
if (m_requestHeaders.size() > 0)
request.addHTTPHeaderFields(m_requestHeaders);
......@@ -579,7 +574,7 @@ static bool canSkipPrelight(PreflightResultCache::iterator cacheIt, bool include
void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
{
String origin = m_doc->securityOrigin()->toHTTPOrigin();
String origin = document()->securityOrigin()->toHTTPOrigin();
KURL url = m_url;
url.setUser(String());
url.setPass(String());
......@@ -667,7 +662,7 @@ void XMLHttpRequest::handleAsynchronousPreflightResult()
ResourceRequest request(url);
request.setHTTPMethod(m_method);
request.setAllowHTTPCookies(m_includeCredentials);
request.setHTTPOrigin(m_doc->securityOrigin()->toHTTPOrigin());
request.setHTTPOrigin(document()->securityOrigin()->toHTTPOrigin());
if (m_requestHeaders.size() > 0)
request.addHTTPHeaderFields(m_requestHeaders);
......@@ -687,8 +682,8 @@ void XMLHttpRequest::loadRequestSynchronously(ResourceRequest& request, Exceptio
ResourceError error;
ResourceResponse response;
if (m_doc->frame())
m_identifier = m_doc->frame()->loader()->loadResourceSynchronously(request, error, response, data);
if (document()->frame())
m_identifier = document()->frame()->loader()->loadResourceSynchronously(request, error, response, data);
m_loader = 0;
......@@ -720,13 +715,13 @@ void XMLHttpRequest::loadRequestAsynchronously(ResourceRequest& request)
// We need to keep content sniffing enabled for local files due to CFNetwork not providing a MIME type
// for local files otherwise, <rdar://problem/5671813>.
bool sendResourceLoadCallbacks = !m_inPreflight;
m_loader = SubresourceLoader::create(m_doc->frame(), this, request, false, sendResourceLoadCallbacks, request.url().isLocalFile());
m_loader = SubresourceLoader::create(document()->frame(), this, request, false, sendResourceLoadCallbacks, request.url().isLocalFile());
if (m_loader) {
// Neither this object nor the JavaScript wrapper should be deleted while
// a request is in progress because we need to keep the listeners alive,
// and they are referenced by the JavaScript wrapper.
setPendingActivity();
setPendingActivity(this);
}
}
......@@ -833,12 +828,12 @@ void XMLHttpRequest::dropProtection()
// can't be recouped until the load is done, so only
// report the extra cost at that point.
JSDOMWindow* window = toJSDOMWindow(m_doc->frame());
JSDOMWindow* window = toJSDOMWindow(document()->frame());
JSC::JSValue* wrapper = getCachedDOMObjectWrapper(*window->globalData(), this);
if (wrapper)
JSC::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);
unsetPendingActivity();
unsetPendingActivity(this);
}
void XMLHttpRequest::overrideMimeType(const String& override)
......@@ -850,7 +845,7 @@ void XMLHttpRequest::setRequestHeader(const String& name, const String& value, E
{
if (m_state != OPENED || m_loader) {
#if ENABLE(DASHBOARD_SUPPORT)
Settings* settings = m_doc ? m_doc->settings() : 0;
Settings* settings = document() ? document()->settings() : 0;
if (settings && settings->usesDashboardBackwardCompatibilityMode())
return;
#endif
......@@ -865,9 +860,9 @@ void XMLHttpRequest::setRequestHeader(const String& name, const String& value, E
}
// A privileged script (e.g. a Dashboard widget) can set any headers.
if (!m_doc->securityOrigin()->canLoadLocalResources() && !isSafeRequestHeader(name)) {
if (m_doc && m_doc->frame())
m_doc->frame()->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "Refused to set unsafe header \"" + name + "\"", 1, String());
if (!document()->securityOrigin()->canLoadLocalResources() && !isSafeRequestHeader(name)) {
if (document() && document()->frame())
document()->frame()->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "Refused to set unsafe header \"" + name + "\"", 1, String());
return;
}
......@@ -977,7 +972,7 @@ String XMLHttpRequest::statusText(ExceptionCode& ec) const
void XMLHttpRequest::processSyncLoadResults(const Vector<char>& data, const ResourceResponse& response, ExceptionCode& ec)
{
if (m_sameOriginRequest && !m_doc->securityOrigin()->canRequest(response.url())) {
if (m_sameOriginRequest && !document()->securityOrigin()->canRequest(response.url())) {
abort();
return;
}
......@@ -1030,7 +1025,7 @@ void XMLHttpRequest::didFinishLoading(SubresourceLoader* loader)
m_responseText += m_decoder->flush();
}
if (Frame* frame = m_doc->frame()) {
if (Frame* frame = document()->frame()) {
if (Page* page = frame->page()) {
page->inspectorController()->resourceRetrievedByXMLHttpRequest(m_loader ? m_loader->identifier() : m_identifier, m_responseText);
page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageLevel, "XHR finished loading: \"" + m_url + "\".", m_lastSendLineNumber, m_lastSendURL);
......@@ -1056,15 +1051,14 @@ void XMLHttpRequest::didFinishLoadingPreflight(SubresourceLoader* loader)
if (m_async)
handleAsynchronousPreflightResult();
if (m_loader) {
unsetPendingActivity();
}
if (m_loader)
unsetPendingActivity(this);
}
void XMLHttpRequest::willSendRequest(SubresourceLoader*, ResourceRequest& request, const ResourceResponse& redirectResponse)
{
// FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
if (!m_doc->securityOrigin()->canRequest(request.url())) {
if (!document()->securityOrigin()->canRequest(request.url())) {
internalAbort();
networkError();
}
......@@ -1094,7 +1088,7 @@ bool XMLHttpRequest::accessControlCheck(const ResourceResponse& response)
return false;
RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::create(accessControlOriginURL);
if (!accessControlOrigin->isSameSchemeHostPort(m_doc->securityOrigin())) </