summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/xml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2009-06-15 09:06:43 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-06-15 09:31:31 (GMT)
commitc411f16870f112c3407c28c22b617f613a82cff4 (patch)
tree29a1bcd590c8b31af2aab445bfe8a978dc5bf582 /src/3rdparty/webkit/WebCore/xml
parent3d77b56b32a0c53ec0bbfaa07236fedb900ff336 (diff)
downloadQt-c411f16870f112c3407c28c22b617f613a82cff4.zip
Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.gz
Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.bz2
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-15062009 ( 65232bf00dc494ebfd978f998c88f58d18ecce1e )
Diffstat (limited to 'src/3rdparty/webkit/WebCore/xml')
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp539
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h54
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl5
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequestException.idl5
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.idl3
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h2
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl3
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathException.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathExpression.cpp21
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.cpp4
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.h32
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathFunctions.cpp131
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathFunctions.h12
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathGrammar.y4
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathNodeSet.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathNodeSet.h16
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathPath.cpp92
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathPath.h14
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathPredicate.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathPredicate.h16
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathResult.cpp48
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathResult.h22
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathStep.cpp283
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathStep.h41
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathUtil.cpp20
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathValue.cpp22
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XPathVariableReference.h4
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XSLStyleSheet.cpp14
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XSLTExtensions.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XSLTProcessor.cpp9
-rw-r--r--src/3rdparty/webkit/WebCore/xml/XSLTUnicodeSort.cpp54
32 files changed, 705 insertions, 778 deletions
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp
index cc92c2a..a837c8c 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.cpp
@@ -23,32 +23,27 @@
#include "XMLHttpRequest.h"
#include "CString.h"
-#include "Console.h"
+#include "CrossOriginAccessControl.h"
+#include "CrossOriginPreflightResultCache.h"
#include "DOMImplementation.h"
-#include "DOMWindow.h"
+#include "Document.h"
#include "Event.h"
#include "EventException.h"
#include "EventListener.h"
#include "EventNames.h"
#include "File.h"
-#include "Frame.h"
-#include "FrameLoader.h"
#include "HTTPParsers.h"
-#include "InspectorController.h"
-#include "KURL.h"
-#include "KURLHash.h"
-#include "Page.h"
+#include "ResourceError.h"
+#include "ResourceRequest.h"
+#include "SecurityOrigin.h"
#include "Settings.h"
-#include "SubresourceLoader.h"
-#include "SystemTime.h"
#include "TextResourceDecoder.h"
+#include "ThreadableLoader.h"
#include "XMLHttpRequestException.h"
#include "XMLHttpRequestProgressEvent.h"
#include "XMLHttpRequestUpload.h"
#include "markup.h"
-#include <wtf/Noncopyable.h>
#include <wtf/StdLibExtras.h>
-#include <wtf/Threading.h>
#if USE(JSC)
#include "JSDOMWindow.h"
@@ -56,14 +51,11 @@
namespace WebCore {
-typedef HashSet<String, CaseFoldingHash> HeadersSet;
-
struct XMLHttpRequestStaticData {
XMLHttpRequestStaticData();
String m_proxyHeaderPrefix;
String m_secHeaderPrefix;
HashSet<String, CaseFoldingHash> m_forbiddenRequestHeaders;
- HashSet<String, CaseFoldingHash> m_allowedCrossSiteResponseHeaders;
};
XMLHttpRequestStaticData::XMLHttpRequestStaticData()
@@ -72,76 +64,25 @@ XMLHttpRequestStaticData::XMLHttpRequestStaticData()
{
m_forbiddenRequestHeaders.add("accept-charset");
m_forbiddenRequestHeaders.add("accept-encoding");
+ m_forbiddenRequestHeaders.add("access-control-request-headers");
+ m_forbiddenRequestHeaders.add("access-control-request-method");
m_forbiddenRequestHeaders.add("connection");
m_forbiddenRequestHeaders.add("content-length");
m_forbiddenRequestHeaders.add("content-transfer-encoding");
+ m_forbiddenRequestHeaders.add("cookie");
+ m_forbiddenRequestHeaders.add("cookie2");
m_forbiddenRequestHeaders.add("date");
m_forbiddenRequestHeaders.add("expect");
m_forbiddenRequestHeaders.add("host");
m_forbiddenRequestHeaders.add("keep-alive");
+ m_forbiddenRequestHeaders.add("origin");
m_forbiddenRequestHeaders.add("referer");
m_forbiddenRequestHeaders.add("te");
m_forbiddenRequestHeaders.add("trailer");
m_forbiddenRequestHeaders.add("transfer-encoding");
m_forbiddenRequestHeaders.add("upgrade");
+ m_forbiddenRequestHeaders.add("user-agent");
m_forbiddenRequestHeaders.add("via");
-
- m_allowedCrossSiteResponseHeaders.add("cache-control");
- m_allowedCrossSiteResponseHeaders.add("content-language");
- m_allowedCrossSiteResponseHeaders.add("content-type");
- m_allowedCrossSiteResponseHeaders.add("expires");
- m_allowedCrossSiteResponseHeaders.add("last-modified");
- m_allowedCrossSiteResponseHeaders.add("pragma");
-}
-
-class PreflightResultCacheItem : Noncopyable {
-public:
- PreflightResultCacheItem(bool credentials)
- : m_absoluteExpiryTime(0)
- , m_credentials(credentials)
- {
- }
-
- bool parse(const ResourceResponse&);
- bool allowsCrossSiteMethod(const String&) const;
- bool allowsCrossSiteHeaders(const HTTPHeaderMap&) const;
- bool allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const;
-
-private:
- template<class HashType>
- static void addToAccessControlAllowList(const String& string, unsigned start, unsigned end, HashSet<String, HashType>&);
- template<class HashType>
- static bool parseAccessControlAllowList(const String& string, HashSet<String, HashType>&);
- static bool parseAccessControlMaxAge(const String& string, unsigned& expiryDelta);
-
- // FIXME: A better solution to holding onto the absolute expiration time might be
- // to start a timer for the expiration delta, that removes this from the cache when
- // it fires.
- double m_absoluteExpiryTime;
- bool m_credentials;
- HashSet<String> m_methods;
- HeadersSet m_headers;
-};
-
-class PreflightResultCache : Noncopyable {
-public:
- static PreflightResultCache& shared();
-
- void appendEntry(const String& origin, const KURL&, PreflightResultCacheItem*);
- bool canSkipPreflight(const String& origin, const KURL&, bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
-
-private:
- PreflightResultCache() { }
-
- typedef HashMap<std::pair<String, KURL>, PreflightResultCacheItem*> PreflightResultHashMap;
-
- PreflightResultHashMap m_preflightHashMap;
- Mutex m_mutex;
-};
-
-static bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name)
-{
- return equalIgnoringCase(name, "accept") || equalIgnoringCase(name, "accept-language") || equalIgnoringCase(name, "content-type");
}
// Determines if a string is a valid token, as defined by
@@ -178,131 +119,6 @@ static bool isSetCookieHeader(const AtomicString& name)
return equalIgnoringCase(name, "set-cookie") || equalIgnoringCase(name, "set-cookie2");
}
-template<class HashType>
-void PreflightResultCacheItem::addToAccessControlAllowList(const String& string, unsigned start, unsigned end, HashSet<String, HashType>& set)
-{
- StringImpl* stringImpl = string.impl();
- if (!stringImpl)
- return;
-
- // Skip white space from start.
- while (start <= end && isSpaceOrNewline((*stringImpl)[start]))
- start++;
-
- // only white space
- if (start > end)
- return;
-
- // Skip white space from end.
- while (end && isSpaceOrNewline((*stringImpl)[end]))
- end--;
-
- // substringCopy() is called on the strings because the cache is accessed on multiple threads.
- set.add(string.substringCopy(start, end - start + 1));
-}
-
-
-template<class HashType>
-bool PreflightResultCacheItem::parseAccessControlAllowList(const String& string, HashSet<String, HashType>& set)
-{
- int start = 0;
- int end;
- while ((end = string.find(',', start)) != -1) {
- if (start == end)
- return false;
-
- addToAccessControlAllowList(string, start, end - 1, set);
- start = end + 1;
- }
- if (start != static_cast<int>(string.length()))
- addToAccessControlAllowList(string, start, string.length() - 1, set);
-
- return true;
-}
-
-bool PreflightResultCacheItem::parseAccessControlMaxAge(const String& string, unsigned& expiryDelta)
-{
- // FIXME: this will not do the correct thing for a number starting with a '+'
- bool ok = false;
- expiryDelta = string.toUIntStrict(&ok);
- return ok;
-}
-
-bool PreflightResultCacheItem::parse(const ResourceResponse& response)
-{
- m_methods.clear();
- if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Methods"), m_methods))
- return false;
-
- m_headers.clear();
- if (!parseAccessControlAllowList(response.httpHeaderField("Access-Control-Allow-Headers"), m_headers))
- return false;
-
- unsigned expiryDelta = 0;
- if (!parseAccessControlMaxAge(response.httpHeaderField("Access-Control-Max-Age"), expiryDelta))
- expiryDelta = 5;
-
- m_absoluteExpiryTime = currentTime() + expiryDelta;
- return true;
-}
-
-bool PreflightResultCacheItem::allowsCrossSiteMethod(const String& method) const
-{
- return m_methods.contains(method) || method == "GET" || method == "POST";
-}
-
-bool PreflightResultCacheItem::allowsCrossSiteHeaders(const HTTPHeaderMap& requestHeaders) const
-{
- HTTPHeaderMap::const_iterator end = requestHeaders.end();
- for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
- if (!m_headers.contains(it->first) && !isOnAccessControlSimpleRequestHeaderWhitelist(it->first))
- return false;
- }
- return true;
-}
-
-bool PreflightResultCacheItem::allowsRequest(bool includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders) const
-{
- if (m_absoluteExpiryTime < currentTime())
- return false;
- if (includeCredentials && !m_credentials)
- return false;
- if (!allowsCrossSiteMethod(method))
- return false;
- if (!allowsCrossSiteHeaders(requestHeaders))
- return false;
- return true;
-}
-
-PreflightResultCache& PreflightResultCache::shared()
-{
- AtomicallyInitializedStatic(PreflightResultCache&, cache = *new PreflightResultCache);
- return cache;
-}
-
-void PreflightResultCache::appendEntry(const String& origin, const KURL& url, PreflightResultCacheItem* preflightResult)
-{
- MutexLocker lock(m_mutex);
- // Note that the entry may already be present in the HashMap if another thread is accessing the same location.
- m_preflightHashMap.set(std::make_pair(origin.copy(), url.copy()), preflightResult);
-}
-
-bool PreflightResultCache::canSkipPreflight(const String& origin, const KURL& url, bool includeCredentials,
- const String& method, const HTTPHeaderMap& requestHeaders)
-{
- MutexLocker lock(m_mutex);
- PreflightResultHashMap::iterator cacheIt = m_preflightHashMap.find(std::make_pair(origin, url));
- if (cacheIt == m_preflightHashMap.end())
- return false;
-
- if (cacheIt->second->allowsRequest(includeCredentials, method, requestHeaders))
- return true;
-
- delete cacheIt->second;
- m_preflightHashMap.remove(cacheIt);
- return false;
-}
-
static const XMLHttpRequestStaticData* staticData = 0;
static const XMLHttpRequestStaticData* createXMLHttpRequestStaticData()
@@ -318,12 +134,11 @@ static const XMLHttpRequestStaticData* initializeXMLHttpRequestStaticData()
return dummy;
}
-XMLHttpRequest::XMLHttpRequest(Document* doc)
- : ActiveDOMObject(doc, this)
+XMLHttpRequest::XMLHttpRequest(ScriptExecutionContext* context)
+ : ActiveDOMObject(context, this)
, m_async(true)
, m_includeCredentials(false)
, m_state(UNSENT)
- , m_identifier(std::numeric_limits<unsigned long>::max())
, m_responseText("")
, m_createdDocument(false)
, m_error(false)
@@ -332,8 +147,8 @@ XMLHttpRequest::XMLHttpRequest(Document* doc)
, m_inPreflight(false)
, m_receivedLength(0)
, m_lastSendLineNumber(0)
+ , m_exceptionCode(0)
{
- ASSERT(document());
initializeXMLHttpRequestStaticData();
}
@@ -349,6 +164,16 @@ Document* XMLHttpRequest::document() const
return static_cast<Document*>(scriptExecutionContext());
}
+#if ENABLE(DASHBOARD_SUPPORT)
+bool XMLHttpRequest::usesDashboardBackwardCompatibilityMode() const
+{
+ if (scriptExecutionContext()->isWorkerContext())
+ return false;
+ Settings* settings = document()->settings();
+ return settings && settings->usesDashboardBackwardCompatibilityMode();
+}
+#endif
+
XMLHttpRequest::State XMLHttpRequest::readyState() const
{
return m_state;
@@ -372,7 +197,7 @@ Document* XMLHttpRequest::responseXML() const
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).
+ // FIXME: Set Last-Modified.
m_responseXML->write(String(m_responseText));
m_responseXML->finishParsing();
m_responseXML->close();
@@ -458,10 +283,20 @@ void XMLHttpRequest::callReadyStateChangeListener()
dispatchReadyStateChangeEvent();
- if (m_state == DONE)
+ if (m_state == DONE && !m_error)
dispatchLoadEvent();
}
+void XMLHttpRequest::setWithCredentials(bool value, ExceptionCode& ec)
+{
+ if (m_state != OPENED || m_loader) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ m_includeCredentials = value;
+}
+
void XMLHttpRequest::open(const String& method, const KURL& url, bool async, ExceptionCode& ec)
{
internalAbort();
@@ -555,12 +390,11 @@ void XMLHttpRequest::send(Document* document, ExceptionCode& ec)
if (!initSend(ec))
return;
- if (m_method != "GET" && m_method != "HEAD" && (m_url.protocolIs("http") || m_url.protocolIs("https"))) {
+ if (m_method != "GET" && m_method != "HEAD" && m_url.protocolInHTTPFamily()) {
String contentType = getRequestHeader("Content-Type");
if (contentType.isEmpty()) {
#if ENABLE(DASHBOARD_SUPPORT)
- Settings* settings = document->settings();
- if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ if (usesDashboardBackwardCompatibilityMode())
setRequestHeaderInternal("Content-Type", "application/x-www-form-urlencoded");
else
#endif
@@ -587,12 +421,11 @@ void XMLHttpRequest::send(const String& body, ExceptionCode& ec)
if (!initSend(ec))
return;
- if (!body.isNull() && m_method != "GET" && m_method != "HEAD" && (m_url.protocolIs("http") || m_url.protocolIs("https"))) {
+ if (!body.isNull() && m_method != "GET" && m_method != "HEAD" && m_url.protocolInHTTPFamily()) {
String contentType = getRequestHeader("Content-Type");
if (contentType.isEmpty()) {
#if ENABLE(DASHBOARD_SUPPORT)
- Settings* settings = document()->settings();
- if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ if (usesDashboardBackwardCompatibilityMode())
setRequestHeaderInternal("Content-Type", "application/x-www-form-urlencoded");
else
#endif
@@ -612,7 +445,7 @@ void XMLHttpRequest::send(File* body, ExceptionCode& ec)
if (!initSend(ec))
return;
- if (m_method != "GET" && m_method != "HEAD" && (m_url.protocolIs("http") || m_url.protocolIs("https"))) {
+ if (m_method != "GET" && m_method != "HEAD" && m_url.protocolInHTTPFamily()) {
// FIXME: Should we set a Content-Type if one is not set.
// FIXME: add support for uploading bundles.
m_requestEntityBody = FormData::create();
@@ -624,19 +457,28 @@ void XMLHttpRequest::send(File* body, ExceptionCode& ec)
void XMLHttpRequest::createRequest(ExceptionCode& ec)
{
+ // Upload event listeners should be disallowed for simple cross-origin requests, because POSTing to an URL that does not
+ // permit cross origin requests should look exactly like POSTing to an URL that does not respond at all. If a listener exists
+ // when creating the request, it will force preflight.
+ // Also, only async requests support upload progress events.
+ m_uploadEventsAllowed = false;
if (m_async) {
dispatchLoadStartEvent();
- if (m_requestEntityBody && m_upload)
+ if (m_requestEntityBody && m_upload) {
+ m_uploadEventsAllowed = m_upload->hasListeners();
m_upload->dispatchLoadStartEvent();
+ }
}
m_sameOriginRequest = scriptExecutionContext()->securityOrigin()->canRequest(m_url);
if (!m_sameOriginRequest) {
- makeCrossSiteAccessRequest(ec);
+ makeCrossOriginAccessRequest(ec);
return;
}
+ m_uploadEventsAllowed = true;
+
makeSameOriginRequest(ec);
}
@@ -649,6 +491,7 @@ void XMLHttpRequest::makeSameOriginRequest(ExceptionCode& ec)
if (m_requestEntityBody) {
ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
request.setHTTPBody(m_requestEntityBody.release());
}
@@ -661,38 +504,31 @@ void XMLHttpRequest::makeSameOriginRequest(ExceptionCode& ec)
loadRequestSynchronously(request, ec);
}
-bool XMLHttpRequest::isSimpleCrossSiteAccessRequest() const
-{
- if (m_method != "GET" && m_method != "POST")
- return false;
-
- HTTPHeaderMap::const_iterator end = m_requestHeaders.end();
- for (HTTPHeaderMap::const_iterator it = m_requestHeaders.begin(); it != end; ++it) {
- if (!isOnAccessControlSimpleRequestHeaderWhitelist(it->first))
- return false;
- }
-
- return true;
-}
-
-void XMLHttpRequest::makeCrossSiteAccessRequest(ExceptionCode& ec)
+void XMLHttpRequest::makeCrossOriginAccessRequest(ExceptionCode& ec)
{
ASSERT(!m_sameOriginRequest);
- if (isSimpleCrossSiteAccessRequest())
- makeSimpleCrossSiteAccessRequest(ec);
+ if (!m_uploadEventsAllowed && isSimpleCrossOriginAccessRequest(m_method, m_requestHeaders))
+ makeSimpleCrossOriginAccessRequest(ec);
else
- makeCrossSiteAccessRequestWithPreflight(ec);
+ makeCrossOriginAccessRequestWithPreflight(ec);
}
-void XMLHttpRequest::makeSimpleCrossSiteAccessRequest(ExceptionCode& ec)
+void XMLHttpRequest::makeSimpleCrossOriginAccessRequest(ExceptionCode& ec)
{
- ASSERT(isSimpleCrossSiteAccessRequest());
+ ASSERT(isSimpleCrossOriginAccessRequest(m_method, m_requestHeaders));
+
+ // Cross-origin requests are only defined for HTTP. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
+ if (!m_url.protocolInHTTPFamily()) {
+ ec = XMLHttpRequestException::NETWORK_ERR;
+ networkError();
+ return;
+ }
KURL url = m_url;
url.setUser(String());
url.setPass(String());
-
+
ResourceRequest request(url);
request.setHTTPMethod(m_method);
request.setAllowHTTPCookies(m_includeCredentials);
@@ -701,20 +537,26 @@ void XMLHttpRequest::makeSimpleCrossSiteAccessRequest(ExceptionCode& ec)
if (m_requestHeaders.size() > 0)
request.addHTTPHeaderFields(m_requestHeaders);
+ if (m_requestEntityBody) {
+ ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
+ request.setHTTPBody(m_requestEntityBody.release());
+ }
+
if (m_async)
loadRequestAsynchronously(request);
else
loadRequestSynchronously(request, ec);
}
-void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
+void XMLHttpRequest::makeCrossOriginAccessRequestWithPreflight(ExceptionCode& ec)
{
String origin = scriptExecutionContext()->securityOrigin()->toString();
KURL url = m_url;
url.setUser(String());
url.setPass(String());
- if (!PreflightResultCache::shared().canSkipPreflight(origin, url, m_includeCredentials, m_method, m_requestHeaders)) {
+ if (!CrossOriginPreflightResultCache::shared().canSkipPreflight(origin, url, m_includeCredentials, m_method, m_requestHeaders)) {
m_inPreflight = true;
ResourceRequest preflightRequest(url);
preflightRequest.setHTTPMethod("OPTIONS");
@@ -739,6 +581,7 @@ void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
}
if (m_async) {
+ m_uploadEventsAllowed = true;
loadRequestAsynchronously(preflightRequest);
return;
}
@@ -761,10 +604,12 @@ void XMLHttpRequest::makeCrossSiteAccessRequestWithPreflight(ExceptionCode& ec)
if (m_requestEntityBody) {
ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
request.setHTTPBody(m_requestEntityBody.release());
}
if (m_async) {
+ m_uploadEventsAllowed = true;
loadRequestAsynchronously(request);
return;
}
@@ -793,53 +638,43 @@ void XMLHttpRequest::handleAsynchronousPreflightResult()
if (m_requestEntityBody) {
ASSERT(m_method != "GET");
+ ASSERT(m_method != "HEAD");
request.setHTTPBody(m_requestEntityBody.release());
}
+ m_uploadEventsAllowed = true;
loadRequestAsynchronously(request);
}
void XMLHttpRequest::loadRequestSynchronously(ResourceRequest& request, ExceptionCode& ec)
{
ASSERT(!m_async);
- Vector<char> data;
- ResourceError error;
- ResourceResponse response;
-
- if (document()->frame())
- m_identifier = document()->frame()->loader()->loadResourceSynchronously(request, error, response, data);
m_loader = 0;
+ m_exceptionCode = 0;
+ StoredCredentials storedCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- // No exception for file:/// resources, see <rdar://problem/4962298>.
- // Also, if we have an HTTP response, then it wasn't a network error in fact.
- if (error.isNull() || request.url().isLocalFile() || response.httpStatusCode() > 0) {
- processSyncLoadResults(data, response, ec);
- return;
- }
-
- if (error.isCancellation()) {
- abortError();
- ec = XMLHttpRequestException::ABORT_ERR;
- return;
- }
-
- networkError();
- ec = XMLHttpRequestException::NETWORK_ERR;
+ ThreadableLoader::loadResourceSynchronously(scriptExecutionContext(), request, *this, storedCredentials);
+ if (!m_exceptionCode && m_error)
+ m_exceptionCode = XMLHttpRequestException::NETWORK_ERR;
+ ec = m_exceptionCode;
}
-
void XMLHttpRequest::loadRequestAsynchronously(ResourceRequest& request)
{
ASSERT(m_async);
+ m_exceptionCode = 0;
// SubresourceLoader::create can return null here, for example if we're no longer attached to a page.
// This is true while running onunload handlers.
// FIXME: We need to be able to send XMLHttpRequests from onunload, <http://bugs.webkit.org/show_bug.cgi?id=10904>.
// FIXME: Maybe create can return null for other reasons too?
- // 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(document()->frame(), this, request, false, sendResourceLoadCallbacks, request.url().isLocalFile());
+ LoadCallbacks callbacks = m_inPreflight ? DoNotSendLoadCallbacks : SendLoadCallbacks;
+ StoredCredentials storedCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+
+ if (m_upload)
+ request.setReportUploadProgress(true);
+
+ m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, callbacks, DoNotSniffContent, storedCredentials);
if (m_loader) {
// Neither this object nor the JavaScript wrapper should be deleted while
@@ -863,7 +698,7 @@ void XMLHttpRequest::abort()
if ((m_state <= OPENED && !sendFlag) || m_state == DONE)
m_state = UNSENT;
- else {
+ else {
ASSERT(!m_loader);
changeState(DONE);
m_state = UNSENT;
@@ -872,7 +707,7 @@ void XMLHttpRequest::abort()
dispatchAbortEvent();
if (!m_uploadComplete) {
m_uploadComplete = true;
- if (m_upload)
+ if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchAbortEvent();
}
}
@@ -917,8 +752,7 @@ void XMLHttpRequest::genericError()
clearRequest();
m_error = true;
- // The spec says we should "Synchronously switch the state to DONE." and then "Synchronously dispatch a readystatechange event on the object"
- // but this does not match Firefox.
+ changeState(DONE);
}
void XMLHttpRequest::networkError()
@@ -927,9 +761,10 @@ void XMLHttpRequest::networkError()
dispatchErrorEvent();
if (!m_uploadComplete) {
m_uploadComplete = true;
- if (m_upload)
+ if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchErrorEvent();
}
+ internalAbort();
}
void XMLHttpRequest::abortError()
@@ -938,7 +773,7 @@ void XMLHttpRequest::abortError()
dispatchAbortEvent();
if (!m_uploadComplete) {
m_uploadComplete = true;
- if (m_upload)
+ if (m_upload && m_uploadEventsAllowed)
m_upload->dispatchAbortEvent();
}
}
@@ -953,11 +788,9 @@ void XMLHttpRequest::dropProtection()
// can't be recouped until the load is done, so only
// report the extra cost at that point.
- if (JSDOMWindow* window = toJSDOMWindow(document()->frame())) {
- JSC::JSValuePtr wrapper = getCachedDOMObjectWrapper(*window->globalData(), this);
- if (wrapper)
- JSC::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);
- }
+ if (JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext()))
+ if (DOMObject* wrapper = getCachedDOMObjectWrapper(*globalObject->globalData(), this))
+ JSC::Heap::heap(wrapper)->reportExtraMemoryCost(m_responseText.size() * 2);
#endif
unsetPendingActivity(this);
@@ -968,24 +801,20 @@ void XMLHttpRequest::overrideMimeType(const String& override)
m_mimeTypeOverride = override;
}
-static void reportUnsafeUsage(Document* document, const String& message)
+static void reportUnsafeUsage(ScriptExecutionContext* context, const String& message)
{
- if (!document)
- return;
- Frame* frame = document->frame();
- if (!frame)
+ if (!context)
return;
- // It's not good to report the bad usage without indicating what source line it came from.
+ // FIXME: It's not good to report the bad usage without indicating what source line it came from.
// We should pass additional parameters so we can tell the console where the mistake occurred.
- frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 1, String());
+ context->addMessage(ConsoleDestination, JSMessageSource, ErrorMessageLevel, message, 1, String());
}
void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& value, ExceptionCode& ec)
{
if (m_state != OPENED || m_loader) {
#if ENABLE(DASHBOARD_SUPPORT)
- Settings* settings = document() ? document()->settings() : 0;
- if (settings && settings->usesDashboardBackwardCompatibilityMode())
+ if (usesDashboardBackwardCompatibilityMode())
return;
#endif
@@ -1000,7 +829,7 @@ void XMLHttpRequest::setRequestHeader(const AtomicString& name, const String& va
// A privileged script (e.g. a Dashboard widget) can set any headers.
if (!scriptExecutionContext()->securityOrigin()->canLoadLocalResources() && !isSafeRequestHeader(name)) {
- reportUnsafeUsage(document(), "Refused to set unsafe header \"" + name + "\"");
+ reportUnsafeUsage(scriptExecutionContext(), "Refused to set unsafe header \"" + name + "\"");
return;
}
@@ -1071,23 +900,18 @@ String XMLHttpRequest::getResponseHeader(const AtomicString& name, ExceptionCode
// See comment in getAllResponseHeaders above.
if (isSetCookieHeader(name) && !scriptExecutionContext()->securityOrigin()->canLoadLocalResources()) {
- reportUnsafeUsage(document(), "Refused to get unsafe header \"" + name + "\"");
+ reportUnsafeUsage(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
return "";
}
if (!m_sameOriginRequest && !isOnAccessControlResponseHeaderWhitelist(name)) {
- reportUnsafeUsage(document(), "Refused to get unsafe header \"" + name + "\"");
+ reportUnsafeUsage(scriptExecutionContext(), "Refused to get unsafe header \"" + name + "\"");
return "";
}
return m_response.httpHeaderField(name);
}
-bool XMLHttpRequest::isOnAccessControlResponseHeaderWhitelist(const String& name) const
-{
- return staticData->m_allowedCrossSiteResponseHeaders.contains(name);
-}
-
String XMLHttpRequest::responseMIMEType() const
{
String mimeType = extractMIMETypeFromMediaType(m_mimeTypeOverride);
@@ -1124,76 +948,56 @@ int XMLHttpRequest::status(ExceptionCode& ec) const
String XMLHttpRequest::statusText(ExceptionCode& ec) const
{
- // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=3547> XMLHttpRequest.statusText returns always "OK".
- if (m_response.httpStatusCode())
- return "OK";
+ if (!m_response.httpStatusText().isNull())
+ return m_response.httpStatusText();
if (m_state == OPENED) {
- // See comments in getStatus() above.
+ // See comments in status() above.
ec = INVALID_STATE_ERR;
}
return String();
}
-void XMLHttpRequest::processSyncLoadResults(const Vector<char>& data, const ResourceResponse& response, ExceptionCode& ec)
-{
- if (m_sameOriginRequest && !scriptExecutionContext()->securityOrigin()->canRequest(response.url())) {
- abort();
- return;
- }
-
- didReceiveResponse(0, response);
- changeState(HEADERS_RECEIVED);
-
- const char* bytes = static_cast<const char*>(data.data());
- int len = static_cast<int>(data.size());
- didReceiveData(0, bytes, len);
-
- didFinishLoading(0);
- if (m_error)
- ec = XMLHttpRequestException::NETWORK_ERR;
-}
-
-void XMLHttpRequest::didFail(SubresourceLoader*, const ResourceError& error)
+void XMLHttpRequest::didFail(const ResourceError& error)
{
// If we are already in an error state, for instance we called abort(), bail out early.
if (m_error)
return;
if (error.isCancellation()) {
+ m_exceptionCode = XMLHttpRequestException::ABORT_ERR;
abortError();
return;
}
+ m_exceptionCode = XMLHttpRequestException::NETWORK_ERR;
networkError();
- return;
}
-void XMLHttpRequest::didFinishLoading(SubresourceLoader* loader)
+void XMLHttpRequest::didFailRedirectCheck()
+{
+ networkError();
+}
+
+void XMLHttpRequest::didFinishLoading(unsigned long identifier)
{
if (m_error)
return;
if (m_inPreflight) {
- didFinishLoadingPreflight(loader);
+ didFinishLoadingPreflight();
return;
}
- ASSERT(loader == m_loader);
-
if (m_state < HEADERS_RECEIVED)
changeState(HEADERS_RECEIVED);
if (m_decoder)
m_responseText += m_decoder->flush();
- 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);
- }
- }
+ scriptExecutionContext()->resourceRetrievedByXMLHttpRequest(identifier, m_responseText);
+ scriptExecutionContext()->addMessage(InspectorControllerDestination, JSMessageSource, LogMessageLevel, "XHR finished loading: \"" + m_url + "\".", m_lastSendLineNumber, m_lastSendURL);
bool hadLoader = m_loader;
m_loader = 0;
@@ -1205,7 +1009,7 @@ void XMLHttpRequest::didFinishLoading(SubresourceLoader* loader)
dropProtection();
}
-void XMLHttpRequest::didFinishLoadingPreflight(SubresourceLoader*)
+void XMLHttpRequest::didFinishLoadingPreflight()
{
ASSERT(m_inPreflight);
ASSERT(!m_sameOriginRequest);
@@ -1218,60 +1022,30 @@ void XMLHttpRequest::didFinishLoadingPreflight(SubresourceLoader*)
unsetPendingActivity(this);
}
-void XMLHttpRequest::willSendRequest(SubresourceLoader*, ResourceRequest& request, const ResourceResponse&)
-{
- // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
- if (!scriptExecutionContext()->securityOrigin()->canRequest(request.url())) {
- internalAbort();
- networkError();
- }
-}
-
-void XMLHttpRequest::didSendData(SubresourceLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
if (!m_upload)
return;
- m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
+ if (m_uploadEventsAllowed)
+ m_upload->dispatchProgressEvent(bytesSent, totalBytesToBeSent);
if (bytesSent == totalBytesToBeSent && !m_uploadComplete) {
m_uploadComplete = true;
- m_upload->dispatchLoadEvent();
+ if (m_uploadEventsAllowed)
+ m_upload->dispatchLoadEvent();
}
}
-bool XMLHttpRequest::accessControlCheck(const ResourceResponse& response)
-{
- const String& accessControlOriginString = response.httpHeaderField("Access-Control-Origin");
- if (accessControlOriginString == "*" && !m_includeCredentials)
- return true;
-
- KURL accessControlOriginURL(accessControlOriginString);
- if (!accessControlOriginURL.isValid())
- return false;
-
- RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::create(accessControlOriginURL);
- if (!accessControlOrigin->isSameSchemeHostPort(scriptExecutionContext()->securityOrigin()))
- return false;
-
- if (m_includeCredentials) {
- const String& accessControlCredentialsString = response.httpHeaderField("Access-Control-Credentials");
- if (accessControlCredentialsString != "true")
- return false;
- }
-
- return true;
-}
-
-void XMLHttpRequest::didReceiveResponse(SubresourceLoader* loader, const ResourceResponse& response)
+void XMLHttpRequest::didReceiveResponse(const ResourceResponse& response)
{
if (m_inPreflight) {
- didReceiveResponsePreflight(loader, response);
+ didReceiveResponsePreflight(response);
return;
}
if (!m_sameOriginRequest) {
- if (!accessControlCheck(response)) {
+ if (!passesAccessControlCheck(response, m_includeCredentials, scriptExecutionContext()->securityOrigin())) {
networkError();
return;
}
@@ -1283,43 +1057,35 @@ void XMLHttpRequest::didReceiveResponse(SubresourceLoader* loader, const Resourc
m_responseEncoding = response.textEncodingName();
}
-void XMLHttpRequest::didReceiveResponsePreflight(SubresourceLoader*, const ResourceResponse& response)
+void XMLHttpRequest::didReceiveResponsePreflight(const ResourceResponse& response)
{
ASSERT(m_inPreflight);
ASSERT(!m_sameOriginRequest);
- if (!accessControlCheck(response)) {
- networkError();
- return;
- }
-
- OwnPtr<PreflightResultCacheItem> preflightResult(new PreflightResultCacheItem(m_includeCredentials));
- if (!preflightResult->parse(response)) {
+ if (!passesAccessControlCheck(response, m_includeCredentials, scriptExecutionContext()->securityOrigin())) {
networkError();
return;
}
- if (!preflightResult->allowsCrossSiteMethod(m_method)) {
+ OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult(new CrossOriginPreflightResultCacheItem(m_includeCredentials));
+ if (!preflightResult->parse(response)
+ || !preflightResult->allowsCrossOriginMethod(m_method)
+ || !preflightResult->allowsCrossOriginHeaders(m_requestHeaders)) {
networkError();
return;
}
- if (!preflightResult->allowsCrossSiteHeaders(m_requestHeaders)) {
- networkError();
- return;
- }
-
- PreflightResultCache::shared().appendEntry(scriptExecutionContext()->securityOrigin()->toString(), m_url, preflightResult.release());
+ CrossOriginPreflightResultCache::shared().appendEntry(scriptExecutionContext()->securityOrigin()->toString(), m_url, preflightResult.release());
}
-void XMLHttpRequest::receivedCancellation(SubresourceLoader*, const AuthenticationChallenge& challenge)
+void XMLHttpRequest::didReceiveAuthenticationCancellation(const ResourceResponse& failureResponse)
{
- m_response = challenge.failureResponse();
+ m_response = failureResponse;
}
-void XMLHttpRequest::didReceiveData(SubresourceLoader*, const char* data, int len)
+void XMLHttpRequest::didReceiveData(const char* data, int len)
{
- if (m_inPreflight)
+ if (m_inPreflight || m_error)
return;
if (m_state < HEADERS_RECEIVED)
@@ -1329,14 +1095,17 @@ void XMLHttpRequest::didReceiveData(SubresourceLoader*, const char* data, int le
if (!m_responseEncoding.isEmpty())
m_decoder = TextResourceDecoder::create("text/plain", m_responseEncoding);
// allow TextResourceDecoder to look inside the m_response if it's XML or HTML
- else if (responseIsXML())
+ else if (responseIsXML()) {
m_decoder = TextResourceDecoder::create("application/xml");
- else if (responseMIMEType() == "text/html")
+ // Don't stop on encoding errors, unlike it is done for other kinds of XML resources. This matches the behavior of previous WebKit versions, Firefox and Opera.
+ m_decoder->useLenientXMLDecoding();
+ } else if (responseMIMEType() == "text/html")
m_decoder = TextResourceDecoder::create("text/html", "UTF-8");
else
m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");
}
- if (len == 0)
+
+ if (!len)
return;
if (len == -1)
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h
index 858f228..6955c11 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.h
@@ -26,19 +26,21 @@
#include "EventTarget.h"
#include "FormData.h"
#include "ResourceResponse.h"
-#include "SubresourceLoaderClient.h"
#include "ScriptString.h"
+#include "ThreadableLoaderClient.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
class Document;
class File;
+struct ResourceRequest;
class TextResourceDecoder;
+class ThreadableLoader;
-class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private SubresourceLoaderClient, public ActiveDOMObject {
+class XMLHttpRequest : public RefCounted<XMLHttpRequest>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
public:
- static PassRefPtr<XMLHttpRequest> create(Document* document) { return adoptRef(new XMLHttpRequest(document)); }
+ static PassRefPtr<XMLHttpRequest> create(ScriptExecutionContext* context) { return adoptRef(new XMLHttpRequest(context)); }
~XMLHttpRequest();
// These exact numeric values are important because JS expects them.
@@ -61,6 +63,8 @@ public:
String statusText(ExceptionCode&) const;
int status(ExceptionCode&) const;
State readyState() const;
+ bool withCredentials() const { return m_includeCredentials; }
+ void setWithCredentials(bool, ExceptionCode&);
void open(const String& method, const KURL&, bool async, ExceptionCode&);
void open(const String& method, const KURL&, bool async, const String& user, ExceptionCode&);
void open(const String& method, const KURL&, bool async, const String& user, const String& password, ExceptionCode&);
@@ -112,26 +116,29 @@ public:
using RefCounted<XMLHttpRequest>::deref;
private:
- XMLHttpRequest(Document*);
+ XMLHttpRequest(ScriptExecutionContext*);
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
Document* document() const;
- virtual void willSendRequest(SubresourceLoader*, ResourceRequest& request, const ResourceResponse& redirectResponse);
- virtual void didSendData(SubresourceLoader*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
- virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
- virtual void didReceiveData(SubresourceLoader*, const char* data, int size);
- virtual void didFail(SubresourceLoader*, const ResourceError&);
- virtual void didFinishLoading(SubresourceLoader*);
- virtual void receivedCancellation(SubresourceLoader*, const AuthenticationChallenge&);
+#if ENABLE(DASHBOARD_SUPPORT)
+ bool usesDashboardBackwardCompatibilityMode() const;
+#endif
+
+ virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
+ virtual void didReceiveResponse(const ResourceResponse&);
+ virtual void didReceiveData(const char* data, int lengthReceived);
+ virtual void didFinishLoading(unsigned long identifier);
+ virtual void didFail(const ResourceError&);
+ virtual void didFailRedirectCheck();
+ virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
// Special versions for the preflight
- void didReceiveResponsePreflight(SubresourceLoader*, const ResourceResponse&);
- void didFinishLoadingPreflight(SubresourceLoader*);
+ void didReceiveResponsePreflight(const ResourceResponse&);
+ void didFinishLoadingPreflight();
- void processSyncLoadResults(const Vector<char>& data, const ResourceResponse&, ExceptionCode&);
void updateAndDispatchOnProgress(unsigned int len);
String responseMIMEType() const;
@@ -153,21 +160,15 @@ private:
void createRequest(ExceptionCode&);
void makeSameOriginRequest(ExceptionCode&);
- void makeCrossSiteAccessRequest(ExceptionCode&);
+ void makeCrossOriginAccessRequest(ExceptionCode&);
- void makeSimpleCrossSiteAccessRequest(ExceptionCode&);
- void makeCrossSiteAccessRequestWithPreflight(ExceptionCode&);
+ void makeSimpleCrossOriginAccessRequest(ExceptionCode&);
+ void makeCrossOriginAccessRequestWithPreflight(ExceptionCode&);
void handleAsynchronousPreflightResult();
void loadRequestSynchronously(ResourceRequest&, ExceptionCode&);
void loadRequestAsynchronously(ResourceRequest&);
- bool isOnAccessControlResponseHeaderWhitelist(const String&) const;
-
- bool isSimpleCrossSiteAccessRequest() const;
- String accessControlOrigin() const;
- bool accessControlCheck(const ResourceResponse&);
-
void genericError();
void networkError();
void abortError();
@@ -198,16 +199,15 @@ private:
bool m_async;
bool m_includeCredentials;
- RefPtr<SubresourceLoader> m_loader;
+ RefPtr<ThreadableLoader> m_loader;
State m_state;
ResourceResponse m_response;
String m_responseEncoding;
RefPtr<TextResourceDecoder> m_decoder;
- unsigned long m_identifier;
- // Unlike most strings in the DOM, we keep this as a JSC::UString, not a WebCore::String.
+ // Unlike most strings in the DOM, we keep this as a ScriptString, not a WebCore::String.
// That's because these strings can easily get huge (they are filled from the network with
// no parsing) and because JS can easily observe many intermediate states, so it's very useful
// to be able to share the buffer with JavaScript versions of the whole or partial string.
@@ -219,6 +219,7 @@ private:
bool m_error;
+ bool m_uploadEventsAllowed;
bool m_uploadComplete;
bool m_sameOriginRequest;
@@ -230,6 +231,7 @@ private:
unsigned m_lastSendLineNumber;
String m_lastSendURL;
+ ExceptionCode m_exceptionCode;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl
index 315d95c..79005e2 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequest.idl
@@ -29,7 +29,8 @@
module xml {
interface [
- CustomMarkFunction
+ CustomMarkFunction,
+ NoStaticTables
] XMLHttpRequest {
// From XMLHttpRequestEventTarget
// event handler attributes
@@ -52,6 +53,8 @@ module xml {
readonly attribute unsigned short readyState;
// request
+ attribute boolean withCredentials
+ setter raises(DOMException);
// void open(in DOMString method, in DOMString url);
// void open(in DOMString method, in DOMString url, in boolean async);
// void open(in DOMString method, in DOMString url, in boolean async, in DOMString user);
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestException.idl b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestException.idl
index 2feb574..380e426 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestException.idl
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestException.idl
@@ -29,14 +29,15 @@
module xml {
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
] XMLHttpRequestException {
readonly attribute unsigned short code;
readonly attribute DOMString name;
readonly attribute DOMString message;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// Override in a Mozilla compatible format
[DontEnum] DOMString toString();
#endif
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.idl b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.idl
index 6de9690..549308b 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.idl
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestProgressEvent.idl
@@ -26,7 +26,8 @@
module events {
interface [
- GenerateConstructor
+ GenerateConstructor,
+ NoStaticTables
// We should also inherit from LSProgressEvent when the idl is added.
] XMLHttpRequestProgressEvent : ProgressEvent {
readonly attribute unsigned long position;
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp
index a58c271..d8a76d5 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.cpp
@@ -30,7 +30,6 @@
#include "Event.h"
#include "EventException.h"
#include "EventNames.h"
-#include "Frame.h"
#include "XMLHttpRequest.h"
#include "XMLHttpRequestProgressEvent.h"
#include <wtf/Assertions.h>
@@ -42,6 +41,11 @@ XMLHttpRequestUpload::XMLHttpRequestUpload(XMLHttpRequest* xmlHttpRequest)
{
}
+bool XMLHttpRequestUpload::hasListeners() const
+{
+ return m_onAbortListener || m_onErrorListener || m_onLoadListener || m_onLoadStartListener || m_onProgressListener || !m_eventListeners.isEmpty();
+}
+
ScriptExecutionContext* XMLHttpRequestUpload::scriptExecutionContext() const
{
XMLHttpRequest* xmlHttpRequest = associatedXMLHttpRequest();
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h
index 93fa7f9..b4f40e0 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.h
@@ -48,6 +48,8 @@ namespace WebCore {
return adoptRef(new XMLHttpRequestUpload(xmlHttpRequest));
}
+ bool hasListeners() const;
+
virtual XMLHttpRequestUpload* toXMLHttpRequestUpload() { return this; }
XMLHttpRequest* associatedXMLHttpRequest() const { return m_xmlHttpRequest; }
diff --git a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl
index c066710..3172f68 100644
--- a/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl
+++ b/src/3rdparty/webkit/WebCore/xml/XMLHttpRequestUpload.idl
@@ -30,7 +30,8 @@ module xml {
interface [
GenerateConstructor,
- CustomMarkFunction
+ CustomMarkFunction,
+ NoStaticTables
] XMLHttpRequestUpload {
// From XMLHttpRequestEventTarget
// event handler attributes
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathException.idl b/src/3rdparty/webkit/WebCore/xml/XPathException.idl
index 6e25514..c3c95e3 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathException.idl
+++ b/src/3rdparty/webkit/WebCore/xml/XPathException.idl
@@ -37,7 +37,7 @@ module xpath {
readonly attribute DOMString name;
readonly attribute DOMString message;
-#if defined(LANGUAGE_JAVASCRIPT)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
// Override in a Mozilla compatible format
[DontEnum] DOMString toString();
#endif
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathExpression.cpp b/src/3rdparty/webkit/WebCore/xml/XPathExpression.cpp
index 446a7ad..6188426 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathExpression.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathExpression.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,9 +30,8 @@
#if ENABLE(XPATH)
#include "Document.h"
-#include "ExceptionCode.h"
-#include "Node.h"
#include "PlatformString.h"
+#include "XPathException.h"
#include "XPathExpressionNode.h"
#include "XPathNSResolver.h"
#include "XPathParser.h"
@@ -67,17 +66,21 @@ PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned sh
return 0;
}
- EventTargetNode* eventTarget = contextNode->ownerDocument()
- ? contextNode->ownerDocument()
- : static_cast<EventTargetNode*>(contextNode);
-
EvaluationContext& evaluationContext = Expression::evaluationContext();
evaluationContext.node = contextNode;
evaluationContext.size = 1;
evaluationContext.position = 1;
- RefPtr<XPathResult> result = XPathResult::create(eventTarget, m_topExpression->evaluate());
+ evaluationContext.hadTypeConversionError = false;
+ RefPtr<XPathResult> result = XPathResult::create(contextNode->document(), m_topExpression->evaluate());
evaluationContext.node = 0; // Do not hold a reference to the context node, as this may prevent the whole document from being destroyed in time.
+ if (evaluationContext.hadTypeConversionError) {
+ // It is not specified what to do if type conversion fails while evaluating an expression, and INVALID_EXPRESSION_ERR is not exactly right
+ // when the failure happens in an otherwise valid expression because of a variable. But XPathEvaluator does not support variables, so it's close enough.
+ ec = XPathException::INVALID_EXPRESSION_ERR;
+ return 0;
+ }
+
if (type != XPathResult::ANY_TYPE) {
ec = 0;
result->convertTo(type, ec);
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.cpp b/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.cpp
index 647c6af..4656f8d 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.cpp
@@ -30,7 +30,6 @@
#if ENABLE(XPATH)
#include "Node.h"
-#include "XPathValue.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
@@ -43,6 +42,9 @@ EvaluationContext& Expression::evaluationContext()
}
Expression::Expression()
+ : m_isContextNodeSensitive(false)
+ , m_isContextPositionSensitive(false)
+ , m_isContextSizeSensitive(false)
{
}
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.h b/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.h
index 9c5f79b..d12b451 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathExpressionNode.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,23 +31,21 @@
#include "StringHash.h"
#include "Node.h"
+#include "XPathValue.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
namespace WebCore {
namespace XPath {
-
- class Value;
struct EvaluationContext {
- EvaluationContext() : node(0), size(0), position(0) { }
-
RefPtr<Node> node;
unsigned long size;
unsigned long position;
HashMap<String, String> variableBindings;
+ bool hadTypeConversionError;
};
class ParseNode {
@@ -64,7 +62,22 @@ namespace WebCore {
virtual Value evaluate() const = 0;
- void addSubExpression(Expression* expr) { m_subExpressions.append(expr); }
+ void addSubExpression(Expression* expr)
+ {
+ m_subExpressions.append(expr);
+ m_isContextNodeSensitive |= expr->m_isContextNodeSensitive;
+ m_isContextPositionSensitive |= expr->m_isContextPositionSensitive;
+ m_isContextSizeSensitive |= expr->m_isContextSizeSensitive;
+ }
+
+ bool isContextNodeSensitive() const { return m_isContextNodeSensitive; }
+ bool isContextPositionSensitive() const { return m_isContextPositionSensitive; }
+ bool isContextSizeSensitive() const { return m_isContextSizeSensitive; }
+ void setIsContextNodeSensitive(bool value) { m_isContextNodeSensitive = value; }
+ void setIsContextPositionSensitive(bool value) { m_isContextPositionSensitive = value; }
+ void setIsContextSizeSensitive(bool value) { m_isContextSizeSensitive = value; }
+
+ virtual Value::Type resultType() const = 0;
protected:
unsigned subExprCount() const { return m_subExpressions.size(); }
@@ -73,6 +86,11 @@ namespace WebCore {
private:
Vector<Expression*> m_subExpressions;
+
+ // Evaluation details that can be used for optimization.
+ bool m_isContextNodeSensitive;
+ bool m_isContextPositionSensitive;
+ bool m_isContextSizeSensitive;
};
}
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathFunctions.cpp b/src/3rdparty/webkit/WebCore/xml/XPathFunctions.cpp
index 841b436..da39443 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathFunctions.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathFunctions.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,8 @@
#include "Document.h"
#include "Element.h"
-#include "NamedAttrMap.h"
+#include "NamedNodeMap.h"
+#include "ProcessingInstruction.h"
#include "XMLNames.h"
#include "XPathUtil.h"
#include "XPathValue.h"
@@ -74,110 +75,157 @@ static HashMap<String, FunctionRec>* functionMap;
class FunLast : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
+public:
+ FunLast() { setIsContextSizeSensitive(true); }
};
class FunPosition : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
+public:
+ FunPosition() { setIsContextPositionSensitive(true); }
};
class FunCount : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
};
class FunId : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NodeSetValue; }
};
class FunLocalName : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
+public:
+ FunLocalName() { setIsContextNodeSensitive(true); } // local-name() with no arguments uses context node.
};
class FunNamespaceURI : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
+public:
+ FunNamespaceURI() { setIsContextNodeSensitive(true); } // namespace-uri() with no arguments uses context node.
};
class FunName : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
+public:
+ FunName() { setIsContextNodeSensitive(true); } // name() with no arguments uses context node.
};
class FunString : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
+public:
+ FunString() { setIsContextNodeSensitive(true); } // string() with no arguments uses context node.
};
class FunConcat : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
};
class FunStartsWith : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
};
class FunContains : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
};
class FunSubstringBefore : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
};
class FunSubstringAfter : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
};
class FunSubstring : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
};
class FunStringLength : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
+public:
+ FunStringLength() { setIsContextNodeSensitive(true); } // string-length() with no arguments uses context node.
};
class FunNormalizeSpace : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
+public:
+ FunNormalizeSpace() { setIsContextNodeSensitive(true); } // normalize-space() with no arguments uses context node.
};
class FunTranslate : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
};
class FunBoolean : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
};
class FunNot : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
};
class FunTrue : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
};
class FunFalse : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
};
class FunLang : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
+public:
+ FunLang() { setIsContextNodeSensitive(true); } // lang() always works on context node.
};
class FunNumber : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
+public:
+ FunNumber() { setIsContextNodeSensitive(true); } // number() with no arguments uses context node.
};
class FunSum : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
};
class FunFloor : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
};
class FunCeiling : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
};
class FunRound : public Function {
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
public:
static double round(double);
};
@@ -246,8 +294,13 @@ inline bool Interval::contains(int value) const
void Function::setArguments(const Vector<Expression*>& args)
{
- Vector<Expression*>::const_iterator end = args.end();
+ ASSERT(!subExprCount());
+
+ // Some functions use context node as implicit argument, so when explicit arguments are added, they may no longer be context node sensitive.
+ if (m_name != "lang" && !args.isEmpty())
+ setIsContextNodeSensitive(false);
+ Vector<Expression*>::const_iterator end = args.end();
for (Vector<Expression*>::const_iterator it = args.begin(); it != end; it++)
addSubExpression(*it);
}
@@ -310,71 +363,67 @@ Value FunId::evaluate() const
return Value(result, Value::adopt);
}
+static inline String expandedNameLocalPart(Node* node)
+{
+ // The local part of an XPath expanded-name matches DOM local name for most node types, except for namespace nodes and processing instruction nodes.
+ ASSERT(node->nodeType() != Node::XPATH_NAMESPACE_NODE); // Not supported yet.
+ if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
+ return static_cast<ProcessingInstruction*>(node)->target();
+ return node->localName().string();
+}
+
+static inline String expandedName(Node* node)
+{
+ const AtomicString& prefix = node->prefix();
+ return prefix.isEmpty() ? expandedNameLocalPart(node) : prefix + ":" + expandedNameLocalPart(node);
+}
+
Value FunLocalName::evaluate() const
{
- Node* node = 0;
if (argCount() > 0) {
Value a = arg(0)->evaluate();
if (!a.isNodeSet())
return "";
- node = a.toNodeSet().firstNode();
- if (!node)
- return "";
+ Node* node = a.toNodeSet().firstNode();
+ return node ? expandedNameLocalPart(node) : "";
}
- if (!node)
- node = evaluationContext().node.get();
-
- return node->localName().string();
+ return expandedNameLocalPart(evaluationContext().node.get());
}
Value FunNamespaceURI::evaluate() const
{
- Node* node = 0;
if (argCount() > 0) {
Value a = arg(0)->evaluate();
if (!a.isNodeSet())
return "";
- node = a.toNodeSet().firstNode();
- if (!node)
- return "";
+ Node* node = a.toNodeSet().firstNode();
+ return node ? node->namespaceURI().string() : "";
}
- if (!node)
- node = evaluationContext().node.get();
-
- return node->namespaceURI().string();
+ return evaluationContext().node->namespaceURI().string();
}
Value FunName::evaluate() const
{
- Node* node = 0;
if (argCount() > 0) {
Value a = arg(0)->evaluate();
if (!a.isNodeSet())
return "";
- node = a.toNodeSet().firstNode();
- if (!node)
- return "";
+ Node* node = a.toNodeSet().firstNode();
+ return node ? expandedName(node) : "";
}
- if (!node)
- node = evaluationContext().node.get();
-
- const AtomicString& prefix = node->prefix();
- return prefix.isEmpty() ? node->localName().string() : prefix + ":" + node->localName();
+ return expandedName(evaluationContext().node.get());
}
Value FunCount::evaluate() const
{
Value a = arg(0)->evaluate();
- if (!a.isNodeSet())
- return 0.0;
-
return double(a.toNodeSet().size());
}
@@ -534,30 +583,30 @@ Value FunLang::evaluate() const
{
String lang = arg(0)->evaluate().toString();
- RefPtr<Node> langNode = 0;
+ Attribute* languageAttribute = 0;
Node* node = evaluationContext().node.get();
while (node) {
- NamedAttrMap* attrs = node->attributes();
+ NamedNodeMap* attrs = node->attributes();
if (attrs)
- langNode = attrs->getNamedItemNS(XMLNames::xmlNamespaceURI, "lang");
- if (langNode)
+ languageAttribute = attrs->getAttributeItem(XMLNames::langAttr);
+ if (languageAttribute)
break;
node = node->parentNode();
}
- if (!langNode)
+ if (!languageAttribute)
return false;
- String langNodeValue = langNode->nodeValue();
+ String langValue = languageAttribute->value();
while (true) {
- if (equalIgnoringCase(langNodeValue, lang))
+ if (equalIgnoringCase(langValue, lang))
return true;
// Remove suffixes one by one.
- int index = langNodeValue.reverseFind('-');
+ int index = langValue.reverseFind('-');
if (index == -1)
break;
- langNodeValue = langNodeValue.left(index);
+ langValue = langValue.left(index);
}
return false;
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathFunctions.h b/src/3rdparty/webkit/WebCore/xml/XPathFunctions.h
index f22d3ef..62d687f 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathFunctions.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathFunctions.h
@@ -1,6 +1,6 @@
/*
- * functions.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +39,6 @@ namespace WebCore {
public:
void setArguments(const Vector<Expression*>&);
void setName(const String& name) { m_name = name; }
-
protected:
Expression* arg(int pos) { return subExpr(pos); }
const Expression* arg(int pos) const { return subExpr(pos); }
@@ -52,11 +51,10 @@ namespace WebCore {
Function* createFunction(const String& name, const Vector<Expression*>& args = Vector<Expression*>());
- }
+ } // namespace XPath
-}
+} // namespace WebCore
#endif // ENABLE(XPATH)
-#endif // XPath_Functions_H
-
+#endif // XPathFunctions_h
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathGrammar.y b/src/3rdparty/webkit/WebCore/xml/XPathGrammar.y
index 7b21038..15a859b 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathGrammar.y
+++ b/src/3rdparty/webkit/WebCore/xml/XPathGrammar.y
@@ -68,8 +68,8 @@ using namespace XPath;
%{
-int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); }
-void xpathyyerror(const char*) { }
+static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); }
+static void xpathyyerror(const char*) { }
%}
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.cpp b/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.cpp
index e29c096..ba9423e 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.cpp
@@ -162,7 +162,7 @@ void NodeSet::sort() const
// It is not possible to just assign the result to m_nodes, because some nodes may get dereferenced and destroyed.
Vector<RefPtr<Node> > sortedNodes;
- sortedNodes.reserveCapacity(nodeCount);
+ sortedNodes.reserveInitialCapacity(nodeCount);
for (unsigned i = 0; i < nodeCount; ++i)
sortedNodes.append(parentMatrix[i][0]);
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.h b/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.h
index 2ab6f1f..1130488 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathNodeSet.h
@@ -39,17 +39,14 @@ namespace WebCore {
class NodeSet {
public:
-
- NodeSet() : m_isSorted(true) {}
- NodeSet(const NodeSet& other) : m_isSorted(other.m_isSorted), m_nodes(other.m_nodes) {}
- NodeSet& operator=(const NodeSet& other) { m_isSorted = other.m_isSorted; m_nodes = other.m_nodes; return *this; }
+ NodeSet() : m_isSorted(true), m_subtreesAreDisjoint(false) { }
size_t size() const { return m_nodes.size(); }
bool isEmpty() const { return !m_nodes.size(); }
Node* operator[](unsigned i) const { return m_nodes.at(i).get(); }
void reserveCapacity(size_t newCapacity) { m_nodes.reserveCapacity(newCapacity); }
void clear() { m_nodes.clear(); }
- void swap(NodeSet& other) { std::swap(m_isSorted, other.m_isSorted); m_nodes.swap(other.m_nodes); }
+ void swap(NodeSet& other) { std::swap(m_isSorted, other.m_isSorted); std::swap(m_subtreesAreDisjoint, other.m_subtreesAreDisjoint); m_nodes.swap(other.m_nodes); }
// NodeSet itself does not verify that nodes in it are unique.
void append(Node* node) { m_nodes.append(node); }
@@ -62,16 +59,21 @@ namespace WebCore {
// Returns 0 if the set is empty.
Node* anyNode() const;
- // NodeSet itself doesn't check if it is contains sorted data - the caller should tell it if it does not.
+ // NodeSet itself doesn't check if it contains nodes in document order - the caller should tell it if it does not.
void markSorted(bool isSorted) { m_isSorted = isSorted; }
- bool isSorted() const { return m_isSorted; }
+ bool isSorted() const { return m_isSorted || m_nodes.size() < 2; }
void sort() const;
+ // No node in the set is ancestor of another. Unlike m_isSorted, this is assumed to be false, unless the caller sets it to true.
+ void markSubtreesDisjoint(bool disjoint) { m_subtreesAreDisjoint = disjoint; }
+ bool subtreesAreDisjoint() const { return m_subtreesAreDisjoint || m_nodes.size() < 2; }
+
void reverse();
private:
bool m_isSorted;
+ bool m_subtreesAreDisjoint;
Vector<RefPtr<Node> > m_nodes;
};
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathPath.cpp b/src/3rdparty/webkit/WebCore/xml/XPathPath.cpp
index bc7b153..1a7ed3f 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathPath.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathPath.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,9 @@ namespace XPath {
Filter::Filter(Expression* expr, const Vector<Predicate*>& predicates)
: m_expr(expr), m_predicates(predicates)
{
+ setIsContextNodeSensitive(m_expr->isContextNodeSensitive());
+ setIsContextPositionSensitive(m_expr->isContextPositionSensitive());
+ setIsContextSizeSensitive(m_expr->isContextSizeSensitive());
}
Filter::~Filter()
@@ -53,9 +56,6 @@ Value Filter::evaluate() const
{
Value v = m_expr->evaluate();
- if (!v.isNodeSet())
- return v;
-
NodeSet& nodes = v.modifiableNodeSet();
nodes.sort();
@@ -83,6 +83,7 @@ Value Filter::evaluate() const
LocationPath::LocationPath()
: m_absolute(false)
{
+ setIsContextNodeSensitive(true);
}
LocationPath::~LocationPath()
@@ -94,9 +95,8 @@ Value LocationPath::evaluate() const
{
EvaluationContext& evaluationContext = Expression::evaluationContext();
EvaluationContext backupContext = evaluationContext;
- /* For absolute location paths, the context node is ignored - the
- * document's root node is used instead.
- */
+ // For absolute location paths, the context node is ignored - the
+ // document's root node is used instead.
Node* context = evaluationContext.node.get();
if (m_absolute && context->nodeType() != Node::DOCUMENT_NODE)
context = context->ownerDocument();
@@ -111,18 +111,33 @@ Value LocationPath::evaluate() const
void LocationPath::evaluate(NodeSet& nodes) const
{
+ bool resultIsSorted = nodes.isSorted();
+
for (unsigned i = 0; i < m_steps.size(); i++) {
Step* step = m_steps[i];
NodeSet newNodes;
HashSet<Node*> newNodesSet;
+ bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis
+ && step->axis() != Step::DescendantAxis && step->axis() != Step::DescendantOrSelfAxis && step->axis() != Step::AttributeAxis);
+
+ if (needToCheckForDuplicateNodes)
+ resultIsSorted = false;
+
+ // This is a simplified check that can be improved to handle more cases.
+ if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis))
+ newNodes.markSubtreesDisjoint(true);
+
for (unsigned j = 0; j < nodes.size(); j++) {
NodeSet matches;
step->evaluate(nodes[j], matches);
-
+
+ if (!matches.isSorted())
+ resultIsSorted = false;
+
for (size_t nodeIndex = 0; nodeIndex < matches.size(); ++nodeIndex) {
Node* node = matches[nodeIndex];
- if (newNodesSet.add(node).second)
+ if (!needToCheckForDuplicateNodes || newNodesSet.add(node).second)
newNodes.append(node);
}
}
@@ -130,53 +145,46 @@ void LocationPath::evaluate(NodeSet& nodes) const
nodes.swap(newNodes);
}
- nodes.markSorted(false);
+ nodes.markSorted(resultIsSorted);
}
-void LocationPath::optimizeStepPair(unsigned index)
+void LocationPath::appendStep(Step* step)
{
- Step* first = m_steps[index];
-
- if (first->axis() == Step::DescendantOrSelfAxis
- && first->nodeTest().kind() == Step::NodeTest::AnyNodeTest
- && first->predicates().size() == 0) {
-
- Step* second = m_steps[index + 1];
- if (second->axis() == Step::ChildAxis
- && second->nodeTest().namespaceURI().isEmpty()
- && second->nodeTest().kind() == Step::NodeTest::NameTest
- && second->nodeTest().data() == "*") {
-
- // Optimize the common case of "//*" AKA descendant-or-self::node()/child::*.
- first->setAxis(Step::DescendantAxis);
- second->setAxis(Step::SelfAxis);
- second->setNodeTest(Step::NodeTest::ElementNodeTest);
- ASSERT(second->nodeTest().data().isEmpty());
+ unsigned stepCount = m_steps.size();
+ if (stepCount) {
+ bool dropSecondStep;
+ optimizeStepPair(m_steps[stepCount - 1], step, dropSecondStep);
+ if (dropSecondStep) {
+ delete step;
+ return;
}
}
-}
-
-void LocationPath::appendStep(Step* step)
-{
+ step->optimize();
m_steps.append(step);
-
- unsigned stepCount = m_steps.size();
- if (stepCount > 1)
- optimizeStepPair(stepCount - 2);
}
void LocationPath::insertFirstStep(Step* step)
{
+ if (m_steps.size()) {
+ bool dropSecondStep;
+ optimizeStepPair(step, m_steps[0], dropSecondStep);
+ if (dropSecondStep) {
+ delete m_steps[0];
+ m_steps[0] = step;
+ return;
+ }
+ }
+ step->optimize();
m_steps.insert(0, step);
-
- if (m_steps.size() > 1)
- optimizeStepPair(0);
}
Path::Path(Filter* filter, LocationPath* path)
- : m_filter(filter),
- m_path(path)
+ : m_filter(filter)
+ , m_path(path)
{
+ setIsContextNodeSensitive(filter->isContextNodeSensitive());
+ setIsContextPositionSensitive(filter->isContextPositionSensitive());
+ setIsContextSizeSensitive(filter->isContextSizeSensitive());
}
Path::~Path()
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathPath.h b/src/3rdparty/webkit/WebCore/xml/XPathPath.h
index 97692b2..dc77971 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathPath.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathPath.h
@@ -1,6 +1,6 @@
/*
- * path.h - Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,8 +32,6 @@
#include "XPathExpressionNode.h"
#include "XPathNodeSet.h"
-int xpathyyparse(void*);
-
namespace WebCore {
namespace XPath {
@@ -49,6 +47,8 @@ namespace WebCore {
virtual Value evaluate() const;
private:
+ virtual Value::Type resultType() const { return Value::NodeSetValue; }
+
Expression* m_expr;
Vector<Predicate*> m_predicates;
};
@@ -57,7 +57,7 @@ namespace WebCore {
public:
LocationPath();
virtual ~LocationPath();
- void setAbsolute(bool value) { m_absolute = value; }
+ void setAbsolute(bool value) { m_absolute = value; setIsContextNodeSensitive(!m_absolute); }
virtual Value evaluate() const;
void evaluate(NodeSet& nodes) const; // nodes is an input/output parameter
@@ -66,7 +66,7 @@ namespace WebCore {
void insertFirstStep(Step* step);
private:
- void optimizeStepPair(unsigned index);
+ virtual Value::Type resultType() const { return Value::NodeSetValue; }
Vector<Step*> m_steps;
bool m_absolute;
@@ -81,6 +81,8 @@ namespace WebCore {
virtual Value evaluate() const;
private:
+ virtual Value::Type resultType() const { return Value::NodeSetValue; }
+
Filter* m_filter;
LocationPath* m_path;
};
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathPredicate.cpp b/src/3rdparty/webkit/WebCore/xml/XPathPredicate.cpp
index 7b3e4d8..2a6482f 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathPredicate.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathPredicate.cpp
@@ -233,8 +233,6 @@ Value Union::evaluate() const
{
Value lhsResult = subExpr(0)->evaluate();
Value rhs = subExpr(1)->evaluate();
- if (!lhsResult.isNodeSet() || !rhs.isNodeSet())
- return NodeSet();
NodeSet& resultSet = lhsResult.modifiableNodeSet();
const NodeSet& rhsNodes = rhs.toNodeSet();
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathPredicate.h b/src/3rdparty/webkit/WebCore/xml/XPathPredicate.h
index 8d1b0d8..6c9d413 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathPredicate.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathPredicate.h
@@ -41,6 +41,8 @@ namespace WebCore {
Number(double);
private:
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
+
Value m_value;
};
@@ -49,12 +51,15 @@ namespace WebCore {
StringExpression(const String&);
private:
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::StringValue; }
+
Value m_value;
};
class Negative : public Expression {
private:
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
};
class NumericOp : public Expression {
@@ -65,6 +70,8 @@ namespace WebCore {
NumericOp(Opcode, Expression* lhs, Expression* rhs);
private:
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NumberValue; }
+
Opcode m_opcode;
};
@@ -74,7 +81,9 @@ namespace WebCore {
EqTestOp(Opcode, Expression* lhs, Expression* rhs);
virtual Value evaluate() const;
private:
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
bool compare(const Value&, const Value&) const;
+
Opcode m_opcode;
};
@@ -83,14 +92,17 @@ namespace WebCore {
enum Opcode { OP_And, OP_Or };
LogicalOp(Opcode, Expression* lhs, Expression* rhs);
private:
+ virtual Value::Type resultType() const { return Value::BooleanValue; }
bool shortCircuitOn() const;
virtual Value evaluate() const;
+
Opcode m_opcode;
};
class Union : public Expression {
private:
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { return Value::NodeSetValue; }
};
class Predicate : Noncopyable {
@@ -98,6 +110,10 @@ namespace WebCore {
Predicate(Expression*);
~Predicate();
bool evaluate() const;
+
+ bool isContextPositionSensitive() const { return m_expr->isContextPositionSensitive() || m_expr->resultType() == Value::NumberValue; }
+ bool isContextSizeSensitive() const { return m_expr->isContextSizeSensitive(); }
+
private:
Expression* m_expr;
};
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathResult.cpp b/src/3rdparty/webkit/WebCore/xml/XPathResult.cpp
index 285350e..b608280 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathResult.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathResult.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,9 +29,8 @@
#if ENABLE(XPATH)
-#include "EventListener.h"
-#include "EventNames.h"
-#include "EventTargetNode.h"
+#include "Document.h"
+#include "Node.h"
#include "ExceptionCode.h"
#include "XPathEvaluator.h"
#include "XPathException.h"
@@ -40,22 +39,9 @@ namespace WebCore {
using namespace XPath;
-class InvalidatingEventListener : public EventListener {
-public:
- static PassRefPtr<InvalidatingEventListener> create(XPathResult* result) { return adoptRef(new InvalidatingEventListener(result)); }
- virtual void handleEvent(Event*, bool) { m_result->invalidateIteratorState(); }
-
-private:
- InvalidatingEventListener(XPathResult* result) : m_result(result) { }
- XPathResult* m_result;
-};
-
-XPathResult::XPathResult(EventTargetNode* eventTarget, const Value& value)
+XPathResult::XPathResult(Document* document, const Value& value)
: m_value(value)
- , m_eventTarget(eventTarget)
{
- m_eventListener = InvalidatingEventListener::create(this);
- m_eventTarget->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener, false);
switch (m_value.type()) {
case Value::BooleanValue:
m_resultType = BOOLEAN_TYPE;
@@ -70,7 +56,8 @@ XPathResult::XPathResult(EventTargetNode* eventTarget, const Value& value)
m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
m_nodeSetPosition = 0;
m_nodeSet = m_value.toNodeSet();
- m_invalidIteratorState = false;
+ m_document = document;
+ m_domTreeVersion = document->domTreeVersion();
return;
}
ASSERT_NOT_REACHED();
@@ -78,8 +65,6 @@ XPathResult::XPathResult(EventTargetNode* eventTarget, const Value& value)
XPathResult::~XPathResult()
{
- if (m_eventTarget)
- m_eventTarget->removeEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
}
void XPathResult::convertTo(unsigned short type, ExceptionCode& ec)
@@ -174,24 +159,13 @@ Node* XPathResult::singleNodeValue(ExceptionCode& ec) const
return nodes.anyNode();
}
-void XPathResult::invalidateIteratorState()
-{
- m_invalidIteratorState = true;
-
- ASSERT(m_eventTarget);
- ASSERT(m_eventListener);
-
- m_eventTarget->removeEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false);
-
- m_eventTarget = 0;
-}
-
bool XPathResult::invalidIteratorState() const
{
if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE)
return false;
-
- return m_invalidIteratorState;
+
+ ASSERT(m_document);
+ return m_document->domTreeVersion() != m_domTreeVersion;
}
unsigned long XPathResult::snapshotLength(ExceptionCode& ec) const
@@ -211,7 +185,7 @@ Node* XPathResult::iterateNext(ExceptionCode& ec)
return 0;
}
- if (m_invalidIteratorState) {
+ if (invalidIteratorState()) {
ec = INVALID_STATE_ERR;
return 0;
}
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathResult.h b/src/3rdparty/webkit/WebCore/xml/XPathResult.h
index ecd5cac..3b91d66 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathResult.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathResult.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,15 +29,14 @@
#if ENABLE(XPATH)
-#include <wtf/RefCounted.h>
#include "XPathValue.h"
+#include <wtf/RefCounted.h>
namespace WebCore {
typedef int ExceptionCode;
- class EventListener;
- class EventTargetNode;
+ class Document;
class Node;
class String;
@@ -56,7 +55,7 @@ namespace WebCore {
FIRST_ORDERED_NODE_TYPE = 9
};
- static PassRefPtr<XPathResult> create(EventTargetNode* eventTarget, const XPath::Value& value) { return adoptRef(new XPathResult(eventTarget, value)); }
+ static PassRefPtr<XPathResult> create(Document* document, const XPath::Value& value) { return adoptRef(new XPathResult(document, value)); }
~XPathResult();
void convertTo(unsigned short type, ExceptionCode&);
@@ -73,21 +72,18 @@ namespace WebCore {
Node* iterateNext(ExceptionCode&);
Node* snapshotItem(unsigned long index, ExceptionCode&);
- void invalidateIteratorState();
-
private:
- XPathResult(EventTargetNode*, const XPath::Value&);
+ XPathResult(Document*, const XPath::Value&);
XPath::Value m_value;
unsigned m_nodeSetPosition;
XPath::NodeSet m_nodeSet; // FIXME: why duplicate the node set stored in m_value?
unsigned short m_resultType;
- bool m_invalidIteratorState;
- RefPtr<EventTargetNode> m_eventTarget;
- RefPtr<EventListener> m_eventListener;
+ RefPtr<Document> m_document;
+ unsigned m_domTreeVersion;
};
-}
+} // namespace WebCore
#endif // ENABLE(XPATH)
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathStep.cpp b/src/3rdparty/webkit/WebCore/xml/XPathStep.cpp
index abdcba5..411b616 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathStep.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathStep.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,10 @@
#if ENABLE(XPATH)
+#include "Attr.h"
#include "Document.h"
#include "Element.h"
-#include "NamedAttrMap.h"
-#include "XPathNSResolver.h"
+#include "NamedNodeMap.h"
#include "XPathParser.h"
#include "XPathUtil.h"
@@ -50,14 +50,74 @@ Step::Step(Axis axis, const NodeTest& nodeTest, const Vector<Predicate*>& predic
Step::~Step()
{
deleteAllValues(m_predicates);
+ deleteAllValues(m_nodeTest.mergedPredicates());
+}
+
+void Step::optimize()
+{
+ // Evaluate predicates as part of node test if possible to avoid building unnecessary NodeSets.
+ // E.g., there is no need to build a set of all "foo" nodes to evaluate "foo[@bar]", we can check the predicate while enumerating.
+ // This optimization can be applied to predicates that are not context node list sensitive, or to first predicate that is only context position sensitive, e.g. foo[position() mod 2 = 0].
+ Vector<Predicate*> remainingPredicates;
+ for (size_t i = 0; i < m_predicates.size(); ++i) {
+ Predicate* predicate = m_predicates[i];
+ if ((!predicate->isContextPositionSensitive() || m_nodeTest.mergedPredicates().isEmpty()) && !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) {
+ m_nodeTest.mergedPredicates().append(predicate);
+ } else
+ remainingPredicates.append(predicate);
+ }
+ swap(remainingPredicates, m_predicates);
+}
+
+void optimizeStepPair(Step* first, Step* second, bool& dropSecondStep)
+{
+ dropSecondStep = false;
+
+ if (first->m_axis == Step::DescendantOrSelfAxis
+ && first->m_nodeTest.kind() == Step::NodeTest::AnyNodeTest
+ && !first->m_predicates.size()
+ && !first->m_nodeTest.mergedPredicates().size()) {
+
+ ASSERT(first->m_nodeTest.data().isEmpty());
+ ASSERT(first->m_nodeTest.namespaceURI().isEmpty());
+
+ // Optimize the common case of "//" AKA /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest.
+ if (second->m_axis == Step::ChildAxis && second->predicatesAreContextListInsensitive()) {
+ first->m_axis = Step::DescendantAxis;
+ first->m_nodeTest = Step::NodeTest(second->m_nodeTest.kind(), second->m_nodeTest.data(), second->m_nodeTest.namespaceURI());
+ swap(second->m_nodeTest.mergedPredicates(), first->m_nodeTest.mergedPredicates());
+ swap(second->m_predicates, first->m_predicates);
+ first->optimize();
+ dropSecondStep = true;
+ }
+ }
+}
+
+bool Step::predicatesAreContextListInsensitive() const
+{
+ for (size_t i = 0; i < m_predicates.size(); ++i) {
+ Predicate* predicate = m_predicates[i];
+ if (predicate->isContextPositionSensitive() || predicate->isContextSizeSensitive())
+ return false;
+ }
+
+ for (size_t i = 0; i < m_nodeTest.mergedPredicates().size(); ++i) {
+ Predicate* predicate = m_nodeTest.mergedPredicates()[i];
+ if (predicate->isContextPositionSensitive() || predicate->isContextSizeSensitive())
+ return false;
+ }
+
+ return true;
}
void Step::evaluate(Node* context, NodeSet& nodes) const
{
- nodesInAxis(context, nodes);
-
EvaluationContext& evaluationContext = Expression::evaluationContext();
-
+ evaluationContext.position = 0;
+
+ nodesInAxis(context, nodes);
+
+ // Check predicates that couldn't be merged into node test.
for (unsigned i = 0; i < m_predicates.size(); i++) {
Predicate* predicate = m_predicates[i];
@@ -68,7 +128,7 @@ void Step::evaluate(Node* context, NodeSet& nodes) const
for (unsigned j = 0; j < nodes.size(); j++) {
Node* node = nodes[j];
- Expression::evaluationContext().node = node;
+ evaluationContext.node = node;
evaluationContext.size = nodes.size();
evaluationContext.position = j + 1;
if (predicate->evaluate())
@@ -79,6 +139,95 @@ void Step::evaluate(Node* context, NodeSet& nodes) const
}
}
+static inline Node::NodeType primaryNodeType(Step::Axis axis)
+{
+ switch (axis) {
+ case Step::AttributeAxis:
+ return Node::ATTRIBUTE_NODE;
+ case Step::NamespaceAxis:
+ return Node::XPATH_NAMESPACE_NODE;
+ default:
+ return Node::ELEMENT_NODE;
+ }
+}
+
+// Evaluate NodeTest without considering merged predicates.
+static inline bool nodeMatchesBasicTest(Node* node, Step::Axis axis, const Step::NodeTest& nodeTest)
+{
+ switch (nodeTest.kind()) {
+ case Step::NodeTest::TextNodeTest:
+ return node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE;
+ case Step::NodeTest::CommentNodeTest:
+ return node->nodeType() == Node::COMMENT_NODE;
+ case Step::NodeTest::ProcessingInstructionNodeTest: {
+ const AtomicString& name = nodeTest.data();
+ return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name);
+ }
+ case Step::NodeTest::AnyNodeTest:
+ return true;
+ case Step::NodeTest::NameTest: {
+ const AtomicString& name = nodeTest.data();
+ const AtomicString& namespaceURI = nodeTest.namespaceURI();
+
+ if (axis == Step::AttributeAxis) {
+ ASSERT(node->isAttributeNode());
+
+ // In XPath land, namespace nodes are not accessible on the attribute axis.
+ if (node->namespaceURI() == "http://www.w3.org/2000/xmlns/")
+ return false;
+
+ if (name == starAtom)
+ return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI;
+
+ return node->localName() == name && node->namespaceURI() == namespaceURI;
+ }
+
+ // Node test on the namespace axis is not implemented yet, the caller has a check for it.
+ ASSERT(axis != Step::NamespaceAxis);
+
+ // For other axes, the principal node type is element.
+ ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
+ if (node->nodeType() != Node::ELEMENT_NODE)
+ return false;
+
+ if (name == starAtom)
+ return namespaceURI.isEmpty() || namespaceURI == node->namespaceURI();
+
+ if (node->isHTMLElement() && node->document()->isHTMLDocument()) {
+ // Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace. Names are compared case-insensitively.
+ return equalIgnoringCase(static_cast<Element*>(node)->localName(), name) && (namespaceURI.isNull() || namespaceURI == node->namespaceURI());
+ }
+ return static_cast<Element*>(node)->hasLocalName(name) && namespaceURI == node->namespaceURI();
+ }
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+static inline bool nodeMatches(Node* node, Step::Axis axis, const Step::NodeTest& nodeTest)
+{
+ if (!nodeMatchesBasicTest(node, axis, nodeTest))
+ return false;
+
+ EvaluationContext& evaluationContext = Expression::evaluationContext();
+
+ // Only the first merged predicate may depend on position.
+ ++evaluationContext.position;
+
+ const Vector<Predicate*>& mergedPredicates = nodeTest.mergedPredicates();
+ for (unsigned i = 0; i < mergedPredicates.size(); i++) {
+ Predicate* predicate = mergedPredicates[i];
+
+ evaluationContext.node = node;
+ // No need to set context size - we only get here when evaluating predicates that do not depend on it.
+ if (!predicate->evaluate())
+ return false;
+ }
+
+ return true;
+}
+
+// Result nodes are ordered in axis order. Node test (including merged predicates) is applied.
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
ASSERT(nodes.isEmpty());
@@ -88,7 +237,7 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
return;
for (Node* n = context->firstChild(); n; n = n->nextSibling())
- if (nodeMatches(n))
+ if (nodeMatches(n, ChildAxis, m_nodeTest))
nodes.append(n);
return;
case DescendantAxis:
@@ -96,17 +245,17 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
return;
for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
- if (nodeMatches(n))
+ if (nodeMatches(n, DescendantAxis, m_nodeTest))
nodes.append(n);
return;
case ParentAxis:
if (context->isAttributeNode()) {
Node* n = static_cast<Attr*>(context)->ownerElement();
- if (nodeMatches(n))
+ if (nodeMatches(n, ParentAxis, m_nodeTest))
nodes.append(n);
} else {
Node* n = context->parentNode();
- if (n && nodeMatches(n))
+ if (n && nodeMatches(n, ParentAxis, m_nodeTest))
nodes.append(n);
}
return;
@@ -114,11 +263,11 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
Node* n = context;
if (context->isAttributeNode()) {
n = static_cast<Attr*>(context)->ownerElement();
- if (nodeMatches(n))
+ if (nodeMatches(n, AncestorAxis, m_nodeTest))
nodes.append(n);
}
for (n = n->parentNode(); n; n = n->parentNode())
- if (nodeMatches(n))
+ if (nodeMatches(n, AncestorAxis, m_nodeTest))
nodes.append(n);
nodes.markSorted(false);
return;
@@ -129,7 +278,7 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
return;
for (Node* n = context->nextSibling(); n; n = n->nextSibling())
- if (nodeMatches(n))
+ if (nodeMatches(n, FollowingSiblingAxis, m_nodeTest))
nodes.append(n);
return;
case PrecedingSiblingAxis:
@@ -138,7 +287,7 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
return;
for (Node* n = context->previousSibling(); n; n = n->previousSibling())
- if (nodeMatches(n))
+ if (nodeMatches(n, PrecedingSiblingAxis, m_nodeTest))
nodes.append(n);
nodes.markSorted(false);
@@ -147,15 +296,15 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
if (context->isAttributeNode()) {
Node* p = static_cast<Attr*>(context)->ownerElement();
while ((p = p->traverseNextNode()))
- if (nodeMatches(p))
+ if (nodeMatches(p, FollowingAxis, m_nodeTest))
nodes.append(p);
} else {
for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
- if (nodeMatches(n))
+ if (nodeMatches(n, FollowingAxis, m_nodeTest))
nodes.append(n);
for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
- if (nodeMatches(c))
+ if (nodeMatches(c, FollowingAxis, m_nodeTest))
nodes.append(c);
}
}
@@ -168,7 +317,7 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
Node* n = context;
while (Node* parent = n->parent()) {
for (n = n->traversePreviousNode(); n != parent; n = n->traversePreviousNode())
- if (nodeMatches(n))
+ if (nodeMatches(n, PrecedingAxis, m_nodeTest))
nodes.append(n);
n = parent;
}
@@ -180,21 +329,23 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
return;
// Avoid lazily creating attribute nodes for attributes that we do not need anyway.
- if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != "*") {
+ if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != starAtom) {
RefPtr<Node> n = static_cast<Element*>(context)->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
- if (n && n->namespaceURI() != "http://www.w3.org/2000/xmlns/") // In XPath land, namespace nodes are not accessible on the attribute axis.
- nodes.append(n.release());
+ if (n && n->namespaceURI() != "http://www.w3.org/2000/xmlns/") { // In XPath land, namespace nodes are not accessible on the attribute axis.
+ if (nodeMatches(n.get(), AttributeAxis, m_nodeTest)) // Still need to check merged predicates.
+ nodes.append(n.release());
+ }
return;
}
- NamedAttrMap* attrs = context->attributes();
+ NamedNodeMap* attrs = context->attributes();
if (!attrs)
return;
- for (unsigned long i = 0; i < attrs->length(); ++i) {
- RefPtr<Node> n = attrs->item(i);
- if (nodeMatches(n.get()))
- nodes.append(n.release());
+ for (unsigned i = 0; i < attrs->length(); ++i) {
+ RefPtr<Attr> attr = attrs->attributeItem(i)->createAttrIfNeeded(static_cast<Element*>(context));
+ if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
+ nodes.append(attr.release());
}
return;
}
@@ -202,30 +353,30 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
// XPath namespace nodes are not implemented yet.
return;
case SelfAxis:
- if (nodeMatches(context))
+ if (nodeMatches(context, SelfAxis, m_nodeTest))
nodes.append(context);
return;
case DescendantOrSelfAxis:
- if (nodeMatches(context))
+ if (nodeMatches(context, DescendantOrSelfAxis, m_nodeTest))
nodes.append(context);
if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
return;
for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
- if (nodeMatches(n))
+ if (nodeMatches(n, DescendantOrSelfAxis, m_nodeTest))
nodes.append(n);
return;
case AncestorOrSelfAxis: {
- if (nodeMatches(context))
+ if (nodeMatches(context, AncestorOrSelfAxis, m_nodeTest))
nodes.append(context);
Node* n = context;
if (context->isAttributeNode()) {
n = static_cast<Attr*>(context)->ownerElement();
- if (nodeMatches(n))
+ if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
nodes.append(n);
}
for (n = n->parentNode(); n; n = n->parentNode())
- if (nodeMatches(n))
+ if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
nodes.append(n);
nodes.markSorted(false);
@@ -236,70 +387,6 @@ void Step::nodesInAxis(Node* context, NodeSet& nodes) const
}
-bool Step::nodeMatches(Node* node) const
-{
- switch (m_nodeTest.kind()) {
- case NodeTest::TextNodeTest:
- return node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE;
- case NodeTest::CommentNodeTest:
- return node->nodeType() == Node::COMMENT_NODE;
- case NodeTest::ProcessingInstructionNodeTest: {
- const String& name = m_nodeTest.data();
- return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name);
- }
- case NodeTest::ElementNodeTest:
- return node->isElementNode();
- case NodeTest::AnyNodeTest:
- return true;
- case NodeTest::NameTest: {
- const String& name = m_nodeTest.data();
- const String& namespaceURI = m_nodeTest.namespaceURI();
-
- if (m_axis == AttributeAxis) {
- ASSERT(node->isAttributeNode());
-
- // In XPath land, namespace nodes are not accessible on the attribute axis.
- if (node->namespaceURI() == "http://www.w3.org/2000/xmlns/")
- return false;
-
- if (name == "*")
- return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI;
-
- return node->localName() == name && node->namespaceURI() == namespaceURI;
- }
-
- if (m_axis == NamespaceAxis) {
- // Node test on the namespace axis is not implemented yet
- return false;
- }
-
- if (name == "*")
- return node->nodeType() == primaryNodeType(m_axis) && (namespaceURI.isEmpty() || namespaceURI == node->namespaceURI());
-
- // We use tagQName here because we don't want the element name in uppercase
- // like we get with HTML elements.
- // Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace.
- return node->nodeType() == Node::ELEMENT_NODE
- && static_cast<Element*>(node)->tagQName().localName() == name
- && ((node->isHTMLElement() && node->document()->isHTMLDocument() && namespaceURI.isNull()) || namespaceURI == node->namespaceURI());
- }
- }
- ASSERT_NOT_REACHED();
- return false;
-}
-
-Node::NodeType Step::primaryNodeType(Axis axis) const
-{
- switch (axis) {
- case AttributeAxis:
- return Node::ATTRIBUTE_NODE;
- case NamespaceAxis:
- return Node::XPATH_NAMESPACE_NODE;
- default:
- return Node::ELEMENT_NODE;
- }
-}
-
}
}
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathStep.h b/src/3rdparty/webkit/WebCore/xml/XPathStep.h
index f1420d0..1c26327 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathStep.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathStep.h
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,8 +52,7 @@ namespace WebCore {
class NodeTest {
public:
enum Kind {
- TextNodeTest, CommentNodeTest, ProcessingInstructionNodeTest, AnyNodeTest, NameTest,
- ElementNodeTest // XPath 2.0
+ TextNodeTest, CommentNodeTest, ProcessingInstructionNodeTest, AnyNodeTest, NameTest
};
NodeTest(Kind kind) : m_kind(kind) {}
@@ -61,44 +60,48 @@ namespace WebCore {
NodeTest(Kind kind, const String& data, const String& namespaceURI) : m_kind(kind), m_data(data), m_namespaceURI(namespaceURI) {}
Kind kind() const { return m_kind; }
- const String data() const { return m_data; }
- const String namespaceURI() const { return m_namespaceURI; }
+ const AtomicString& data() const { return m_data; }
+ const AtomicString& namespaceURI() const { return m_namespaceURI; }
+ Vector<Predicate*>& mergedPredicates() { return m_mergedPredicates; }
+ const Vector<Predicate*>& mergedPredicates() const { return m_mergedPredicates; }
private:
Kind m_kind;
- String m_data;
- String m_namespaceURI;
+ AtomicString m_data;
+ AtomicString m_namespaceURI;
+
+ // When possible, we merge some or all predicates with node test for better performance.
+ Vector<Predicate*> m_mergedPredicates;
};
Step(Axis, const NodeTest& nodeTest, const Vector<Predicate*>& predicates = Vector<Predicate*>());
~Step();
+ void optimize();
+
void evaluate(Node* context, NodeSet&) const;
-
+
Axis axis() const { return m_axis; }
- NodeTest nodeTest() const { return m_nodeTest; }
- const Vector<Predicate*>& predicates() const { return m_predicates; }
-
- void setAxis(Axis axis) { m_axis = axis; }
- void setNodeTest(NodeTest nodeTest) { m_nodeTest = nodeTest; }
- void setPredicates(const Vector<Predicate*>& predicates) { m_predicates = predicates; }
-
+ const NodeTest& nodeTest() const { return m_nodeTest; }
+
private:
+ friend void optimizeStepPair(Step*, Step*, bool&);
+ bool predicatesAreContextListInsensitive() const;
+
void parseNodeTest(const String&);
void nodesInAxis(Node* context, NodeSet&) const;
- bool nodeMatches(Node*) const;
String namespaceFromNodetest(const String& nodeTest) const;
- Node::NodeType primaryNodeType(Axis) const;
Axis m_axis;
NodeTest m_nodeTest;
Vector<Predicate*> m_predicates;
};
+ void optimizeStepPair(Step*, Step*, bool& dropSecondStep);
}
}
#endif // ENABLE(XPATH)
-#endif // XPath_Step_H
+#endif // XPathStep_h
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathUtil.cpp b/src/3rdparty/webkit/WebCore/xml/XPathUtil.cpp
index ab4b1d4..0100bea 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathUtil.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathUtil.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright 2005 Frerich Raabe <raabe@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
+ * Copyright (C) 2006, 2009 Apple Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,13 +51,17 @@ String stringValue(Node* node)
return node->nodeValue();
default:
if (isRootDomNode(node) || node->nodeType() == Node::ELEMENT_NODE) {
- String str;
-
- for (Node* n = node->firstChild(); n; n = n->traverseNextNode(node))
- if (n->isTextNode())
- str += n->nodeValue();
+ Vector<UChar> result;
+ result.reserveCapacity(1024);
- return str;
+ for (Node* n = node->firstChild(); n; n = n->traverseNextNode(node)) {
+ if (n->isTextNode()) {
+ const String& nodeValue = n->nodeValue();
+ result.append(nodeValue.characters(), nodeValue.length());
+ }
+ }
+
+ return String::adopt(result);
}
}
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp b/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp
index bac0e13..29e211e 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XPathValue.cpp
@@ -30,11 +30,11 @@
#if ENABLE(XPATH)
#include "Node.h"
+#include "XPathExpressionNode.h"
#include "XPathUtil.h"
-
+#include <limits>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
-#include <limits>
using std::numeric_limits;
@@ -45,6 +45,9 @@ const Value::AdoptTag Value::adopt = {};
const NodeSet& Value::toNodeSet() const
{
+ if (!isNodeSet())
+ Expression::evaluationContext().hadTypeConversionError = true;
+
if (!m_data) {
DEFINE_STATIC_LOCAL(NodeSet, emptyNodeSet, ());
return emptyNodeSet;
@@ -55,6 +58,9 @@ const NodeSet& Value::toNodeSet() const
NodeSet& Value::modifiableNodeSet()
{
+ if (!isNodeSet())
+ Expression::evaluationContext().hadTypeConversionError = true;
+
if (!m_data)
m_data = ValueData::create();
@@ -86,8 +92,18 @@ double Value::toNumber() const
case NumberValue:
return m_number;
case StringValue: {
+ const String& str = m_data->m_string.simplifyWhiteSpace();
+
+ // String::toDouble() supports exponential notation, which is not allowed in XPath.
+ unsigned len = str.length();
+ for (unsigned i = 0; i < len; ++i) {
+ UChar c = str[i];
+ if (!isASCIIDigit(c) && c != '.' && c != '-')
+ return numeric_limits<double>::quiet_NaN();
+ }
+
bool canConvert;
- double value = m_data->m_string.simplifyWhiteSpace().toDouble(&canConvert);
+ double value = str.toDouble(&canConvert);
if (canConvert)
return value;
return numeric_limits<double>::quiet_NaN();
diff --git a/src/3rdparty/webkit/WebCore/xml/XPathVariableReference.h b/src/3rdparty/webkit/WebCore/xml/XPathVariableReference.h
index 811176d..5e5a59a 100644
--- a/src/3rdparty/webkit/WebCore/xml/XPathVariableReference.h
+++ b/src/3rdparty/webkit/WebCore/xml/XPathVariableReference.h
@@ -33,12 +33,14 @@
namespace WebCore {
namespace XPath {
-
+
+ // Variable references are not used with XPathEvaluator.
class VariableReference : public Expression {
public:
VariableReference(const String& name);
private:
virtual Value evaluate() const;
+ virtual Value::Type resultType() const { ASSERT_NOT_REACHED(); return Value::NumberValue; }
String m_name;
};
diff --git a/src/3rdparty/webkit/WebCore/xml/XSLStyleSheet.cpp b/src/3rdparty/webkit/WebCore/xml/XSLStyleSheet.cpp
index 0d112a5..b7d52f8 100644
--- a/src/3rdparty/webkit/WebCore/xml/XSLStyleSheet.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XSLStyleSheet.cpp
@@ -30,11 +30,12 @@
#include "DocLoader.h"
#include "Document.h"
#include "Frame.h"
-#include "loader.h"
#include "Node.h"
#include "XMLTokenizer.h"
+#include "XMLTokenizerScope.h"
#include "XSLImportRule.h"
#include "XSLTProcessor.h"
+#include "loader.h"
#include <libxml/uri.h>
#include <libxslt/xsltutils.h>
@@ -138,7 +139,6 @@ bool XSLStyleSheet::parseString(const String& string, bool)
// Parse in a single chunk into an xmlDocPtr
const UChar BOM = 0xFEFF;
const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char*>(&BOM);
- setLoaderForLibXMLCallbacks(docLoader());
if (!m_stylesheetDocTaken)
xmlFreeDoc(m_stylesheetDoc);
m_stylesheetDocTaken = false;
@@ -146,8 +146,8 @@ bool XSLStyleSheet::parseString(const String& string, bool)
Console* console = 0;
if (Frame* frame = ownerDocument()->frame())
console = frame->domWindow()->console();
- xmlSetStructuredErrorFunc(console, XSLTProcessor::parseErrorFunc);
- xmlSetGenericErrorFunc(console, XSLTProcessor::genericErrorFunc);
+
+ XMLTokenizerScope scope(docLoader(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console);
const char* buffer = reinterpret_cast<const char*>(string.characters());
int size = string.length() * sizeof(UChar);
@@ -171,13 +171,9 @@ bool XSLStyleSheet::parseString(const String& string, bool)
BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE",
XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_NOWARNING | XML_PARSE_NOCDATA);
xmlFreeParserCtxt(ctxt);
-
- loadChildSheets();
- xmlSetStructuredErrorFunc(0, 0);
- xmlSetGenericErrorFunc(0, 0);
+ loadChildSheets();
- setLoaderForLibXMLCallbacks(0);
return m_stylesheetDoc;
}
diff --git a/src/3rdparty/webkit/WebCore/xml/XSLTExtensions.cpp b/src/3rdparty/webkit/WebCore/xml/XSLTExtensions.cpp
index d89f08b..069ddd8 100644
--- a/src/3rdparty/webkit/WebCore/xml/XSLTExtensions.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XSLTExtensions.cpp
@@ -27,6 +27,7 @@
#include "config.h"
#if ENABLE(XSLT)
+#include "XSLTExtensions.h"
#include <libxml/xpathInternals.h>
diff --git a/src/3rdparty/webkit/WebCore/xml/XSLTProcessor.cpp b/src/3rdparty/webkit/WebCore/xml/XSLTProcessor.cpp
index b644486..3865124 100644
--- a/src/3rdparty/webkit/WebCore/xml/XSLTProcessor.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XSLTProcessor.cpp
@@ -55,11 +55,10 @@
#include <wtf/Assertions.h>
#include <wtf/Platform.h>
#include <wtf/Vector.h>
+
#if PLATFORM(MAC)
#include "SoftLinking.h"
-#endif
-#if PLATFORM(MAC)
SOFT_LINK_LIBRARY(libxslt);
SOFT_LINK(libxslt, xsltFreeStylesheet, void, (xsltStylesheetPtr sheet), (sheet))
SOFT_LINK(libxslt, xsltFreeTransformContext, void, (xsltTransformContextPtr ctxt), (ctxt))
@@ -128,7 +127,7 @@ static xmlDocPtr docLoaderFunc(const xmlChar* uri,
bool requestAllowed = globalDocLoader->frame() && globalDocLoader->doc()->securityOrigin()->canRequest(url);
if (requestAllowed) {
- globalDocLoader->frame()->loader()->loadResourceSynchronously(url, error, response, data);
+ globalDocLoader->frame()->loader()->loadResourceSynchronously(url, AllowStoredCredentials, error, response, data);
requestAllowed = globalDocLoader->doc()->securityOrigin()->canRequest(response.url());
}
if (!requestAllowed) {
@@ -284,7 +283,7 @@ PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourc
return result.release();
}
-static inline RefPtr<DocumentFragment> createFragmentFromSource(const String& sourceString, const String& sourceMIMEType, Node* sourceNode, Document* outputDoc)
+static inline RefPtr<DocumentFragment> createFragmentFromSource(const String& sourceString, const String& sourceMIMEType, Document* outputDoc)
{
RefPtr<DocumentFragment> fragment = new DocumentFragment(outputDoc);
@@ -433,7 +432,7 @@ PassRefPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode
if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
return 0;
- return createFragmentFromSource(resultString, resultMIMEType, sourceNode, outputDoc);
+ return createFragmentFromSource(resultString, resultMIMEType, outputDoc);
}
void XSLTProcessor::setParameter(const String& /*namespaceURI*/, const String& localName, const String& value)
diff --git a/src/3rdparty/webkit/WebCore/xml/XSLTUnicodeSort.cpp b/src/3rdparty/webkit/WebCore/xml/XSLTUnicodeSort.cpp
index ed66112..b0b9c72 100644
--- a/src/3rdparty/webkit/WebCore/xml/XSLTUnicodeSort.cpp
+++ b/src/3rdparty/webkit/WebCore/xml/XSLTUnicodeSort.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,10 +32,8 @@
#if ENABLE(XSLT)
#include "PlatformString.h"
-
#include <libxslt/templates.h>
#include <libxslt/xsltutils.h>
-
#include <wtf/unicode/Collator.h>
#if PLATFORM(MAC)
@@ -43,57 +41,29 @@
#endif
#if PLATFORM(MAC)
+
SOFT_LINK_LIBRARY(libxslt)
SOFT_LINK(libxslt, xsltComputeSortResult, xmlXPathObjectPtr*, (xsltTransformContextPtr ctxt, xmlNodePtr sort), (ctxt, sort))
SOFT_LINK(libxslt, xsltEvalAttrValueTemplate, xmlChar*, (xsltTransformContextPtr ctxt, xmlNodePtr node, const xmlChar *name, const xmlChar *ns), (ctxt, node, name, ns))
-static void init_xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
-static void (*softLink_xsltTransformError)(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *, ...) WTF_ATTRIBUTE_PRINTF(4, 5) = init_xsltTransformError;
+static void xsltTransformErrorTrampoline(xsltTransformContextPtr, xsltStylesheetPtr, xmlNodePtr, const char* message, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
-static void init_xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char* msg, ...)
+void xsltTransformErrorTrampoline(xsltTransformContextPtr context, xsltStylesheetPtr style, xmlNodePtr node, const char* message, ...)
{
- softLink_xsltTransformError = (void (*) (xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *, ...))dlsym(libxsltLibrary(), "xsltTransformError");
- ASSERT(softLink_xsltTransformError);
-
va_list args;
- va_start(args, msg);
-#if PLATFORM(WIN_OS)
- char str[1024];
- vsnprintf(str, sizeof(str) - 1, msg, args);
-#else
- char* str;
- vasprintf(&str, msg, args);
-#endif
+ va_start(args, message);
+ char* messageWithArgs;
+ vasprintf(&messageWithArgs, message, args);
va_end(args);
- softLink_xsltTransformError(ctxt, style, node, "%s", str);
+ static void (*xsltTransformErrorPointer)(xsltTransformContextPtr, xsltStylesheetPtr, xmlNodePtr, const char*, ...) WTF_ATTRIBUTE_PRINTF(4, 5)
+ = reinterpret_cast<void (*)(xsltTransformContextPtr, xsltStylesheetPtr, xmlNodePtr, const char*, ...)>(dlsym(libxsltLibrary(), "xsltTransformError"));
+ xsltTransformErrorPointer(context, style, node, "%s", messageWithArgs);
-#if !PLATFORM(WIN_OS)
- free(str);
-#endif
+ free(messageWithArgs);
}
-inline void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char* msg, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
-
-inline void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char* msg, ...)
-{
- va_list args;
- va_start(args, msg);
-#if PLATFORM(WIN_OS)
- char str[1024];
- vsnprintf(str, sizeof(str) - 1, msg, args);
-#else
- char* str;
- vasprintf(&str, msg, args);
-#endif
- va_end(args);
-
- softLink_xsltTransformError(ctxt, style, node, "%s", str);
-
-#if !PLATFORM(WIN_OS)
- free(str);
-#endif
-}
+#define xsltTransformError xsltTransformErrorTrampoline
#endif