diff --git a/CMakeLists.txt b/CMakeLists.txt index 459ea7b839e6..c59e0f6c0a2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,7 @@ set(ALL_PORTS AppleWin Efl GTK + Haiku JSCOnly Mac PlayStation diff --git a/LayoutTests/fast/block/border-fit-with-right-alignment-expected.html b/LayoutTests/fast/block/border-fit-with-right-alignment-expected.html index 6f4ea98700a1..c1b35081e1f8 100644 --- a/LayoutTests/fast/block/border-fit-with-right-alignment-expected.html +++ b/LayoutTests/fast/block/border-fit-with-right-alignment-expected.html @@ -1,4 +1,4 @@ - + + + + + diff --git a/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp b/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp new file mode 100644 index 000000000000..00a9fb8daaa8 --- /dev/null +++ b/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2010 Stephan Aßmus, + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ImageBackingStore.h" +#include "ImageDecoder.h" + +#include + +namespace WebCore { + +NativeImagePtr ImageBackingStore::image() const +{ + int bytesPerRow = size().width() * sizeof(RGBA32); + BitmapRef* bitmap = new BitmapRef(BRect(0, 0, size().width() - 1, size().height() - 1), 0, B_RGBA32, bytesPerRow); + if (!bitmap || !bitmap->IsValid() || !m_pixelsPtr) { + delete bitmap; + return NULL; + } + + const uint8* source = reinterpret_cast(m_pixelsPtr); + uint8* destination = reinterpret_cast(bitmap->Bits()); + int h = size().height(); + int w = size().width(); + for (int y = 0; y < h; y++) { +#if 0 +// FIXME: Enable this conversion once Haiku has B_RGBA32P[remultiplied]... + memcpy(dst, source, bytesPerRow); +#else + const uint8* sourceHandle = source; + uint8* destinationHandle = destination; + for (int x = 0; x < w; x++) { + if (sourceHandle[3] == 255 || !sourceHandle[3]) { + destinationHandle[0] = sourceHandle[0]; + destinationHandle[1] = sourceHandle[1]; + destinationHandle[2] = sourceHandle[2]; + destinationHandle[3] = sourceHandle[3]; + } else { + destinationHandle[0] = static_cast(sourceHandle[0]) * 255 / sourceHandle[3]; + destinationHandle[1] = static_cast(sourceHandle[1]) * 255 / sourceHandle[3]; + destinationHandle[2] = static_cast(sourceHandle[2]) * 255 / sourceHandle[3]; + destinationHandle[3] = sourceHandle[3]; + } + destinationHandle += 4; + sourceHandle += 4; + } +#endif + destination += bytesPerRow; + source += bytesPerRow; + } + + return bitmap; +} + +} // namespace WebCore + diff --git a/Source/WebCore/platform/network/DNSResolveQueue.cpp b/Source/WebCore/platform/network/DNSResolveQueue.cpp index 885070485559..9b16b22e9e91 100644 --- a/Source/WebCore/platform/network/DNSResolveQueue.cpp +++ b/Source/WebCore/platform/network/DNSResolveQueue.cpp @@ -33,6 +33,8 @@ #include "DNSResolveQueueCurl.h" #elif USE(CF) #include "DNSResolveQueueCFNet.h" +#elif USE(HAIKU) +#include "DNSResolveQueueHaiku.h" #endif #include diff --git a/Source/WebCore/platform/network/HTTPParsers.cpp b/Source/WebCore/platform/network/HTTPParsers.cpp index 474a1a2e0c54..e3d1098e28c4 100644 --- a/Source/WebCore/platform/network/HTTPParsers.cpp +++ b/Source/WebCore/platform/network/HTTPParsers.cpp @@ -284,12 +284,16 @@ String filenameFromHTTPContentDisposition(const String& value) if (key.isEmpty() || key != "filename") continue; - + String value = keyValuePair.substring(valueStartPos + 1).stripWhiteSpace(); // Remove quotes if there are any - if (value[0] == '\"') - value = value.substring(1, value.length() - 2); + if (value[0] == '"') { + if (value[value.length() - 1] == '"') + value = value.substring(1, value.length() - 2); + else + return String(); + } return value; } diff --git a/Source/WebCore/platform/network/NetworkStorageSession.h b/Source/WebCore/platform/network/NetworkStorageSession.h index 58da878907ff..0655d72f8299 100644 --- a/Source/WebCore/platform/network/NetworkStorageSession.h +++ b/Source/WebCore/platform/network/NetworkStorageSession.h @@ -38,6 +38,8 @@ #if PLATFORM(COCOA) || USE(CFURLCONNECTION) #include #include +#elif PLATFORM(HAIKU) +class BUrlContext; #endif #if USE(SOUP) @@ -107,6 +109,12 @@ class NetworkStorageSession { void setCookieObserverHandler(Function&&); void getCredentialFromPersistentStorage(const ProtectionSpace&, GCancellable*, Function&& completionHandler); void saveCredentialToPersistentStorage(const ProtectionSpace&, const Credential&); +#elif USE(HAIKU) + WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID); + ~NetworkStorageSession(); + + BUrlContext& platformSession() const; + void setPlatformSession(BUrlContext*); #elif USE(CURL) WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID); ~NetworkStorageSession(); @@ -173,6 +181,8 @@ class NetworkStorageSession { mutable std::unique_ptr m_session; Function m_cookieObserverHandler; +#elif USE(HAIKU) + BUrlContext* m_context; #elif USE(CURL) UniqueRef m_cookieStorage; mutable UniqueRef m_cookieDatabase; diff --git a/Source/WebCore/platform/network/ResourceHandle.h b/Source/WebCore/platform/network/ResourceHandle.h index 9e25d9e2b449..cbbc9573dcee 100644 --- a/Source/WebCore/platform/network/ResourceHandle.h +++ b/Source/WebCore/platform/network/ResourceHandle.h @@ -67,6 +67,10 @@ typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; #endif +#if PLATFORM(HAIKU) +class BCertificate; +#endif + namespace WTF { class SchedulePair; template class MessageQueue; @@ -141,6 +145,10 @@ class ResourceHandle : public RefCounted, public AuthenticationC void unschedule(WTF::SchedulePair&); #endif +#if PLATFORM(HAIKU) + bool didReceiveInvalidCertificate(BCertificate& certificate, const char* message); +#endif + #if USE(CFURLCONNECTION) CFURLStorageSessionRef storageSession() const; CFURLConnectionRef connection() const; @@ -166,7 +174,7 @@ class ResourceHandle : public RefCounted, public AuthenticationC WEBCORE_EXPORT static void forceContentSniffing(); -#if USE(CURL) +#if USE(CURL) || USE(HAIKU) ResourceHandleInternal* getInternal() { return d.get(); } #endif diff --git a/Source/WebCore/platform/network/ResourceHandleClient.h b/Source/WebCore/platform/network/ResourceHandleClient.h index 7343bda55047..b91882a646d5 100644 --- a/Source/WebCore/platform/network/ResourceHandleClient.h +++ b/Source/WebCore/platform/network/ResourceHandleClient.h @@ -41,6 +41,10 @@ OBJC_CLASS NSCachedURLResponse; #endif +#if PLATFORM(HAIKU) +class BCertificate; +#endif + namespace WebCore { class AuthenticationChallenge; class Credential; @@ -92,6 +96,11 @@ class ResourceHandleClient { virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) { } virtual void receivedCancellation(ResourceHandle*, const AuthenticationChallenge&) { } +#if PLATFORM(HAIKU) + virtual bool didReceiveInvalidCertificate(ResourceHandle*, const BCertificate&, + const char*) { return false; } +#endif + #if PLATFORM(IOS_FAMILY) || USE(CFURLCONNECTION) virtual RetainPtr connectionProperties(ResourceHandle*) { return nullptr; } #endif diff --git a/Source/WebCore/platform/network/ResourceHandleInternal.h b/Source/WebCore/platform/network/ResourceHandleInternal.h index 243de9f8265a..1cf06fb1e7fe 100644 --- a/Source/WebCore/platform/network/ResourceHandleInternal.h +++ b/Source/WebCore/platform/network/ResourceHandleInternal.h @@ -43,6 +43,11 @@ #include #endif +#if PLATFORM(HAIKU) +#include +class BUrlProtocolHandler; +#endif + #if PLATFORM(COCOA) OBJC_CLASS NSURLAuthenticationChallenge; OBJC_CLASS NSURLConnection; @@ -72,6 +77,9 @@ class ResourceHandleInternal { , m_shouldContentEncodingSniff(shouldContentEncodingSniff) #if USE(CFURLCONNECTION) , m_currentRequest(request) +#endif +#if PLATFORM(HAIKU) + , m_urlrequest(0) #endif , m_failureTimer(*loader, &ResourceHandle::failureTimerFired) { @@ -129,6 +137,11 @@ class ResourceHandleInternal { MonotonicTime m_startTime; #endif +#if PLATFORM(HAIKU) + BUrlProtocolHandler* m_urlrequest; + BString m_url; +#endif + #if PLATFORM(COCOA) // We need to keep a reference to the original challenge to be able to cancel it. // It is almost identical to m_currentWebChallenge.nsURLAuthenticationChallenge(), but has a different sender. diff --git a/Source/WebCore/platform/network/haiku/AuthenticationChallenge.h b/Source/WebCore/platform/network/haiku/AuthenticationChallenge.h new file mode 100644 index 000000000000..0d62ed5cbd12 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/AuthenticationChallenge.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef AuthenticationChallenge_h +#define AuthenticationChallenge_h + +#include "AuthenticationChallengeBase.h" +#include "AuthenticationClient.h" + +namespace WebCore { + +class AuthenticationChallenge : public AuthenticationChallengeBase { +public: + AuthenticationChallenge() + { + } + + AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error) + : AuthenticationChallengeBase(protectionSpace, proposedCredential, previousFailureCount, response, error) + { + } + + AuthenticationClient* authenticationClient() const { return m_authenticationClient.get(); } + + RefPtr m_authenticationClient; +}; + +} + +#endif diff --git a/Source/WebCore/platform/network/haiku/BUrlProtocolHandler.cpp b/Source/WebCore/platform/network/haiku/BUrlProtocolHandler.cpp new file mode 100644 index 000000000000..8bfa7bb9b3a7 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/BUrlProtocolHandler.cpp @@ -0,0 +1,398 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2007 Staikos Computing Services Inc. + Copyright (C) 2008 Holger Hans Peter Freyther + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "config.h" +#include "BUrlProtocolHandler.h" + +#include "FormData.h" +#include "HTTPParsers.h" +#include "MIMETypeRegistry.h" +#include "NetworkStorageSession.h" +#include "ProtectionSpace.h" +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include "ResourceHandleInternal.h" +#include "ResourceResponse.h" +#include "ResourceRequest.h" +#include +#include + +#include +#include +#include +#include +#include + +#include + +static const int gMaxRecursionLimit = 10; + +namespace WebCore { + +BUrlProtocolHandler::BUrlProtocolHandler(NetworkingContext* context, + ResourceHandle* handle, bool synchronous) + : BUrlProtocolAsynchronousListener(!synchronous) + , m_resourceHandle(handle) + , m_redirected(false) + , m_responseDataSent(false) + , m_postData(NULL) + , m_request(handle->firstRequest().toNetworkRequest( + context ? &context->storageSession()->platformSession() : nullptr)) + , m_position(0) + , m_redirectionTries(gMaxRecursionLimit) +{ + if (!m_resourceHandle) + return; + + BString method = BString(m_resourceHandle->firstRequest().httpMethod()); + + m_postData = NULL; + + if (m_request == NULL) + return; + + m_baseUrl = URL(m_request->Url()); + + BHttpRequest* httpRequest = dynamic_cast(m_request); + if(httpRequest) { + // TODO maybe we have data to send in other cases ? + if(method == B_HTTP_POST || method == B_HTTP_PUT) { + FormData* form = m_resourceHandle->firstRequest().httpBody(); + if(form) { + m_postData = new BFormDataIO(form); + httpRequest->AdoptInputData(m_postData, m_postData->Size()); + } + } + + httpRequest->SetMethod(method.String()); + } + + // In synchronous mode, call this listener directly. + // In asynchronous mode, go through a BMessage + if(this->SynchronousListener()) { + m_request->SetListener(this->SynchronousListener()); + } else { + m_request->SetListener(this); + } + + if (m_request->Run() < B_OK) { + ResourceHandleClient* client = m_resourceHandle->client(); + if (!client) + return; + + ResourceError error("BUrlProtocol", 42, + handle->firstRequest().url(), + "The service kit failed to start the request."); + client->didFail(m_resourceHandle, error); + } +} + +BUrlProtocolHandler::~BUrlProtocolHandler() +{ + abort(); + if (m_request) + m_request->SetListener(NULL); + delete m_request; +} + +void BUrlProtocolHandler::abort() +{ + if (m_resourceHandle != NULL && m_request != NULL) + m_request->Stop(); + + m_resourceHandle = NULL; +} + +static bool ignoreHttpError(BHttpRequest* reply, bool receivedData) +{ + int httpStatusCode = static_cast(reply->Result()).StatusCode(); + + if (httpStatusCode == 401 || httpStatusCode == 407) + return false; + + if (receivedData && (httpStatusCode >= 400 && httpStatusCode < 600)) + return true; + + return false; +} + +void BUrlProtocolHandler::RequestCompleted(BUrlRequest* caller, bool success) +{ + if (!m_resourceHandle) + return; + + ResourceHandleClient* client = m_resourceHandle->client(); + if (!client) + return; + + BHttpRequest* httpRequest = dynamic_cast(m_request); + + if (success || (httpRequest && ignoreHttpError(httpRequest, m_responseDataSent))) { + client->didFinishLoading(m_resourceHandle); + return; + } else if(httpRequest) { + const BHttpResult& result = static_cast(httpRequest->Result()); + int httpStatusCode = result.StatusCode(); + + if (httpStatusCode != 0) { + ResourceError error("HTTP", httpStatusCode, + URL(caller->Url()), strerror(caller->Status())); + + client->didFail(m_resourceHandle, error); + return; + } + } + + // If we get here, it means we are in failure without an HTTP error code + // (DNS error, or error from a protocol other than HTTP). + ResourceError error("BUrlRequest", caller->Status(), URL(caller->Url()), strerror(caller->Status())); + client->didFail(m_resourceHandle, error); +} + + +bool BUrlProtocolHandler::CertificateVerificationFailed(BUrlRequest*, + BCertificate& certificate, const char* message) +{ + return m_resourceHandle->didReceiveInvalidCertificate(certificate, message); +} + + +void BUrlProtocolHandler::AuthenticationNeeded(BHttpRequest* request, ResourceResponse& response) +{ + if (!m_resourceHandle) + return; + + ResourceHandleInternal* d = m_resourceHandle->getInternal(); + unsigned failureCount = 0; + + const URL& url = m_resourceHandle->firstRequest().url(); + ProtectionSpaceServerType serverType = ProtectionSpaceServerHTTP; + if (url.protocolIs("https")) + serverType = ProtectionSpaceServerHTTPS; + + String challenge = static_cast(request->Result()).Headers()["WWW-Authenticate"]; + ProtectionSpaceAuthenticationScheme scheme = ProtectionSpaceAuthenticationSchemeDefault; + + ResourceHandleClient* client = m_resourceHandle->client(); + + // TODO according to RFC7235, there could be more than one challenge in WWW-Authenticate. We + // should parse them all, instead of just the first one. + if (challenge.startsWith("Digest")) + scheme = ProtectionSpaceAuthenticationSchemeHTTPDigest; + else if (challenge.startsWith("Basic")) + scheme = ProtectionSpaceAuthenticationSchemeHTTPBasic; + else { + // Unknown authentication type, ignore (various websites are intercepting the auth and + // handling it by themselves) + return; + } + + String realm; + int realmStart = challenge.find("realm=\"", 0); + if (realmStart > 0) { + realmStart += 7; + int realmEnd = challenge.find("\"", realmStart); + if (realmEnd >= 0) + realm = challenge.substring(realmStart, realmEnd - realmStart); + } + + int port; + if (url.port()) + port = *url.port(); + else if (url.protocolIs("https")) + port = 443; + else + port = 80; + ProtectionSpace protectionSpace(url.host().utf8().data(), port, serverType, realm, scheme); + ResourceError resourceError(url.host().utf8().data(), 401, url, String()); + + m_redirectionTries--; + if(m_redirectionTries == 0) + { + client->didFinishLoading(m_resourceHandle); + return; + } + + Credential proposedCredential(d->m_user, d->m_pass, CredentialPersistenceForSession); + + AuthenticationChallenge authenticationChallenge(protectionSpace, + proposedCredential, failureCount++, response, resourceError); + authenticationChallenge.m_authenticationClient = m_resourceHandle; + m_resourceHandle->didReceiveAuthenticationChallenge(authenticationChallenge); + // will set m_user and m_pass in ResourceHandleInternal + + if (d->m_user != "") { + // Handle this just like redirects. + m_redirected = true; + + ResourceRequest request = m_resourceHandle->firstRequest(); + ResourceResponse responseCopy = response; + request.setCredentials(d->m_user.utf8().data(), d->m_pass.utf8().data()); + client->willSendRequestAsync(m_resourceHandle, WTFMove(request), WTFMove(responseCopy), + [handle = makeRef(*m_resourceHandle)] (ResourceRequest&& request) { + //continueAfterWillSendRequest(handle.ptr(), WTFMove(request)); + }); + } else { + // Anything to do in case of failure? + } +} + + +void BUrlProtocolHandler::ConnectionOpened(BUrlRequest*) +{ + m_responseDataSent = false; +} + + +void BUrlProtocolHandler::HeadersReceived(BUrlRequest* caller, + const BUrlResult& result) +{ + if (!m_resourceHandle) + return; + + const BHttpResult* httpResult = dynamic_cast(&result); + + WTF::String contentType = result.ContentType(); + int contentLength = result.Length(); + URL url; + + WTF::String encoding = extractCharsetFromMediaType(contentType); + WTF::String mimeType = extractMIMETypeFromMediaType(contentType); + + if (httpResult) { + url = URL(httpResult->Url()); + + BString location = httpResult->Headers()["Location"]; + if (location.Length() > 0) { + m_redirected = true; + url = URL(url, location); + } else { + m_redirected = false; + } + } else { + url = m_baseUrl; + } + + ResourceResponse response(url, mimeType, contentLength, encoding); + + if (httpResult) { + int statusCode = httpResult->StatusCode(); + + String suggestedFilename = filenameFromHTTPContentDisposition( + httpResult->Headers()["Content-Disposition"]); + + if (!suggestedFilename.isEmpty()) + response.setSuggestedFilename(suggestedFilename); + + response.setHTTPStatusCode(statusCode); + response.setHTTPStatusText(httpResult->StatusText()); + + // Add remaining headers. + const BHttpHeaders& resultHeaders = httpResult->Headers(); + for (int i = 0; i < resultHeaders.CountHeaders(); i++) { + BHttpHeader& headerPair = resultHeaders.HeaderAt(i); + response.setHTTPHeaderField(headerPair.Name(), headerPair.Value()); + } + + if (statusCode == 401) { + AuthenticationNeeded((BHttpRequest*)m_request, response); + // AuthenticationNeeded may have aborted the request + // so we need to make sure we can continue. + if (!m_resourceHandle) + return; + } + } + + ResourceHandleClient* client = m_resourceHandle->client(); + if (!client) + return; + + if (m_redirected) { + m_redirectionTries--; + + if (m_redirectionTries == 0) { + ResourceError error(url.host().utf8().data(), 400, url, + "Redirection limit reached"); + client->didFail(m_resourceHandle, error); + return; + } + + // Notify the client that we are redirecting. + ResourceRequest request = m_resourceHandle->firstRequest(); + ResourceResponse responseCopy = response; + request.setURL(url); + + client->willSendRequestAsync(m_resourceHandle, WTFMove(request), WTFMove(responseCopy), + [handle = makeRef(*m_resourceHandle)] (ResourceRequest&& request) { + //continueAfterWillSendRequest(handle.ptr(), WTFMove(request)); + }); + } else { + ResourceResponse responseCopy = response; + // Make sure the resource handle is not deleted immediately, otherwise + // didReceiveResponse would crash. Keep a reference to it so it can be + // deleted cleanly after the function returns. + RefPtr protectedHandle(m_resourceHandle); + protectedHandle->didReceiveResponse(WTFMove(responseCopy), [this/*, protectedThis = makeRef(*this)*/] { + //continueAfterDidReceiveResponse(); + }); + } +} + +void BUrlProtocolHandler::DataReceived(BUrlRequest* caller, const char* data, + off_t position, ssize_t size) +{ + if (!m_resourceHandle) + return; + + ResourceHandleClient* client = m_resourceHandle->client(); + if (!client) + return; + + // don't emit the "Document has moved here" type of HTML + if (m_redirected) + return; + + if (position != m_position) + { + debugger("bad redirect"); + return; + } + + if (size > 0) { + m_responseDataSent = true; + client->didReceiveData(m_resourceHandle, data, size, size); + } + + m_position += size; +} + +void BUrlProtocolHandler::UploadProgress(BUrlRequest* caller, ssize_t bytesSent, ssize_t bytesTotal) +{ + if (!m_resourceHandle) + return; + + ResourceHandleClient* client = m_resourceHandle->client(); + if (!client) + return; + + client->didSendData(m_resourceHandle, bytesSent, bytesTotal); +} + +} diff --git a/Source/WebCore/platform/network/haiku/BUrlProtocolHandler.h b/Source/WebCore/platform/network/haiku/BUrlProtocolHandler.h new file mode 100644 index 000000000000..71b55685adb1 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/BUrlProtocolHandler.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef BURLPROTOCOLHANDLER_H +#define BURLPROTOCOLHANDLER_H + +#include "HaikuFormDataStream.h" +#include "ResourceRequest.h" + +#include +#include +#include +#include + +class BFile; + +namespace WebCore { + +class NetworkingContext; +class ResourceHandle; +class ResourceResponse; + +class BUrlProtocolHandler : public BUrlProtocolAsynchronousListener +{ +public: + BUrlProtocolHandler(NetworkingContext* context, ResourceHandle *handle, + bool synchronous); + virtual ~BUrlProtocolHandler(); + void abort(); + + bool isValid() { return m_request != NULL; } + +private: + void AuthenticationNeeded(BHttpRequest* caller, ResourceResponse& response); + + // BUrlListener hooks + void ConnectionOpened(BUrlRequest* caller) override; + void HeadersReceived(BUrlRequest* caller, const BUrlResult& result) override; + void DataReceived(BUrlRequest* caller, const char* data, off_t position, + ssize_t size) override; + void UploadProgress(BUrlRequest* caller, ssize_t bytesSent, ssize_t bytesTotal) override; + void RequestCompleted(BUrlRequest* caller, bool success) override; + bool CertificateVerificationFailed(BUrlRequest* caller, BCertificate& certificate, const char* message) override; + +private: + ResourceHandle* m_resourceHandle; + bool m_redirected; + bool m_responseDataSent; + BFormDataIO* m_postData; + BUrlRequest* m_request; + off_t m_position; + URL m_baseUrl; + + int m_redirectionTries; +}; + +} + +#endif // BURLPROTOCOLHANDLER_H diff --git a/Source/WebCore/platform/network/haiku/CertificateInfo.cpp b/Source/WebCore/platform/network/haiku/CertificateInfo.cpp new file mode 100644 index 000000000000..ade3c990ccca --- /dev/null +++ b/Source/WebCore/platform/network/haiku/CertificateInfo.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "CertificateInfo.h" + +#include "NotImplemented.h" +#include "ResourceError.h" +#include "ResourceResponse.h" + +namespace WebCore { + +CertificateInfo::CertificateInfo() + : m_certificate(nullptr) +{ +} + +} // namespace WebCore + diff --git a/Source/WebCore/platform/network/haiku/CertificateInfo.h b/Source/WebCore/platform/network/haiku/CertificateInfo.h new file mode 100644 index 000000000000..ea5cecaedd71 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/CertificateInfo.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 Haiku Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CertificateInfo_h +#define CertificateInfo_h + +#include "CertificateInfoBase.h" +#include "NotImplemented.h" +#include +#include +#include +#include +#include + +#include + +namespace WebCore { + +class ResourceError; +class ResourceResponse; + +class CertificateInfo : public CertificateInfoBase { +public: + CertificateInfo(); + explicit CertificateInfo(const BCertificate& certificate) + : m_certificate(&certificate) + { } + + Optional summaryInfo() const { notImplemented(); return WTF::nullopt; } + + const BCertificate& certificate() const { return *m_certificate; } + +private: + const BCertificate* m_certificate; +}; + +} // namespace WebCore + +namespace WTF { +namespace Persistence { + +template<> struct Coder { + static void encode(Encoder& encoder, const WebCore::CertificateInfo& certificateInfo) + { + notImplemented(); + } + + static bool decode(Decoder& decoder, WebCore::CertificateInfo& certificateInfo) + { + notImplemented(); + return false; + } +}; + +} // namespace WTF::Persistence +} // namespace WTF + +#endif // CertificateInfo_h diff --git a/Source/WebCore/platform/network/haiku/CookieJarHaiku.cpp b/Source/WebCore/platform/network/haiku/CookieJarHaiku.cpp new file mode 100644 index 000000000000..62085c5dc86c --- /dev/null +++ b/Source/WebCore/platform/network/haiku/CookieJarHaiku.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 George Staikos + * Copyright (C) 2007 Ryan Leavengood + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "CookieStorage.h" + +#include "NetworkStorageSession.h" +#include "NotImplemented.h" + +#include +#include + +#include +#include + +#define TRACE_COOKIE_JAR 0 + + +namespace WebCore { + +void setCookieStoragePrivateBrowsingEnabled(bool) +{ +#if TRACE_COOKIE_JAR + printf("CookieJar: private browsing (NOT IMPLEMENTED)\n"); +#endif +} + +void startObservingCookieChanges(const NetworkStorageSession& storageSession, WTF::Function&& callback) +{ + notImplemented(); +} + +void stopObservingCookieChanges(const NetworkStorageSession& storageSession) +{ +} + +} // namespace WebCore + diff --git a/Source/WebCore/platform/network/haiku/CredentialStorageHaiku.cpp b/Source/WebCore/platform/network/haiku/CredentialStorageHaiku.cpp new file mode 100644 index 000000000000..54ccad05651d --- /dev/null +++ b/Source/WebCore/platform/network/haiku/CredentialStorageHaiku.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CredentialStorage.h" + +#include "Credential.h" + +namespace WebCore { + +Credential CredentialStorage::getFromPersistentStorage(const ProtectionSpace&) +{ + return Credential(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/network/haiku/DNSHaiku.cpp b/Source/WebCore/platform/network/haiku/DNSHaiku.cpp new file mode 100644 index 000000000000..1aaeb881333c --- /dev/null +++ b/Source/WebCore/platform/network/haiku/DNSHaiku.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DNS.h" +#include "DNSResolveQueueHaiku.h" + +#include "NotImplemented.h" + +namespace WebCore { + +void DNSResolveQueueHaiku::updateIsUsingProxy() +{ + notImplemented(); +} + +void DNSResolveQueueHaiku::platformResolve(const String& /* hostname */) +{ + notImplemented(); +} + +void DNSResolveQueueHaiku::resolve(const String& /* hostname */, uint64_t /* identifier */, DNSCompletionHandler&& /* completionHandler */) +{ + notImplemented(); +} + +void DNSResolveQueueHaiku::stopResolve(uint64_t /* identifier */) +{ + notImplemented(); +} + +} diff --git a/Source/WebCore/platform/network/haiku/DNSResolveQueueHaiku.h b/Source/WebCore/platform/network/haiku/DNSResolveQueueHaiku.h new file mode 100644 index 000000000000..1e9ede28cd4f --- /dev/null +++ b/Source/WebCore/platform/network/haiku/DNSResolveQueueHaiku.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 Adrien Destugues + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "DNSResolveQueue.h" + +namespace WebCore { + +class DNSResolveQueueHaiku final : public DNSResolveQueue { +public: + DNSResolveQueueHaiku() = default; + void resolve(const String& hostname, uint64_t identifier, DNSCompletionHandler&&) final; + void stopResolve(uint64_t identifier) final; + +private: + void updateIsUsingProxy() final; + void platformResolve(const String&) final; +}; + +using DNSResolveQueuePlatform = DNSResolveQueueHaiku; + +} diff --git a/Source/WebCore/platform/network/haiku/HaikuFormDataStream.cpp b/Source/WebCore/platform/network/haiku/HaikuFormDataStream.cpp new file mode 100644 index 000000000000..7a182fd4b3d8 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/HaikuFormDataStream.cpp @@ -0,0 +1,239 @@ +/* + Copyright (C) 2018 Haiku, inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "HaikuFormDataStream.h" + +#include "BlobRegistry.h" +#include "BlobRegistryImpl.h" +#include "SharedBuffer.h" + +#include + +namespace WebCore { + +BFormDataIO::BFormDataIO(const FormData* formData) +{ + ASSERT(isMainThread()); + + if (!formData || formData->isEmpty()) + return; + + m_formData = formData->isolatedCopy(); + + // Resolve the blob elements so the formData can correctly report it's size. + m_formData = m_formData->resolveBlobReferences(blobRegistry()); +} + +BFormDataIO::~BFormDataIO() +{ +} + +ssize_t BFormDataIO::Size() +{ + computeContentLength(); + + return m_totalSize; +} + + +ssize_t +BFormDataIO::Read(void* buffer, size_t size) +{ + if (!m_formData) + return -1; + + const auto totalElementSize = m_formData->elements().size(); + if (m_elementPosition >= totalElementSize) + return 0; + + size_t totalReadBytes = 0; + + while ((m_elementPosition < totalElementSize) && (totalReadBytes < size)) { + const auto& element = m_formData->elements().at(m_elementPosition); + + size_t bufferSize = size - totalReadBytes; + char* bufferPosition = (char*)buffer + totalReadBytes; + + WTF::Optional readBytes = switchOn(element.data, + [&] (const Vector& bytes) { + return readFromData(bytes, bufferPosition, bufferSize); + }, [&] (const FormDataElement::EncodedFileData& fileData) { + return readFromFile(fileData, bufferPosition, bufferSize); + }, [&] (const FormDataElement::EncodedBlobData& blobData) { + return readFromBlob(blobData, bufferPosition, bufferSize); + } + ); + + if (!readBytes) + return -1; + + totalReadBytes += *readBytes; + } + + m_totalReadSize += totalReadBytes; + + return totalReadBytes; +} + +ssize_t +BFormDataIO::Write(const void* /*buffer*/, size_t /*size*/) +{ + // Write isn't implemented since we don't use it + return B_NOT_SUPPORTED; +} + + +void BFormDataIO::computeContentLength() +{ + if (!m_formData || m_isContentLengthUpdated) + return; + + m_isContentLengthUpdated = true; + + for (const auto& element : m_formData->elements()) + m_totalSize += element.lengthInBytes(); +} + + +WTF::Optional BFormDataIO::readFromFile(const FormDataElement::EncodedFileData& fileData, char* buffer, size_t size) +{ + if (m_fileHandle == FileSystem::invalidPlatformFileHandle) + m_fileHandle = FileSystem::openFile(fileData.filename, FileSystem::FileOpenMode::Read); + + if (!FileSystem::isHandleValid(m_fileHandle)) { + LOG(Network, "Haiku - Failed while trying to open %s for upload\n", fileData.filename.utf8().data()); + m_fileHandle = FileSystem::invalidPlatformFileHandle; + return WTF::nullopt; + } + + // Note: there is no management of a file offset, we just keep the file + // handle open and read from the current position. + auto readBytes = FileSystem::readFromFile(m_fileHandle, buffer, size); + if (readBytes < 0) { + LOG(Network, "Haiku - Failed while trying to read %s for upload\n", fileData.filename.utf8().data()); + FileSystem::closeFile(m_fileHandle); + m_fileHandle = FileSystem::invalidPlatformFileHandle; + return WTF::nullopt; + } + + if (!readBytes) { + FileSystem::closeFile(m_fileHandle); + m_fileHandle = FileSystem::invalidPlatformFileHandle; + m_elementPosition++; + } + + return readBytes; +} + +WTF::Optional BFormDataIO::readFromData(const Vector& data, char* buffer, size_t size) +{ + size_t elementSize = data.size() - m_dataOffset; + const char* elementBuffer = data.data() + m_dataOffset; + + size_t readBytes = elementSize > size ? size : elementSize; + memcpy(buffer, elementBuffer, readBytes); + + if (elementSize > readBytes) + m_dataOffset += readBytes; + else { + m_dataOffset = 0; + m_elementPosition++; + } + + return readBytes; +} + + +WTF::Optional BFormDataIO::readFromBlob(const FormDataElement::EncodedBlobData& blob, char* buffer, size_t size) +{ + auto* blobData = static_cast(blobRegistry()).getBlobDataFromURL(blob.url); + + if (!blobData) + return WTF::nullopt; + + auto& blobItem = blobData->items().at(m_blobItemIndex); + off_t readBytes; + + switch (blobItem.type()) { + case BlobDataItem::Type::Data: + { + size_t elementSize = blobItem.data().data()->size() - m_dataOffset; + const uint8_t* elementBuffer = blobItem.data().data()->data() + m_dataOffset; + + readBytes = elementSize > size ? size : elementSize; + memcpy(buffer, elementBuffer, readBytes); + + if (elementSize > readBytes) + m_dataOffset += readBytes; + else { + m_dataOffset = 0; + m_blobItemIndex++; + } + } + break; + case BlobDataItem::Type::File: { + // Open the file if not done yet + if (m_fileHandle == FileSystem::invalidPlatformFileHandle) + { + WTF::Optional fileModificationTime = FileSystem::getFileModificationTime(blobItem.file()->path()); + if (fileModificationTime + && fileModificationTime == blobItem.file()->expectedModificationTime()) + m_fileHandle = FileSystem::openFile(blobItem.file()->path(), FileSystem::FileOpenMode::Read); + + // FIXME the blob can specify an offset and chunk size inside the file + // So we should seek there and make sure we stop at the right time. + } + + + if (!FileSystem::isHandleValid(m_fileHandle)) { + LOG(Network, "Haiku - Failed while trying to open %s for upload\n", fileData.filename.utf8().data()); + m_fileHandle = FileSystem::invalidPlatformFileHandle; + readBytes = -1; + } else { + // Note: there is no management of a file offset, we just keep the file + // handle open and read from the current position. + readBytes = FileSystem::readFromFile(m_fileHandle, buffer, size); + if (readBytes < 0) { + LOG(Network, "Haiku - Failed while trying to read %s for upload\n", fileData.filename.utf8().data()); + } + } + + if (readBytes <= 0) { + FileSystem::closeFile(m_fileHandle); + m_fileHandle = FileSystem::invalidPlatformFileHandle; + m_blobItemIndex++; + } + } + break; + } + + // Should we advance to the next form element yet? + if (m_blobItemIndex > blobData->items().size()) + { + m_elementPosition++; + m_blobItemIndex = 0; + } + + if (readBytes < 0) + return WTF::nullopt; + return readBytes; +} + +}; diff --git a/Source/WebCore/platform/network/haiku/HaikuFormDataStream.h b/Source/WebCore/platform/network/haiku/HaikuFormDataStream.h new file mode 100644 index 000000000000..6ab0cabb3c52 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/HaikuFormDataStream.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2018 Haiku, inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HAIKUFORMDATASTREAM_H +#define HAIKUFORMDATASTREAM_H + +#include "wtf/FileSystem.h" +#include "FormData.h" + +#include +#include + +namespace WebCore { + +class BFormDataIO : public BDataIO +{ +public: + BFormDataIO(const FormData* form); + ~BFormDataIO(); + + ssize_t Size(); + ssize_t Read(void* buffer, size_t size) override; + ssize_t Write(const void* buffer, size_t size) override; + +private: + void computeContentLength(); + + WTF::Optional readFromFile(const FormDataElement::EncodedFileData&, char*, size_t); + WTF::Optional readFromData(const Vector&, char*, size_t); + WTF::Optional readFromBlob(const FormDataElement::EncodedBlobData&, char*, size_t); + + RefPtr m_formData; + + bool m_isContentLengthUpdated { false }; + unsigned long long m_totalSize { 0 }; + unsigned long long m_totalReadSize { 0 }; + + size_t m_elementPosition { 0 }; + size_t m_blobItemIndex { 0 }; + + FileSystem::PlatformFileHandle m_fileHandle { FileSystem::invalidPlatformFileHandle }; + size_t m_dataOffset { 0 }; +}; + +}; + + +#endif /* !HAIKUFORMDATASTREAM_H */ diff --git a/Source/WebCore/platform/network/haiku/NetworkStateNotifierHaiku.cpp b/Source/WebCore/platform/network/haiku/NetworkStateNotifierHaiku.cpp new file mode 100644 index 000000000000..47cb3e98d72d --- /dev/null +++ b/Source/WebCore/platform/network/haiku/NetworkStateNotifierHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkStateNotifier.h" +#include "NotImplemented.h" + +#include +#include + +namespace WebCore { + +void NetworkStateNotifier::updateStateWithoutNotifying() +{ + // Should return true if at least one network interface is up. + notImplemented(); + m_isOnLine = true; +} + +void NetworkStateNotifier::startObserving() +{ + // Should register to call singleton().updateStateSoon() when an interface is up/down + notImplemented(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/network/haiku/NetworkStorageSessionHaiku.cpp b/Source/WebCore/platform/network/haiku/NetworkStorageSessionHaiku.cpp new file mode 100644 index 000000000000..e21d2c689345 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/NetworkStorageSessionHaiku.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013 University of Szeged. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkStorageSession.h" + +#include +#include + +#include "Cookie.h" +#include "CookieRequestHeaderFieldProxy.h" +#include "NetworkingContext.h" +#include "NotImplemented.h" +#include "ResourceHandle.h" +#include "wtf/URL.h" + +#include +#include + +#define TRACE_COOKIE_JAR 0 + +namespace WebCore { + +NetworkStorageSession::NetworkStorageSession(PAL::SessionID sessionID) + : m_sessionID(sessionID) + , m_context(nullptr) +{ +} + +NetworkStorageSession::~NetworkStorageSession() +{ +} + +static std::unique_ptr& defaultSession() +{ + ASSERT(isMainThread()); + static NeverDestroyed> session; + return session; +} + +void NetworkStorageSession::setCookiesFromDOM(const URL& firstParty, + const SameSiteInfo& sameSiteInfo, const URL& url, + WTF::Optional frameID, WTF::Optional pageID, + const String& value) const +{ + BNetworkCookie* heapCookie + = new BNetworkCookie(value, BUrl(url)); + +#if TRACE_COOKIE_JAR + printf("CookieJar: Add %s for %s\n", heapCookie->RawCookie(true).String(), + url.string().utf8().data()); + printf(" from %s\n", value.utf8().data()); +#endif + platformSession().GetCookieJar().AddCookie(heapCookie); +} + +bool NetworkStorageSession::cookiesEnabled() const +{ + return true; +} + +std::pair NetworkStorageSession::cookiesForDOM(const URL& firstParty, + const SameSiteInfo& sameSiteInfo, const URL& url, + WTF::Optional frameID, WTF::Optional pageID, + IncludeSecureCookies includeSecureCookies) const +{ +#if TRACE_COOKIE_JAR + printf("CookieJar: Request for %s\n", url.string().utf8().data()); +#endif + + BString result; + BUrl hUrl(url); + bool secure = false; + + const BNetworkCookie* c; + for (BNetworkCookieJar::UrlIterator it( + platformSession().GetCookieJar().GetUrlIterator(hUrl)); + (c = it.Next()); ) { + // filter out httpOnly cookies,as this method is used to get cookies + // from JS code and these shouldn't be visible there. + if(c->HttpOnly()) + continue; + + // filter out secure cookies if they should be + if (c->Secure()) + { + secure = true; + if (includeSecureCookies == IncludeSecureCookies::No) + continue; + } + + result << "; " << c->RawCookie(false); + } + result.Remove(0, 2); + + return {result, secure}; +} + +void NetworkStorageSession::setCookies(const Vector&, const URL&, const URL&) +{ + // FIXME: Implement for WebKit to use. +} + +void NetworkStorageSession::setCookie(const Cookie&) +{ + // FIXME: Implement for WebKit to use. +} + +void NetworkStorageSession::deleteCookie(const Cookie&) +{ + // FIXME: Implement for WebKit to use. +} + +void NetworkStorageSession::deleteCookie(const URL& url, const String& cookie) const +{ +#if TRACE_COOKIE_JAR + printf("CookieJar: delete cookie for %s (NOT IMPLEMENTED)\n", url.string().utf8().data()); +#endif + notImplemented(); +} + +void NetworkStorageSession::deleteAllCookies() +{ + notImplemented(); +} + +void NetworkStorageSession::deleteAllCookiesModifiedSince(WallTime since) +{ + notImplemented(); +} + +void NetworkStorageSession::deleteCookiesForHostnames(const Vector& cookieHostNames) +{ + notImplemented(); +} + +Vector NetworkStorageSession::getAllCookies() +{ + // FIXME: Implement for WebKit to use. + return { }; +} + +void NetworkStorageSession::getHostnamesWithCookies(HashSet& hostnames) +{ + notImplemented(); +} + +Vector NetworkStorageSession::getCookies(const URL&) +{ + // FIXME: Implement for WebKit to use. + return { }; +} + +bool NetworkStorageSession::getRawCookies(const URL& firstParty, + const SameSiteInfo& sameSiteInfo, const URL& url, WTF::Optional frameID, + WTF::Optional pageID, Vector& rawCookies) const +{ +#if TRACE_COOKIE_JAR + printf("CookieJar: get raw cookies for %s (NOT IMPLEMENTED)\n", url.string().utf8().data()); +#endif + notImplemented(); + + rawCookies.clear(); + return false; // return true when implemented +} + +void NetworkStorageSession::flushCookieStore() +{ + // FIXME: Implement for WebKit to use. +} + +std::pair NetworkStorageSession::cookieRequestHeaderFieldValue(const URL& firstParty, + const SameSiteInfo& sameSiteInfo, const URL& url, WTF::Optional frameID, + WTF::Optional pageID, IncludeSecureCookies includeSecureCookies) const +{ +#if TRACE_COOKIE_JAR + printf("CookieJar: RequestHeaderField for %s\n", url.string().utf8().data()); +#endif + + BString result; + BUrl hUrl(url); + bool secure = false; + + const BNetworkCookie* c; + for (BNetworkCookieJar::UrlIterator it( + platformSession().GetCookieJar().GetUrlIterator(hUrl)); + (c = it.Next()); ) { + // filter out secure cookies if they should be + if (c->Secure()) + { + secure = true; + if (includeSecureCookies == IncludeSecureCookies::No) + continue; + } + + result << "; " << c->RawCookie(false); + } + result.Remove(0, 2); + + return {result, secure}; +} + +std::pair NetworkStorageSession::cookieRequestHeaderFieldValue(const CookieRequestHeaderFieldProxy& headerFieldProxy) const +{ + return cookieRequestHeaderFieldValue(headerFieldProxy.firstParty, headerFieldProxy.sameSiteInfo, headerFieldProxy.url, headerFieldProxy.frameID, headerFieldProxy.pageID, headerFieldProxy.includeSecureCookies); +} + +BUrlContext& NetworkStorageSession::platformSession() const +{ + static BUrlContext sDefaultContext; + return m_context ? *m_context : sDefaultContext; +} + +void NetworkStorageSession::setPlatformSession(BUrlContext* context) +{ + m_context = context; +} + +} + diff --git a/Source/WebCore/platform/network/haiku/ProxyServerHaiku.cpp b/Source/WebCore/platform/network/haiku/ProxyServerHaiku.cpp new file mode 100644 index 000000000000..4bdde731a085 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/ProxyServerHaiku.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ProxyServer.h" + +#include "wtf/URL.h" + +namespace WebCore { + +Vector proxyServersForURL(const URL&) +{ + // FIXME: Implement. + return Vector(); +} + +} // namespace WebCore + diff --git a/Source/WebCore/platform/network/haiku/ResourceError.h b/Source/WebCore/platform/network/haiku/ResourceError.h new file mode 100644 index 000000000000..1996a6b85d9e --- /dev/null +++ b/Source/WebCore/platform/network/haiku/ResourceError.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ResourceError_h +#define ResourceError_h + +#include "ResourceErrorBase.h" + +namespace WebCore { + +class ResourceError : public ResourceErrorBase +{ +public: + ResourceError(Type type = Type::Null) + : ResourceErrorBase(type) + { + } + + ResourceError(const String& domain, int errorCode, const URL& failingURL, const String& localizedDescription, Type type = Type::General) + : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription, type) + { + } + +private: + friend class ResourceErrorBase; + void doPlatformIsolatedCopy(const ResourceError&) { } +}; +} + +#endif // ResourceError_h_ diff --git a/Source/WebCore/platform/network/haiku/ResourceHandleHaiku.cpp b/Source/WebCore/platform/network/haiku/ResourceHandleHaiku.cpp new file mode 100644 index 000000000000..f49280ca06fc --- /dev/null +++ b/Source/WebCore/platform/network/haiku/ResourceHandleHaiku.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2006 Nikolas Zimmermann + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2008 Holger Hans Peter Freyther + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ResourceHandle.h" + +#include "DocumentLoader.h" +#include "Frame.h" +#include "NotImplemented.h" +#include "Page.h" +#include "BUrlProtocolHandler.h" +#include "ResourceHandleClient.h" +#include "ResourceHandleInternal.h" +#include "SharedBuffer.h" + +// TODO move to SynchronousLoaderClientHaiku.cpp +#include "SynchronousLoaderClient.h" + +namespace WebCore { + +ResourceHandleInternal::~ResourceHandleInternal() +{ +} + +ResourceHandle::~ResourceHandle() +{ + cancel(); +} + +bool ResourceHandle::start() +{ + // If NetworkingContext is invalid then we are no longer attached to a Page, + // this must be an attempted load from an unload event handler, so let's just block it. + if (d->m_context && !d->m_context->isValid()) + return false; + + if (!d->m_user.isEmpty() || !d->m_pass.isEmpty()) { + // If credentials were specified for this request, add them to the url, + // so that they will be passed to QNetworkRequest. + URL urlWithCredentials(firstRequest().url()); + urlWithCredentials.setUser(d->m_user); + urlWithCredentials.setPass(d->m_pass); + d->m_firstRequest.setURL(urlWithCredentials); + } + + d->m_urlrequest = new BUrlProtocolHandler(d->m_context.get(), this, false); + + if (!d->m_urlrequest->isValid()) + scheduleFailure(InvalidURLFailure); + return true; +} + +void ResourceHandle::cancel() +{ + if (d->m_urlrequest) { + d->m_urlrequest->abort(); + delete d->m_urlrequest; + d->m_urlrequest = 0; + } +} + +void ResourceHandle::platformLoadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentialsPolicy /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector& data) +{ + ASSERT_NOT_REACHED(); +} + + +bool ResourceHandle::didReceiveInvalidCertificate(BCertificate& certificate, + const char* message) +{ + if (client()) + return client()->didReceiveInvalidCertificate(this, certificate, message); + return false; +} + + +void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) +{ + ResourceHandleInternal* internal = getInternal(); + ASSERT(internal->m_currentWebChallenge.isNull()); + ASSERT(challenge.authenticationClient() == this); // Should be already set. + internal->m_currentWebChallenge = challenge; + + if (client()) + client()->didReceiveAuthenticationChallenge(this, challenge); +} + +void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential) +{ + ASSERT(!challenge.isNull()); + ResourceHandleInternal* internal = getInternal(); + if (challenge != internal->m_currentWebChallenge) + return; + + internal->m_user = credential.user(); + internal->m_pass = credential.password(); + + clearAuthentication(); +} + +void ResourceHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge) +{ + ASSERT(!challenge.isNull()); + ResourceHandleInternal* internal = getInternal(); + if (challenge != internal->m_currentWebChallenge) + return; + + internal->m_user = ""; + internal->m_pass = ""; + + clearAuthentication(); +} + +void ResourceHandle::receivedCancellation(const AuthenticationChallenge&) +{ + // TODO +} + + +void ResourceHandle::receivedRequestToPerformDefaultHandling(const AuthenticationChallenge&) +{ + ASSERT_NOT_REACHED(); +} + + +void ResourceHandle::receivedChallengeRejection(const AuthenticationChallenge&) +{ + ASSERT_NOT_REACHED(); +} + + +void ResourceHandle::platformSetDefersLoading(bool defers) +{ + d->m_defersLoading = defers; + + /*if (d->m_job) + d->m_job->setLoadMode(QNetworkReplyHandler::LoadMode(defers));*/ +} + +// TODO move to SynchronousLoaderClientHaiku.cpp +void SynchronousLoaderClient::didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) +{ + notImplemented(); +} + +ResourceError SynchronousLoaderClient::platformBadResponseError() +{ + notImplemented(); + return ResourceError(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/network/haiku/ResourceRequest.h b/Source/WebCore/platform/network/haiku/ResourceRequest.h new file mode 100644 index 000000000000..de3542205d09 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/ResourceRequest.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * Copyright (C) 2019 Haiku, Inc. All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ResourceRequest_h +#define ResourceRequest_h + +#include "ResourceRequestBase.h" + +#include +#include + +class BUrlContext; +class BUrlRequest; + +namespace WebCore { + + class ResourceRequest : public ResourceRequestBase { + public: + ResourceRequest(const String& url) + : ResourceRequestBase(URL({ }, url), ResourceRequestCachePolicy::UseProtocolCachePolicy) + { + } + + ResourceRequest(const URL& url) + : ResourceRequestBase(url, ResourceRequestCachePolicy::UseProtocolCachePolicy) + { + } + + ResourceRequest(const URL& url, const String& referrer, ResourceRequestCachePolicy policy = ResourceRequestCachePolicy::UseProtocolCachePolicy) + : ResourceRequestBase(url, policy) + { + setHTTPReferrer(referrer); + } + + ResourceRequest() + : ResourceRequestBase(URL(), ResourceRequestCachePolicy::UseProtocolCachePolicy) + { + } + + BUrlRequest* toNetworkRequest(BUrlContext*); + + void setCredentials(const char* username, const char* password); + void updateFromDelegatePreservingOldProperties(const ResourceRequest& delegateProvidedRequest) { *this = delegateProvidedRequest; } + + template void encodePlatformData(Encoder&) const; + template bool decodePlatformData(Decoder&); + + private: + friend class ResourceRequestBase; + + void doUpdatePlatformRequest() {} + void doUpdateResourceRequest() {} + void doUpdatePlatformHTTPBody() { } + void doUpdateResourceHTTPBody() { } + + void doPlatformSetAsIsolatedCopy(const ResourceRequest&) { } + + BString fUsername; + BString fPassword; + }; + +template +void ResourceRequest::encodePlatformData(Encoder& encoder) const +{ + encodeBase(encoder); +} + +template +bool ResourceRequest::decodePlatformData(Decoder& decoder) +{ + if(!decodeBase(decoder)) + { + return false; + } + + return true; +} + +} // namespace WebCore + +#endif // ResourceRequest_h diff --git a/Source/WebCore/platform/network/haiku/ResourceRequestHaiku.cpp b/Source/WebCore/platform/network/haiku/ResourceRequestHaiku.cpp new file mode 100644 index 000000000000..d24b955c03e0 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/ResourceRequestHaiku.cpp @@ -0,0 +1,112 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ResourceRequest.h" + +#include "CookieJar.h" +#include "NetworkingContext.h" + +#include +#include +#include +#include +#include +#include + +namespace WebCore { + +BUrlRequest* ResourceRequest::toNetworkRequest(BUrlContext* context) +{ + BUrlRequest* request = BUrlProtocolRoster::MakeRequest(url()); + + if (!request) { + m_url = WTF::blankURL(); // This tells the ResourceLoader we failed. + return NULL; + } + + if (context) + request->SetContext(context); + + if (timeoutInterval() > 0) + request->SetTimeout(timeoutInterval()); + + BHttpRequest* httpRequest = dynamic_cast(request); + if (httpRequest != NULL) { + const HTTPHeaderMap &headers = httpHeaderFields(); + BHttpHeaders* requestHeaders = new BHttpHeaders(); + + for (HTTPHeaderMap::const_iterator it = headers.begin(), + end = headers.end(); it != end; ++it) + { + requestHeaders->AddHeader(it->key.utf8().data(), + it->value.utf8().data()); + } + + if (!fUsername.IsEmpty()) { + httpRequest->SetUserName(fUsername); + httpRequest->SetPassword(fPassword); + } + + if (!requestHeaders->HasHeader("Accept-Language")) { + // Add the default languages + BMessage message; + BLocaleRoster::Default()->GetPreferredLanguages(&message); + + BString languages; + BString language; + for(int i = 0; message.FindString("language", i, &language) == B_OK; i++) { + if (i != 0) + languages << ','; + languages << language; + languages << ";q="; + // This will lead to negative priorities if there are more than + // 100 languages. Hopefully no one can read that much... + languages << 1 - (i / 100.f); + + int underscore = language.FindFirst('_'); + if (underscore > 0) { + // Some page only accept 2-letter language codes (eg Google + // account login). Include that if we have a country suffix + language.Truncate(underscore); + languages << ','; + languages << language; + languages << ";q="; + languages << 1 - (i / 100.f); + } + } + + requestHeaders->AddHeader("Accept-Language", languages); + } + + httpRequest->AdoptHeaders(requestHeaders); + } + + return request; +} + + +void ResourceRequest::setCredentials(const char* username, const char* password) +{ + fUsername = username; + fPassword = password; +} + +} + diff --git a/Source/WebCore/platform/network/haiku/ResourceResponse.h b/Source/WebCore/platform/network/haiku/ResourceResponse.h new file mode 100644 index 000000000000..32f6341be466 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/ResourceResponse.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ResourceResponse_h +#define ResourceResponse_h + +#include "ResourceResponseBase.h" + +namespace WebCore { + +class ResourceResponse : public ResourceResponseBase { +public: + ResourceResponse() + { + } + + ResourceResponse(const URL& url, const String& mimeType, long long expectedLength, const String& textEncodingName) + : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName) + { + m_resourceName = url.lastPathComponent(); + } + + void setSuggestedFilename(String name) { m_resourceName = name;} + + template void encodePlatformData(Encoder&) const; + template bool decodePlatformData(Decoder&); + +private: + friend class ResourceResponseBase; + + String platformSuggestedFilename() const { return m_resourceName; } + + String m_resourceName; +}; + +template +void ResourceResponse::encodePlatformData(Encoder& encoder) const +{ + fprintf(stderr,"%s \n",__PRETTY_FUNCTION__); + encodeBase(encoder); +} + +template +bool ResourceResponse::decodePlatformData(Decoder& decoder) +{ + fprintf(stderr,"%s \n",__PRETTY_FUNCTION__); + if(!decodeBase(decoder)) + { + fprintf(stderr,"%s -- failed\n",__PRETTY_FUNCTION__); + return false; + } + + return true; +} + +} // namespace WebCore + +#endif // ResourceResponse_h diff --git a/Source/WebCore/platform/network/haiku/SocketStreamHandleHaiku.cpp b/Source/WebCore/platform/network/haiku/SocketStreamHandleHaiku.cpp new file mode 100644 index 000000000000..383032bc5d5f --- /dev/null +++ b/Source/WebCore/platform/network/haiku/SocketStreamHandleHaiku.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2009 Brent Fulgham. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SocketStreamHandleImpl.h" + +#include "Logging.h" +#include "SocketStreamError.h" +#include "SocketStreamHandleClient.h" +#include "StorageSessionProvider.h" + +#include +#include +#include + +#include +#include +#include + +namespace WebCore { + +SocketStreamHandleImpl::SocketStreamHandleImpl(const URL& url, SocketStreamHandleClient& client, const StorageSessionProvider* provider) + : SocketStreamHandle(url, client) + , m_storageSessionProvider(provider) +{ + LOG(Network, "SocketStreamHandle %p new client %p", this, &m_client); + ASSERT(isMainThread()); + + m_workerThread = Thread::create("WebSocket thread", [this, protectedThis = makeRef(*this)] { + threadEntryPoint(); + }); +} + +SocketStreamHandleImpl::~SocketStreamHandleImpl() +{ + LOG(Network, "SocketStreamHandle %p delete", this); + stopThread(); +} + +Optional SocketStreamHandleImpl::platformSendInternal(const uint8_t* data, size_t length) +{ + LOG(Network, "SocketStreamHandle %p platformSend", this); + ASSERT(isMainThread()); + + if (m_hasPendingWriteData) + return 0; + + m_hasPendingWriteData = true; + + auto writeBuffer = makeUniqueArray(length); + memcpy(writeBuffer.get(), data, length); + + callOnWorkerThread([this, writeBuffer = WTFMove(writeBuffer), writeBufferSize = length]() mutable { + ASSERT(!isMainThread()); + m_writeBuffer = WTFMove(writeBuffer); + m_writeBufferSize = writeBufferSize; + m_writeBufferOffset = 0; + }); + + return length; +} + +void SocketStreamHandleImpl::platformClose() +{ + LOG(Network, "SocketStreamHandle %p platformClose", this); + ASSERT(isMainThread()); + + if (m_state == Closed) + return; + m_state = Closed; + + stopThread(); + m_client.didCloseSocketStream(*this); +} + +void SocketStreamHandleImpl::threadEntryPoint() +{ + ASSERT(!isMainThread()); + + unsigned int port = m_url.port() ? *m_url.port() : (m_url.protocolIs("wss") ? 443 : 80); + BNetworkAddress peer(m_url.host().utf8().data(), port); + BSocket* socket = m_url.protocolIs("wss") ? new BSecureSocket : new BSocket; + + // Connect to host + status_t status = socket->Connect(peer); + if (status != B_OK) { + handleError(status); + return; + } + + callOnMainThread([this, protectedThis = makeRef(*this)] { + if (m_state == Connecting) { + m_state = Open; + m_client.didOpenSocketStream(*this); + } + }); + + while (m_running) { + executeTasks(); + + status_t readable = socket->WaitForReadable(20 * 1000); + status_t writable = B_ERROR; + if (m_writeBuffer.get() != nullptr) + writable = socket->WaitForWritable(20 * 1000); + + // These logic only run when there's data waiting. + if ((writable == B_OK) && m_running) { + auto bytesSent = socket->Write(m_writeBuffer.get() + m_writeBufferOffset, m_writeBufferSize - m_writeBufferOffset); + m_writeBufferOffset += bytesSent; + + if (m_writeBufferSize <= m_writeBufferOffset) { + m_writeBuffer = nullptr; + m_writeBufferSize = 0; + m_writeBufferOffset = 0; + + callOnMainThread([this, protectedThis = makeRef(*this)] { + m_hasPendingWriteData = false; + sendPendingData(); + }); + } + } + + if ((readable == B_OK) && m_running) { + auto readBuffer = makeUniqueArray(kReadBufferSize); + ssize_t bytesRead = socket->Read(readBuffer.get(), kReadBufferSize); + // `0` result means nothing to handle at this moment. + if (bytesRead <= 0) { + // Make sure we are still connected. + if (!socket->IsConnected()) { + m_running = false; + callOnMainThread([this, protectedThis = makeRef(*this)] { + close(); + }); + break; + } + continue; + } + + callOnMainThread([this, protectedThis = makeRef(*this), buffer = WTFMove(readBuffer), size = bytesRead ] { + if (m_state == Open) + m_client.didReceiveSocketStreamData(*this, reinterpret_cast(buffer.get()), size); + }); + } + } + + m_writeBuffer = nullptr; + delete socket; +} + +void SocketStreamHandleImpl::handleError(status_t errorCode) +{ + m_running = false; + callOnMainThread([this, protectedThis = makeRef(*this), errorCode, localizedDescription = strerror(errorCode)] { + if (m_state == Closed) + return; + + // TODO: when to call m_client.didFailToReceiveSocketStreamData(*this); ? + m_client.didFailSocketStream(*this, SocketStreamError(static_cast(errorCode), { }, localizedDescription)); + }); +} + +void SocketStreamHandleImpl::stopThread() +{ + ASSERT(isMainThread()); + + m_running = false; + + if (m_workerThread) { + m_workerThread->waitForCompletion(); + m_workerThread = nullptr; + } +} + +void SocketStreamHandleImpl::callOnWorkerThread(Function&& task) +{ + ASSERT(isMainThread()); + m_taskQueue.append(std::make_unique>(WTFMove(task))); +} + +void SocketStreamHandleImpl::executeTasks() +{ + ASSERT(!isMainThread()); + + auto tasks = m_taskQueue.takeAllMessages(); + for (auto& task : tasks) + (*task)(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/network/haiku/SocketStreamHandleImpl.h b/Source/WebCore/platform/network/haiku/SocketStreamHandleImpl.h new file mode 100644 index 000000000000..322b25b0fed2 --- /dev/null +++ b/Source/WebCore/platform/network/haiku/SocketStreamHandleImpl.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009-2018 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "SocketStreamHandle.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace WebCore { + +class SocketStreamHandleClient; +class StorageSessionProvider; + +class SocketStreamHandleImpl : public SocketStreamHandle { +public: + static Ref create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&, const StorageSessionProvider* provider) { return adoptRef(*new SocketStreamHandleImpl(url, client, provider)); } + + virtual ~SocketStreamHandleImpl(); + + WEBCORE_EXPORT void platformSend(const uint8_t* data, size_t length, Function&&) final; + WEBCORE_EXPORT void platformSendHandshake(const uint8_t* data, size_t length, const Optional&, Function&&) final; + WEBCORE_EXPORT void platformClose() final; + +private: + WEBCORE_EXPORT SocketStreamHandleImpl(const URL&, SocketStreamHandleClient&, const StorageSessionProvider*); + + size_t bufferedAmount() final; + Optional platformSendInternal(const uint8_t*, size_t); + bool sendPendingData(); + + void threadEntryPoint(); + void handleError(status_t); + void stopThread(); + + void callOnWorkerThread(Function&&); + void executeTasks(); + + static const size_t kReadBufferSize = 4 * 1024; + + RefPtr m_storageSessionProvider; + RefPtr m_workerThread; + std::atomic m_running { true }; + + MessageQueue> m_taskQueue; + + bool m_hasPendingWriteData { false }; + size_t m_writeBufferSize { 0 }; + size_t m_writeBufferOffset { 0 }; + UniqueArray m_writeBuffer; + + StreamBuffer m_buffer; + static const unsigned maxBufferSize = 100 * 1024 * 1024; +}; + +} // namespace WebCore diff --git a/Source/WebCore/platform/text/haiku/StringHaiku.cpp b/Source/WebCore/platform/text/haiku/StringHaiku.cpp new file mode 100644 index 000000000000..e50ec909e4d2 --- /dev/null +++ b/Source/WebCore/platform/text/haiku/StringHaiku.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007 Ryan Leavengood + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include +#include + +#include + +namespace WTF { + +// String conversions +String::String(const BString& string) +{ + if (string.Length()) + m_impl = String::fromUTF8(string.String(), string.Length()).impl(); + else + m_impl = StringImpl::empty(); +} + +String::operator BString() const +{ + BString string; + string.SetTo(utf8().data()); + + return string; +} + +} // namespace WebCore + diff --git a/Source/WebKit/CMakeLists.txt b/Source/WebKit/CMakeLists.txt index b8e08c1fb42b..c453360d1910 100644 --- a/Source/WebKit/CMakeLists.txt +++ b/Source/WebKit/CMakeLists.txt @@ -96,6 +96,10 @@ set(WebKit_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/WebKitLibraries" ) +SET(WebKit_LOCAL_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/css" +) + set(PROTOCOL_GENERATOR_SCRIPTS_DIR "${JAVASCRIPTCORE_DIR}/inspector/scripts") list(APPEND WebKit_UNIFIED_SOURCE_LIST_FILES @@ -417,6 +421,15 @@ add_executable(WebProcess ${WebProcess_SOURCES}) ADD_WEBKIT_PREFIX_HEADER(WebProcess) target_link_libraries(WebProcess ${WebProcess_LIBRARIES}) +if (WebProcess_RESOURCES) + add_custom_command(TARGET WebProcess POST_BUILD + COMMAND rc -o WebProcess.rsrc ${WEBKIT_DIR}/haiku/WebProcess.rdef + COMMAND xres -o ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/WebProcess WebProcess.rsrc + COMMAND mimeset -f ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/WebProcess + DEPENDS ${WebProcess_RESOURCES} + VERBATIM) +endif() + if (WebKit_WebProcess_OUTPUT_NAME) set_target_properties(WebProcess PROPERTIES OUTPUT_NAME ${WebKit_WebProcess_OUTPUT_NAME}) endif () diff --git a/Source/WebKit/NetworkProcess/CustomProtocols/LegacyCustomProtocolManager.h b/Source/WebKit/NetworkProcess/CustomProtocols/LegacyCustomProtocolManager.h index dc79eebcf18d..5c47b3bd49fe 100644 --- a/Source/WebKit/NetworkProcess/CustomProtocols/LegacyCustomProtocolManager.h +++ b/Source/WebKit/NetworkProcess/CustomProtocols/LegacyCustomProtocolManager.h @@ -88,6 +88,12 @@ class LegacyCustomProtocolManager : public NetworkProcessSupplement, public IPC: }; typedef std::unique_ptr CustomProtocol; #endif +#if USE(HAIKU) + class HaikuCustomProtocolImpl { + // TODO + }; + typedef std::unique_ptr CustomProtocol; +#endif uint64_t addCustomProtocol(CustomProtocol&&); void removeCustomProtocol(uint64_t customProtocolID); diff --git a/Source/WebKit/NetworkProcess/EntryPoint/unix/NetworkProcessMain.cpp b/Source/WebKit/NetworkProcess/EntryPoint/unix/NetworkProcessMain.cpp index 736c01708a46..9f42524d4fac 100644 --- a/Source/WebKit/NetworkProcess/EntryPoint/unix/NetworkProcessMain.cpp +++ b/Source/WebKit/NetworkProcess/EntryPoint/unix/NetworkProcessMain.cpp @@ -24,6 +24,7 @@ */ #include "NetworkProcessMainUnix.h" +#include "wtf/Platform.h" #include diff --git a/Source/WebKit/NetworkProcess/NetworkDataTask.cpp b/Source/WebKit/NetworkProcess/NetworkDataTask.cpp index bcbae9d31fbf..41fa61792563 100644 --- a/Source/WebKit/NetworkProcess/NetworkDataTask.cpp +++ b/Source/WebKit/NetworkProcess/NetworkDataTask.cpp @@ -42,6 +42,9 @@ #if USE(CURL) #include "NetworkDataTaskCurl.h" #endif +#if PLATFORM(HAIKU) +#include "NetworkDataTaskHaiku.h" +#endif namespace WebKit { using namespace WebCore; @@ -58,6 +61,9 @@ Ref NetworkDataTask::create(NetworkSession& session, NetworkDat #if USE(CURL) return NetworkDataTaskCurl::create(session, client, parameters.request, parameters.storedCredentialsPolicy, parameters.contentSniffingPolicy, parameters.contentEncodingSniffingPolicy, parameters.shouldClearReferrerOnHTTPSToHTTPRedirect, parameters.isMainFrameNavigation); #endif +#if PLATFORM(HAIKU) + return NetworkDataTaskHaiku::create(session, client, parameters.request, parameters.storedCredentialsPolicy, parameters.contentSniffingPolicy, parameters.contentEncodingSniffingPolicy, parameters.shouldClearReferrerOnHTTPSToHTTPRedirect, parameters.isMainFrameNavigation); +#endif } NetworkDataTask::NetworkDataTask(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& requestWithCredentials, StoredCredentialsPolicy storedCredentialsPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect, bool dataTaskIsForMainFrameNavigation) diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp index dd9a1e3a8c5d..d82450f70ccc 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp +++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp @@ -420,6 +420,8 @@ void NetworkProcess::createNetworkConnectionToWebProcess(bool isServiceWorkerPro IPC::Attachment clientSocket(clientIdentifier); parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0); +#elif PLATFORM(HAIKU) + //do nothing #else notImplemented(); #endif diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h index 0e1dabd00ee4..9aa33cecd769 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.h +++ b/Source/WebKit/NetworkProcess/NetworkProcess.h @@ -386,6 +386,9 @@ class NetworkProcess : public AuxiliaryProcess, private DownloadManager::Client, // Message Handlers void didReceiveSyncNetworkProcessMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr&); void initializeNetworkProcess(NetworkProcessCreationParameters&&); +#if PLATFORM(HAIKU) + void createNetworkConnectionToWebProcessHaiku(bool isServiceWorkerProcess, WebCore::RegistrableDomain&&,int64_t webPID); +#endif void createNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::RegistrableDomain&&); void fetchWebsiteData(PAL::SessionID, OptionSet, OptionSet, uint64_t callbackID); diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in index 6d0624083f75..404cbc7c6953 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in +++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in @@ -27,6 +27,9 @@ messages -> NetworkProcess LegacyReceiver { # Creates a connection for communication with a WebProcess CreateNetworkConnectionToWebProcess(bool isServiceWorkerProcess, WebCore::RegistrableDomain registrableDomain) +#if PLATFORM(HAIKU) + CreateNetworkConnectionToWebProcessHaiku(bool isServiceWorkerProcess, WebCore::RegistrableDomain registrableDomain,int64_t webPID) +#endif #if USE(SOUP) SetIgnoreTLSErrors(bool ignoreTLSErrors) UserPreferredLanguagesChanged(Vector languages) diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp index 0d4f9a2a1aea..4fbe218a0ad0 100644 --- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp +++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp @@ -778,9 +778,12 @@ void NetworkResourceLoader::startBufferingTimerIfNeeded() { if (isSynchronous()) return; + if (m_bufferingTimer.isActive()) return; + m_bufferingTimer.startOneShot(m_parameters.maximumBufferingTime); + } void NetworkResourceLoader::bufferingTimerFired() diff --git a/Source/WebKit/NetworkProcess/NetworkSession.cpp b/Source/WebKit/NetworkProcess/NetworkSession.cpp index 1d0a8ab9ba75..532c7d264b1c 100644 --- a/Source/WebKit/NetworkProcess/NetworkSession.cpp +++ b/Source/WebKit/NetworkProcess/NetworkSession.cpp @@ -50,6 +50,10 @@ #include "NetworkSessionCurl.h" #endif +#if PLATFORM(HAIKU) +#include "NetworkSessionHaiku.h" +#endif + namespace WebKit { using namespace WebCore; @@ -64,6 +68,9 @@ Ref NetworkSession::create(NetworkProcess& networkProcess, Netwo #if USE(CURL) return NetworkSessionCurl::create(networkProcess, WTFMove(parameters)); #endif +#if PLATFORM(HAIKU) + return NetworkSessionHaiku::create(networkProcess, WTFMove(parameters)); +#endif } NetworkStorageSession& NetworkSession::networkStorageSession() const diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheDataHaiku.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCacheDataHaiku.cpp new file mode 100644 index 000000000000..dc2c046cb3a8 --- /dev/null +++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheDataHaiku.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkCacheData.h" + +#include + +namespace WebKit { +namespace NetworkCache { + +Data::Data(const uint8_t* data, size_t size) +{ + notImplemented(); +} + +Data Data::empty() +{ + notImplemented(); + return { }; +} + +const uint8_t* Data::data() const +{ + notImplemented(); + return nullptr; +} + +bool Data::isNull() const +{ + notImplemented(); + return true; +} + +bool Data::apply(const Function& applier) const +{ + notImplemented(); + return false; +} + +Data Data::subrange(size_t offset, size_t size) const +{ + return { }; +} + +Data concatenate(const Data& a, const Data& b) +{ + notImplemented(); + return { }; +} + +Data Data::adoptMap(void* map, size_t size, int fd) +{ + notImplemented(); + return { }; +} + +} // namespace NetworkCache +} // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp index be84371a8630..e99496ff627c 100644 --- a/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp +++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheFileSystem.cpp @@ -53,7 +53,7 @@ namespace WebKit { namespace NetworkCache { -#if !OS(WINDOWS) +#if !OS(WINDOWS) && !OS(HAIKU) static DirectoryEntryType directoryEntryType(uint8_t dtype) { switch (dtype) { @@ -71,7 +71,7 @@ static DirectoryEntryType directoryEntryType(uint8_t dtype) void traverseDirectory(const String& path, const Function& function) { -#if !OS(WINDOWS) +#if !OS(WINDOWS) && !OS(HAIKU) DIR* dir = opendir(FileSystem::fileSystemRepresentation(path).data()); if (!dir) return; diff --git a/Source/WebKit/NetworkProcess/cache/NetworkCacheIOChannelHaiku.cpp b/Source/WebKit/NetworkProcess/cache/NetworkCacheIOChannelHaiku.cpp new file mode 100644 index 000000000000..7b0c0e80ae4c --- /dev/null +++ b/Source/WebKit/NetworkProcess/cache/NetworkCacheIOChannelHaiku.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 Haiku Inc., + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkCacheIOChannel.h" + +#include + +namespace WebKit { +namespace NetworkCache { + +IOChannel::IOChannel(const String& filePath, Type type) + : m_path{filePath} + , m_type{type} +{ + notImplemented(); +} + +IOChannel::~IOChannel() +{ +} + +Ref IOChannel::open(const String& filePath, IOChannel::Type type) +{ + return adoptRef(*new IOChannel(filePath, type)); +} + +void IOChannel::read(size_t offset, size_t size, WorkQueue* queue, Function&& completionHandler) +{ + notImplemented(); +} + +void IOChannel::write(size_t offset, const Data& data, WorkQueue* queue, Function&& completionHandler) +{ + notImplemented(); +} + +} // namespace NetworkCache +} // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/haiku/NetworkDataTaskHaiku.cpp b/Source/WebKit/NetworkProcess/haiku/NetworkDataTaskHaiku.cpp new file mode 100644 index 000000000000..23a9a0550f8a --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/NetworkDataTaskHaiku.cpp @@ -0,0 +1,342 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkDataTaskHaiku.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "BeDC.h" +#include +static const int gMaxRecursionLimit = 10; + +namespace WebKit { + +using namespace WebCore; + +NetworkDataTaskHaiku::NetworkDataTaskHaiku(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& requestWithCredentials, + StoredCredentialsPolicy storedCredentialsPolicy, ContentSniffingPolicy shouldContentSniff, ContentEncodingSniffingPolicy, + bool shouldClearReferrerOnHTTPSToHTTPRedirect, bool dataTaskIsForMainFrameNavigation) + : NetworkDataTask(session, client, requestWithCredentials, storedCredentialsPolicy, shouldClearReferrerOnHTTPSToHTTPRedirect, dataTaskIsForMainFrameNavigation) + //, BUrlProtocolAsynchronousListener(true) + , m_postData(NULL) + , m_responseDataSent(false) + , m_redirected(false) + , m_redirectionTries(gMaxRecursionLimit) + , m_position(0) + +{ + if (m_scheduledFailureType != NoFailure) + return; + + auto request = requestWithCredentials; + if (request.url().protocolIsInHTTPFamily()) { + m_startTime = MonotonicTime::now(); + auto url = request.url(); + if (m_storedCredentialsPolicy == StoredCredentialsPolicy::Use) { + m_user = url.user(); + m_password = url.pass(); + request.removeCredentials(); + } + } + createRequest(WTFMove(request)); +} + +NetworkDataTaskHaiku::~NetworkDataTaskHaiku() +{ + cancel(); + if (m_request) + m_request->SetListener(NULL); + delete m_request; +} + +void NetworkDataTaskHaiku::createRequest(ResourceRequest&& request) +{ + m_currentRequest = WTFMove(request); + m_request = m_currentRequest.toNetworkRequest(nullptr); + + BString method = BString(m_currentRequest.httpMethod()); + + m_postData = NULL; + + if (m_request == NULL) + return; + + m_baseUrl = URL(m_request->Url()); + + BHttpRequest* httpRequest = dynamic_cast(m_request); + if(httpRequest) { + + if(method == B_HTTP_POST || method == B_HTTP_PUT) { + FormData* form = m_currentRequest.httpBody(); + if(form) { + m_postData = new BFormDataIO(form); + httpRequest->AdoptInputData(m_postData, m_postData->Size()); + } + } + + httpRequest->SetMethod(method.String()); + } + + if(this->SynchronousListener()){ + m_request->SetListener(this->SynchronousListener()); + } else { + m_request->SetListener(this); + } + + if (m_request->Run() < B_OK) + { + if (!m_client) + return; + + ResourceError error("BUrlProtocol", 42, + m_baseUrl, + "The service kit failed to start the request."); + + m_networkLoadMetrics.responseEnd = MonotonicTime::now() - m_startTime; + m_networkLoadMetrics.markComplete(); + m_client->didCompleteWithError(error,m_networkLoadMetrics); + } +} + +void NetworkDataTaskHaiku::cancel() +{ + if(m_state == State::Canceling || m_state == State::Completed) + return; + + m_state = State::Canceling; + + if(m_request) + m_request->Stop(); + +} + +void NetworkDataTaskHaiku::resume() +{ + if(m_state == State::Completed || m_state == State::Canceling) + return; + + m_state = State::Running; + + if(m_request) + m_request->Resume(); +} + +void NetworkDataTaskHaiku::invalidateAndCancel() +{ +} + +NetworkDataTask::State NetworkDataTaskHaiku::state() const +{ + return m_state; +} + +void NetworkDataTaskHaiku::ConnectionOpened(BUrlRequest*) +{ + m_responseDataSent = false; +} +void NetworkDataTaskHaiku::HeadersReceived(BUrlRequest* caller, const BUrlResult& result) +{ + if (m_currentRequest.isNull()) + return; + + const BHttpResult* httpResult = dynamic_cast(&result); + + WTF::String contentType = result.ContentType(); + int contentLength = result.Length(); + URL url; + + WTF::String encoding = extractCharsetFromMediaType(contentType); + WTF::String mimeType = extractMIMETypeFromMediaType(contentType); + + if (httpResult) { + url = URL(httpResult->Url()); + + BString location = httpResult->Headers()["Location"]; + if (location.Length() > 0) { + m_redirected = true; + url = URL(url, location); + } else { + m_redirected = false; + } + } else { + url = m_baseUrl; + } + + ResourceResponse response(url, mimeType, contentLength, encoding); + + if (httpResult) { + int statusCode = httpResult->StatusCode(); + + String suggestedFilename = filenameFromHTTPContentDisposition( + httpResult->Headers()["Content-Disposition"]); + + if (!suggestedFilename.isEmpty()) + response.setSuggestedFilename(suggestedFilename); + + response.setHTTPStatusCode(statusCode); + response.setHTTPStatusText(httpResult->StatusText()); + + // Add remaining headers. + const BHttpHeaders& resultHeaders = httpResult->Headers(); + for (int i = 0; i < resultHeaders.CountHeaders(); i++) { + BHttpHeader& headerPair = resultHeaders.HeaderAt(i); + response.setHTTPHeaderField(headerPair.Name(), headerPair.Value()); + } + + if (statusCode == 401) { + + //TODO + + //AuthenticationNeeded((BHttpRequest*)m_request, response); + // AuthenticationNeeded may have aborted the request + // so we need to make sure we can continue. + + if (m_currentRequest.isNull()) + return; + } + } + + if (!m_client) + return; + + if (m_redirected) { + m_redirectionTries--; + + if (m_redirectionTries == 0) { + ResourceError error(url.host().utf8().data(), 400, url, + "Redirection limit reached"); + + m_networkLoadMetrics.responseEnd = MonotonicTime::now() - m_startTime; + m_networkLoadMetrics.markComplete(); + m_client->didCompleteWithError(error,m_networkLoadMetrics); + return; + } + + // Notify the client that we are redirecting. + ResourceRequest request = m_currentRequest; + ResourceResponse responseCopy = response; + request.setURL(url); + m_client->willPerformHTTPRedirection(WTFMove(responseCopy),WTFMove(request), [this](const ResourceRequest& newRequest){ + + if(newRequest.isNull() || m_state == State::Canceling) + return; + + m_startTime = MonotonicTime::now();//network metrics + + if( m_state != State::Suspended ){ + m_state = State::Suspended; + resume(); + } + }); + + } else { + ResourceResponse responseCopy = response; + m_client->didReceiveResponse(WTFMove(responseCopy),[this](WebCore::PolicyAction policyAction){ + if(m_state == State::Canceling || m_state == State::Completed){ + return; + } + }); + } +} +void NetworkDataTaskHaiku::DataReceived(BUrlRequest* caller, const char* data, off_t position, + ssize_t size) +{ + if (m_currentRequest.isNull()) + return; + + if (!m_client) + return; + + // don't emit the "Document has moved here" type of HTML + if (m_redirected) + return; + + if (position != m_position) + { + debugger("bad redirect"); + return; + } + + if (size > 0) { + m_responseDataSent = true; + runOnMainThread([this,data=data,size=size]{ + m_client->didReceiveData(SharedBuffer::create(data,size)); + }); + } + + m_position += size; +} +void NetworkDataTaskHaiku::UploadProgress(BUrlRequest* caller, ssize_t bytesSent, ssize_t bytesTotal) +{ +} +void NetworkDataTaskHaiku::RequestCompleted(BUrlRequest* caller, bool success) +{ +} +bool NetworkDataTaskHaiku::CertificateVerificationFailed(BUrlRequest* caller, BCertificate& certificate, const char* message) +{ + //TODO + return true; +} +void NetworkDataTaskHaiku::DebugMessage(BUrlRequest* caller,BUrlProtocolDebugMessage type,const char* text) +{ + int8 color; + switch(type) + { + case B_URL_PROTOCOL_DEBUG_TEXT: + case B_URL_PROTOCOL_DEBUG_HEADER_IN: + case B_URL_PROTOCOL_DEBUG_TRANSFER_IN: + color = DC_GREEN; + break; + case B_URL_PROTOCOL_DEBUG_HEADER_OUT: + case B_URL_PROTOCOL_DEBUG_TRANSFER_OUT: + color = DC_BLUE; + break; + case B_URL_PROTOCOL_DEBUG_ERROR: + color = DC_RED; + } + BeDC dc("network-request",type); + dc.SendMessage((char*)text); +} +void NetworkDataTaskHaiku::runOnMainThread(Function&& task) +{ + if(isMainThread()) + task(); + else + callOnMainThreadAndWait(WTFMove(task)); +} +} diff --git a/Source/WebKit/NetworkProcess/haiku/NetworkDataTaskHaiku.h b/Source/WebKit/NetworkProcess/haiku/NetworkDataTaskHaiku.h new file mode 100644 index 000000000000..599d487fa19d --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/NetworkDataTaskHaiku.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "config.h" +#include "NetworkDataTask.h" + +#include +#include +#include +#include + +#include +#include +#include + +namespace WebKit { +using namespace WebCore; + +class NetworkDataTaskHaiku final : public NetworkDataTask + ,public BUrlProtocolAsynchronousListener +{ +public: + static Ref create(NetworkSession& session, NetworkDataTaskClient& client, const WebCore::ResourceRequest& request, WebCore::StoredCredentialsPolicy storedCredentialsPolicy, WebCore::ContentSniffingPolicy shouldContentSniff, WebCore::ContentEncodingSniffingPolicy shouldContentEncodingSniff, + bool shouldClearReferrerOnHTTPSToHTTPRedirect, bool dataTaskIsForMainFrameNavigation) + { + return adoptRef(*new NetworkDataTaskHaiku(session, client, request, storedCredentialsPolicy, shouldContentSniff, shouldContentEncodingSniff, shouldClearReferrerOnHTTPSToHTTPRedirect, dataTaskIsForMainFrameNavigation)); + } + + ~NetworkDataTaskHaiku(); +private: + NetworkDataTaskHaiku(NetworkSession&, NetworkDataTaskClient&, const WebCore::ResourceRequest&, WebCore::StoredCredentialsPolicy, WebCore::ContentSniffingPolicy, WebCore::ContentEncodingSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect, bool dataTaskIsForMainFrameNavigation); + void createRequest(WebCore::ResourceRequest&&); + State m_state{State::Suspended}; + void cancel() override; + void resume() override; + void invalidateAndCancel() override; + NetworkDataTask::State state() const override; + + void runOnMainThread(Function&&); + + void ConnectionOpened(BUrlRequest* caller) override; + void HeadersReceived(BUrlRequest* caller, const BUrlResult& result) override; + void DataReceived(BUrlRequest* caller, const char* data, off_t position, + ssize_t size) override; + void UploadProgress(BUrlRequest* caller, ssize_t bytesSent, ssize_t bytesTotal) override; + void RequestCompleted(BUrlRequest* caller, bool success) override; + bool CertificateVerificationFailed(BUrlRequest* caller, BCertificate& certificate, const char* message) override; + void DebugMessage(BUrlRequest* caller,BUrlProtocolDebugMessage type,const char* text) override; + + WebCore::ResourceResponse m_response; + WebCore::ResourceRequest m_currentRequest; + WebCore::NetworkLoadMetrics m_networkLoadMetrics; + unsigned m_redirectCount { 0 }; + unsigned m_authFailureCount { 0 }; + MonotonicTime m_startTime; + BUrlRequest* m_request; + BFormDataIO* m_postData; + URL m_baseUrl; + bool m_responseDataSent; + bool m_redirected; + off_t m_position; + + int m_redirectionTries; +}; +} diff --git a/Source/WebKit/NetworkProcess/haiku/NetworkProcessHaiku.cpp b/Source/WebKit/NetworkProcess/haiku/NetworkProcessHaiku.cpp new file mode 100644 index 000000000000..41278379e0fc --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/NetworkProcessHaiku.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkProcess.h" + +#include "NetworkProcessCreationParameters.h" +#include +#include + +#include "NetworkConnectionToWebProcess.h" +#include "NetworkProcessProxyMessages.h" +#include +#include + +namespace WebCore +{ + class NetworkStorageSession; +} + +namespace WebKit { + +using namespace WebCore; + +void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreationParameters& parameters) +{ + notImplemented(); +} + +void NetworkProcess::allowSpecificHTTPSCertificateForHost(const CertificateInfo& certificateInfo, const String& host) +{ + notImplemented(); +} + +std::unique_ptr NetworkProcess::platformCreateDefaultStorageSession() const +{ + return std::make_unique(PAL::SessionID::defaultSessionID()); +} + +void NetworkProcess::platformProcessDidTransitionToForeground() +{ + notImplemented(); +} + +void NetworkProcess::platformProcessDidTransitionToBackground() +{ + notImplemented(); +} + +void NetworkProcess::clearCacheForAllOrigins(uint32_t cachesToClear) +{ + notImplemented(); +} + +void NetworkProcess::platformProcessDidResume() +{ + notImplemented(); +} + +void NetworkProcess::platformTerminate() +{ + notImplemented(); +} + +void NetworkProcess::platformPrepareToSuspend(CompletionHandler&& completionHandler) +{ + notImplemented(); + completionHandler(); +} + +void NetworkProcess::clearDiskCache(WallTime modifiedSince, CompletionHandler&& completionHandler) +{ + notImplemented(); +} + +void NetworkProcess::createNetworkConnectionToWebProcessHaiku(bool isServiceWorkerProcess, WebCore::RegistrableDomain&& registrableDomain,int64_t webPID) +{ + team_id webID = (team_id)webPID; + uint32_t connectionRandkey = (uint32_t)find_thread(NULL); + BString key; + key.SetToFormat("%u",connectionRandkey); + + /* Network Process uses current thread id as key for workqueue identification and shares its pid and key to webprocess + So a connection can be established*/ + auto connection = NetworkConnectionToWebProcess::create(*this,{webID,key}); + m_webProcessConnections.append(WTFMove(connection)); + + IPC::Attachment clientConnector(getpid(),connectionRandkey); + parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientConnector), 0); + createNetworkConnectionToWebProcess(isServiceWorkerProcess,std::move(registrableDomain)); +} + + +} // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/haiku/NetworkProcessMainHaiku.cpp b/Source/WebKit/NetworkProcess/haiku/NetworkProcessMainHaiku.cpp new file mode 100644 index 000000000000..cdb8c985e835 --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/NetworkProcessMainHaiku.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkProcessMainUnix.h" + +#include "AuxiliaryProcessMainHaiku.h" +#include "NetworkProcess.h" +#include + +namespace WebKit { +class NetworkProcessMainBase: public AuxiliaryProcessMainBase +{ + public: + ProcessApp* app = nullptr; + bool platformInitialize(char* sign) override + { + app = new ProcessApp(sign); + return true; + } + void runApp() + { + app->Run(); + } +}; +template<> +void initializeAuxiliaryProcess(AuxiliaryProcessInitializationParameters&& parameters) +{ + static NeverDestroyed networkProcess(WTFMove(parameters)); +} + +int NetworkProcessMainUnix(int argc, char** argv) +{ + return AuxiliaryProcessMain(argc, argv); +} + +} // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/haiku/NetworkSessionHaiku.cpp b/Source/WebKit/NetworkProcess/haiku/NetworkSessionHaiku.cpp new file mode 100644 index 000000000000..0797da7fe2cb --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/NetworkSessionHaiku.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetworkSessionHaiku.h" + +#include "NetworkProcess.h" +#include "NetworkSessionCreationParameters.h" +#include "WebCookieManager.h" +#include + +namespace WebKit { + +using namespace WebCore; + +NetworkSessionHaiku::NetworkSessionHaiku(NetworkProcess& networkProcess, NetworkSessionCreationParameters&& parameters) + : NetworkSession(networkProcess, parameters.sessionID, parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle) +{ + notImplemented(); +} + +NetworkSessionHaiku::~NetworkSessionHaiku() +{ + +} + +} // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/haiku/NetworkSessionHaiku.h b/Source/WebKit/NetworkProcess/haiku/NetworkSessionHaiku.h new file mode 100644 index 000000000000..b83ad078b7b5 --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/NetworkSessionHaiku.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2018 Sony Interactive Entertainment Inc. + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "NetworkSession.h" + +namespace WebKit { + +struct NetworkSessionCreationParameters; + +class NetworkSessionHaiku final : public NetworkSession { +public: + static Ref create(NetworkProcess& networkProcess, NetworkSessionCreationParameters&& parameters) + { + return adoptRef(*new NetworkSessionHaiku(networkProcess, WTFMove(parameters))); + } + ~NetworkSessionHaiku(); + +private: + NetworkSessionHaiku(NetworkProcess&, NetworkSessionCreationParameters&&); +}; + +} // namespace WebKit diff --git a/Source/WebKit/NetworkProcess/haiku/RemoteNetworkingContextHaiku.cpp b/Source/WebKit/NetworkProcess/haiku/RemoteNetworkingContextHaiku.cpp new file mode 100644 index 000000000000..82d556271b8a --- /dev/null +++ b/Source/WebKit/NetworkProcess/haiku/RemoteNetworkingContextHaiku.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RemoteNetworkingContext.h" + +#include "NetworkProcess.h" +#include "NetworkSession.h" +#include "WebsiteDataStoreParameters.h" +#include + +namespace WebKit { + +using namespace WebCore; + +void RemoteNetworkingContext::ensureWebsiteDataStoreSession(NetworkProcess& networkProcess, WebsiteDataStoreParameters&& parameters) +{ + auto sessionID = parameters.networkSessionParameters.sessionID; + if (networkProcess.storageSession(sessionID)) + return; + + networkProcess.ensureSession(sessionID, String::number(sessionID.sessionID())); + networkProcess.setSession(sessionID, NetworkSession::create(networkProcess, WTFMove(parameters.networkSessionParameters))); +} + +} diff --git a/Source/WebKit/Platform/IPC/ArgumentCoder.h b/Source/WebKit/Platform/IPC/ArgumentCoder.h index 1bbaf101eb8f..8668a2ed0c58 100644 --- a/Source/WebKit/Platform/IPC/ArgumentCoder.h +++ b/Source/WebKit/Platform/IPC/ArgumentCoder.h @@ -34,6 +34,10 @@ class ResourceResponse; struct ViewportArguments; } +namespace WebKit { + struct PidWrapper; +}; + namespace IPC { class Decoder; @@ -84,6 +88,7 @@ class DefaultDecoderValues { }; // ResourceResponseBase has the legacy decode template, not ResourceResponse. +template<> class UsesModernDecoder : public DefaultDecoderValues { }; template<> class UsesModernDecoder : public DefaultDecoderValues { }; template<> class UsesLegacyDecoder : public DefaultDecoderValues { }; diff --git a/Source/WebKit/Platform/IPC/Attachment.cpp b/Source/WebKit/Platform/IPC/Attachment.cpp index 95ae710b139e..474b8a022962 100644 --- a/Source/WebKit/Platform/IPC/Attachment.cpp +++ b/Source/WebKit/Platform/IPC/Attachment.cpp @@ -50,7 +50,7 @@ void Attachment::release() } #endif -#if !OS(WINDOWS) +#if !OS(WINDOWS) && !PLATFORM(HAIKU) void Attachment::encode(Encoder& encoder) const { encoder.addAttachment(WTFMove(*const_cast(this))); diff --git a/Source/WebKit/Platform/IPC/Attachment.h b/Source/WebKit/Platform/IPC/Attachment.h index 7f3b413c8461..9d2a30111586 100644 --- a/Source/WebKit/Platform/IPC/Attachment.h +++ b/Source/WebKit/Platform/IPC/Attachment.h @@ -35,6 +35,10 @@ #include #endif +#if PLATFORM(HAIKU) +#include +#include +#endif namespace IPC { class Decoder; @@ -66,6 +70,12 @@ class Attachment { Attachment(HANDLE handle) : m_handle(handle) { } +#elif PLATFORM(HAIKU) + Attachment(team_id connectionInfo,uint32_t key) + : m_connectionID(connectionInfo), + m_key(key) + { + } #endif Type type() const { return m_type; } @@ -83,6 +93,9 @@ class Attachment { mach_msg_type_name_t disposition() const { return m_disposition; } #elif OS(WINDOWS) HANDLE handle() const { return m_handle; } +#elif PLATFORM(HAIKU) + team_id connectionID () const { return m_connectionID; } + uint32_t key () const { return m_key; } #endif void encode(Encoder&) const; @@ -99,6 +112,9 @@ class Attachment { mach_msg_type_name_t m_disposition; #elif OS(WINDOWS) HANDLE m_handle { INVALID_HANDLE_VALUE }; +#elif PLATFORM(HAIKU) + team_id m_connectionID; + uint32_t m_key; #endif }; diff --git a/Source/WebKit/Platform/IPC/Connection.cpp b/Source/WebKit/Platform/IPC/Connection.cpp index 361f8619d23c..f81061fba44e 100644 --- a/Source/WebKit/Platform/IPC/Connection.cpp +++ b/Source/WebKit/Platform/IPC/Connection.cpp @@ -586,12 +586,12 @@ std::unique_ptr Connection::waitForSyncReply(uint64_t syncRequestID, Se WallTime absoluteTime = WallTime::now() + timeout; willSendSyncMessage(sendSyncOptions); - + bool timedOut = false; while (!timedOut) { // First, check if we have any messages that we need to process. SyncMessageState::singleton().dispatchMessages(nullptr); - + { LockHolder locker(m_syncReplyStateMutex); @@ -622,6 +622,7 @@ std::unique_ptr Connection::waitForSyncReply(uint64_t syncRequestID, Se // This allows the WebProcess to still serve clients while waiting for the message to return. // Notably, it can continue to process accessibility requests, which are on the main thread. timedOut = !SyncMessageState::singleton().wait(absoluteTime); + } RELEASE_LOG_ERROR(IPC, "Connection::waitForSyncReply: Timed-out while waiting for reply, id = %" PRIu64, syncRequestID); diff --git a/Source/WebKit/Platform/IPC/Connection.h b/Source/WebKit/Platform/IPC/Connection.h index 3edf82adf3b5..f4c1bc2d73c8 100644 --- a/Source/WebKit/Platform/IPC/Connection.h +++ b/Source/WebKit/Platform/IPC/Connection.h @@ -55,6 +55,12 @@ #include "GSocketMonitor.h" #endif +#if PLATFORM(HAIKU) +#include +#include +#include +#endif + namespace IPC { enum class SendOption { @@ -147,6 +153,17 @@ class Connection : public ThreadSafeRefCounted createServerConnection(Identifier, Client&); @@ -432,6 +449,15 @@ class Connection : public ThreadSafeRefCounted m_pendingWriteEncoder; EventListener m_writeListener; HANDLE m_connectionPipe { INVALID_HANDLE_VALUE }; +#elif PLATFORM(HAIKU) + Identifier m_connectedProcess; + BHandler* m_readHandler; + BMessenger m_messenger; + BMessenger targetMessenger; + void runReadEventLoop(); + void runWriteEventLoop(); + Vector m_readBuffer; + std::unique_ptr m_pendingWriteEncoder; #endif }; @@ -523,12 +549,10 @@ template bool Connection::sendSync(T&& message, typename T::Reply&& // Encode the rest of the input arguments. encoder->encode(message.arguments()); - // Now send the message and wait for a reply. std::unique_ptr replyDecoder = sendSyncMessage(syncRequestID, WTFMove(encoder), timeout, sendSyncOptions); if (!replyDecoder) return false; - // Decode the reply. Optional replyArguments; *replyDecoder >> replyArguments; diff --git a/Source/WebKit/Platform/IPC/Decoder.cpp b/Source/WebKit/Platform/IPC/Decoder.cpp index 154c3d9da901..55b958c902ee 100644 --- a/Source/WebKit/Platform/IPC/Decoder.cpp +++ b/Source/WebKit/Platform/IPC/Decoder.cpp @@ -341,10 +341,10 @@ bool Decoder::decode(double& result) } bool Decoder::removeAttachment(Attachment& attachment) -{ +{fprintf(stderr,"\n%s\n",__PRETTY_FUNCTION__); if (m_attachments.isEmpty()) return false; - +fprintf(stderr,"\n%s\n",__PRETTY_FUNCTION__); attachment = m_attachments.takeLast(); return true; } diff --git a/Source/WebKit/Platform/IPC/Encoder.cpp b/Source/WebKit/Platform/IPC/Encoder.cpp index b586162eab44..8a439882dd5c 100644 --- a/Source/WebKit/Platform/IPC/Encoder.cpp +++ b/Source/WebKit/Platform/IPC/Encoder.cpp @@ -30,7 +30,7 @@ #include "MessageFlags.h" #include #include - +#include #if OS(DARWIN) #include #endif diff --git a/Source/WebKit/Platform/IPC/haiku/AttachmentHaiku.cpp b/Source/WebKit/Platform/IPC/haiku/AttachmentHaiku.cpp new file mode 100644 index 000000000000..377cc0ec545e --- /dev/null +++ b/Source/WebKit/Platform/IPC/haiku/AttachmentHaiku.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Attachment.h" + +#include "Decoder.h" +#include "Encoder.h" +#include + +namespace IPC { + +void Attachment::encode(Encoder& encoder) const +{ + //int encoding is easier + encoder << (int64_t)m_connectionID; + encoder << m_key; +} + +bool Attachment::decode(Decoder& decoder, Attachment& attachment) +{ + + int64_t sourceID; + if (!decoder.decode(sourceID)) + return false; + + uint32_t sourceKey; + if (!decoder.decode(sourceKey)) + return false; + + attachment.m_connectionID = (team_id)sourceID; + attachment.m_key = sourceKey; + return true; +} + +} // namespace IPC diff --git a/Source/WebKit/Platform/IPC/haiku/ConnectionHaiku.cpp b/Source/WebKit/Platform/IPC/haiku/ConnectionHaiku.cpp new file mode 100644 index 000000000000..65a6308b4451 --- /dev/null +++ b/Source/WebKit/Platform/IPC/haiku/ConnectionHaiku.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" +#include "Connection.h" + +#include +#include +#include +#include +namespace IPC{ + class ReadLoop: public BHandler + { + public: + ReadLoop(IPC::Connection* con) + :BHandler("Read Message Loop"), + connection(con) + { + } + void MessageReceived(BMessage* message) + { + + switch(message->what) + { + case 'ipcm': + connection->prepareIncomingMessage(message); + break; + case 'inig': + connection->finalizeConnection(message); + break; + default: + BHandler::MessageReceived(message); + + } + } + private: + IPC::Connection* connection; + + }; + void Connection::finalizeConnection(BMessage* message) + { + //unwrap the message + status_t result = message->FindMessenger("target",&targetMessenger); + if(result == B_OK) + m_isConnected = true; + + m_connectionQueue->dispatch([protectedThis = makeRef(*this)]() mutable { + protectedThis->sendOutgoingMessages(); + }); + } + void Connection::platformInitialize(Identifier identifier) + { + m_connectedProcess = identifier; + } + void Connection::platformInvalidate() + { + + } + void Connection::prepareIncomingMessage(BMessage* message) + { + size_t size; + const uint8_t* Buffer; + status_t result; + + result = message->FindData("bufferData",B_ANY_TYPE,(const void**)&Buffer,(ssize_t*)&size); + + if(result == B_OK) + { + Vector attachments(0); + auto decoder = std::make_unique(Buffer,size,nullptr,WTFMove(attachments)); + processIncomingMessage(WTFMove(decoder)); + } + else + { + //return + } + } + void Connection::runReadEventLoop() + { + status_t result; + BLooper* looper = m_connectionQueue->runLoop().runLoopLooper(); + + looper->Lock(); + looper->AddHandler(m_readHandler); + looper->SetPreferredHandler(m_readHandler); + looper->Unlock(); + /* + notify the mainloop about our workqueue + */ + BMessage init('inil'); + init.AddString("identifier",m_connectedProcess.key.String()); + init.AddPointer("looper",(const void*)looper); + BMessenger hostProcess(NULL,getpid()); + result = hostProcess.SendMessage(&init); + /* + notify the other process about our workqueue + */ + BMessenger target(looper->PreferredHandler(),looper,&result); + BMessage inig('inig'); + inig.AddString("identifier",m_connectedProcess.key.String()); + inig.AddMessenger("target",target); + BMessage reply; + m_messenger.SendMessage(&inig); + //sent to the other process + } + void Connection::runWriteEventLoop() + { + // write the pending encoding but do we need this will messaging fail + //probably when the message queue is full + } + bool Connection::open() + { + status_t result = m_messenger.SetTo(NULL,m_connectedProcess.connectedProcess); + m_readHandler = new ReadLoop(this); + m_connectionQueue->dispatch([this,protectedThis = makeRef(*this)]{ + this->runReadEventLoop(); + }); + return true; + } + bool Connection::platformCanSendOutgoingMessages() const + { + return true; + } + bool Connection::sendOutgoingMessage(std::unique_ptr encoder) + { + BMessage processMessage('ipcm'); + processMessage.AddString("identifier",m_connectedProcess.key.String()); + const uint8_t* Buffer= encoder->buffer(); + status_t result = processMessage.AddData("bufferData",B_ANY_TYPE,(void*)Buffer,encoder->bufferSize()); + // + processMessage.AddInt32("sender",getpid()); + result = targetMessenger.SendMessage(&processMessage); + + if(result == B_OK) + return true; + else + { + m_pendingWriteEncoder = WTFMove(encoder); + return false; + } + } + void Connection::willSendSyncMessage(OptionSet ) + { + + } + void Connection::didReceiveSyncReply(OptionSet ) + { + + } +} diff --git a/Source/WebKit/Platform/Module.h b/Source/WebKit/Platform/Module.h index 441cddd713e0..3b6c4ce64a65 100644 --- a/Source/WebKit/Platform/Module.h +++ b/Source/WebKit/Platform/Module.h @@ -37,6 +37,10 @@ typedef struct _GModule GModule; #endif +#if PLATFORM(HAIKU) +#include +#endif + #if OS(WINDOWS) #include #endif @@ -71,6 +75,8 @@ class Module { RetainPtr m_bundle; #elif USE(GLIB) GModule* m_handle; +#elif PLATFORM(HAIKU) + image_id m_module; #endif }; diff --git a/Source/WebKit/Platform/SharedMemory.h b/Source/WebKit/Platform/SharedMemory.h index 38e241f17e48..dd2a261de55a 100644 --- a/Source/WebKit/Platform/SharedMemory.h +++ b/Source/WebKit/Platform/SharedMemory.h @@ -39,6 +39,12 @@ #include #endif +#if PLATFORM(HAIKU) +#include +#include +#include +#endif + namespace IPC { class Decoder; class Encoder; @@ -88,6 +94,10 @@ class SharedMemory : public RefCounted { #elif OS(WINDOWS) mutable HANDLE m_handle; size_t m_size; +#elif PLATFORM(HAIKU) + mutable area_id m_areaid; + size_t m_size; + WebCore::BitmapRef* m_bitmap; #endif }; @@ -101,6 +111,9 @@ class SharedMemory : public RefCounted { #endif #if OS(WINDOWS) static RefPtr adopt(HANDLE, size_t, Protection); +#elif PLATFORM(HAIKU) + static RefPtr bitmapAllocate(WebCore::IntSize); + static RefPtr adopt(area_id, size_t , Protection); #endif ~SharedMemory(); @@ -118,6 +131,10 @@ class SharedMemory : public RefCounted { HANDLE handle() const { return m_handle; } #endif +#if PLATFORM(HAIKU) + WebCore::BitmapRef* bitmap() const { return ((m_bitmap) ? m_bitmap : NULL); } +#endif + // Return the system page size in bytes. static unsigned systemPageSize(); @@ -139,6 +156,9 @@ class SharedMemory : public RefCounted { mach_port_t m_port { MACH_PORT_NULL }; #elif OS(WINDOWS) HANDLE m_handle; +#elif PLATFORM(HAIKU) + area_id m_areaid; + WebCore::BitmapRef* m_bitmap; #endif }; diff --git a/Source/WebKit/Platform/haiku/LoggingHaiku.cpp b/Source/WebKit/Platform/haiku/LoggingHaiku.cpp new file mode 100644 index 000000000000..b78517cd47cc --- /dev/null +++ b/Source/WebKit/Platform/haiku/LoggingHaiku.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Logging.h" + +#if !LOG_DISABLED + +#include "wtf/text/WTFString.h" + +namespace WebKit { + +String logLevelString() +{ + return getenv("WEBKIT_DEBUG"); +} + +} // namespace WebKit + +#endif // !LOG_DISABLED diff --git a/Source/WebKit/Platform/haiku/ModuleHaiku.cpp b/Source/WebKit/Platform/haiku/ModuleHaiku.cpp new file mode 100644 index 000000000000..6c1b3916ff0f --- /dev/null +++ b/Source/WebKit/Platform/haiku/ModuleHaiku.cpp @@ -0,0 +1,55 @@ +/* + Copyright (C) 2014 Haiku, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Module.h" + +#include + +namespace WebKit { + +bool Module::load() +{ + m_module = load_add_on(m_path.utf8().data()); + if (!m_module) { + return false; + } + + return true; +} + +void Module::unload() +{ + unload_add_on(m_module); + m_module = 0; +} + +void* Module::platformFunctionPointer(const char* functionName) const +{ + if (m_module) { + void* pointer = NULL; + get_image_symbol(m_module, functionName, B_SYMBOL_TYPE_ANY, &pointer); + return pointer; + } + + return 0; +} + +} + diff --git a/Source/WebKit/Platform/haiku/SharedMemoryHaiku.cpp b/Source/WebKit/Platform/haiku/SharedMemoryHaiku.cpp new file mode 100644 index 000000000000..40a390724dfa --- /dev/null +++ b/Source/WebKit/Platform/haiku/SharedMemoryHaiku.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SharedMemory.h" + +#include "Decoder.h" +#include "Encoder.h" + +#include +#include +#include +#include + +using namespace WebCore; +namespace WebKit { + +SharedMemory::Handle::Handle() +:m_areaid(0), +m_size(0), +m_bitmap(NULL) +{ +} + +SharedMemory::Handle::~Handle() +{ + clear(); +} + +SharedMemory::Handle::Handle(Handle&& other) = default; +SharedMemory::Handle& SharedMemory::Handle::operator=(Handle&& other) = default; +void SharedMemory::Handle::clear() +{ + if(!m_areaid) + return; + + m_areaid = 0; +} + +bool SharedMemory::Handle::isNull() const +{ + return !m_areaid; +} + +void SharedMemory::Handle::encode(IPC::Encoder& encoder) const +{ + encoder << (uint64_t)m_size; + encoder << (int64_t)m_areaid; +} + +bool SharedMemory::Handle::decode(IPC::Decoder& decoder, Handle& handle) +{ + uint64_t size; + if(!decoder.decode(size)) + return false; + + int64_t areaid; + if(!decoder.decode(areaid)) + return false; + + handle.m_areaid = (area_id)areaid; + handle.m_size = size; + + return true; +} + +static uint32 protectionMode(SharedMemory::Protection protection) +{ + switch(protection) + { + case SharedMemory::Protection::ReadOnly: + return B_READ_AREA; + case SharedMemory::Protection::ReadWrite: + return B_READ_AREA | B_WRITE_AREA; + } +} + +RefPtr SharedMemory::allocate(size_t size) +{ + void* baseAddress; + + area_id sharedArea = create_area("WebKit-shared-memory",&baseAddress,B_ANY_ADDRESS, + size,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA); + + if(sharedArea<0) + return nullptr; + + RefPtr memory = adoptRef(new SharedMemory); + memory->m_size = size; + memory->m_data = baseAddress; + memory->m_areaid = sharedArea; + memory->m_bitmap = NULL; + + return memory; +} + +RefPtr SharedMemory::bitmapAllocate(WebCore::IntSize bounds) +{ + BitmapRef* sharedBitmap = new BitmapRef(BRect(0,0,bounds.width()-1,bounds.height()-1),B_RGBA32,true); + + if(!sharedBitmap->IsValid()) + return nullptr; + + RefPtr memory = adoptRef(new SharedMemory); + memory->m_size = sharedBitmap->BitsLength(); + memory->m_data = sharedBitmap->Bits(); + memory->m_areaid = sharedBitmap->Area(); + memory->m_bitmap = sharedBitmap; + + return memory; +} + +RefPtr SharedMemory::map(const Handle& handle, Protection protection) +{ + RefPtr memory = adopt(handle.m_areaid, handle.m_size, protection); + if(!memory) + return nullptr; + + handle.m_areaid = 0; + return memory; +} + +RefPtr SharedMemory::adopt(area_id area, size_t size, Protection protection) +{ + if(!area) + return nullptr; + + void* baseAddress; + + area_id clonedArea = clone_area("WebKit-cloned-memory",&baseAddress,B_ANY_ADDRESS, + protectionMode(protection),area); + + if(clonedArea<0) + return nullptr; + + RefPtr memory = adoptRef(new SharedMemory); + memory->m_size = size; + memory->m_data = baseAddress; + memory->m_areaid = clonedArea; + memory->m_bitmap = NULL; + + return memory; +} + +SharedMemory::~SharedMemory() +{ + if(!m_areaid) + return; + //unset + delete_area(m_areaid); + m_areaid = 0; +} + +bool SharedMemory::createHandle(Handle& handle, Protection) +{ + ASSERT_ARG(handle,handle.isNull()); + ASSERT(m_areaid); + + handle.m_areaid = m_areaid; + handle.m_size = m_size; + + if(handle.m_bitmap) + handle.m_bitmap = m_bitmap; + + return true; +} + +unsigned SharedMemory::systemPageSize() +{ + return B_PAGE_SIZE; +} + +} // namespace WebKit + + diff --git a/Source/WebKit/PlatformHaiku.cmake b/Source/WebKit/PlatformHaiku.cmake new file mode 100644 index 000000000000..9ca974878861 --- /dev/null +++ b/Source/WebKit/PlatformHaiku.cmake @@ -0,0 +1,163 @@ +list(APPEND WebKit_SOURCES + NetworkProcess/cache/NetworkCacheDataHaiku.cpp + NetworkProcess/cache/NetworkCacheIOChannelHaiku.cpp + NetworkProcess/haiku/NetworkProcessHaiku.cpp + NetworkProcess/haiku/NetworkProcessMainHaiku.cpp + NetworkProcess/haiku/RemoteNetworkingContextHaiku.cpp + NetworkProcess/haiku/NetworkSessionHaiku.cpp + NetworkProcess/haiku/NetworkDataTaskHaiku.cpp + + Platform/IPC/haiku/AttachmentHaiku.cpp + Platform/IPC/haiku/ConnectionHaiku.cpp + Platform/haiku/LoggingHaiku.cpp + Platform/haiku/ModuleHaiku.cpp + Platform/haiku/SharedMemoryHaiku.cpp + + PluginProcess/unix/PluginControllerProxyUnix.cpp + PluginProcess/unix/PluginProcessMainUnix.cpp + PluginProcess/unix/PluginProcessUnix.cpp + + Shared/WebCoreArgumentCoders.cpp + Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp + Shared/CoordinatedGraphics/SimpleViewportController.cpp + Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp + Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp + Shared/CoordinatedGraphics/threadedcompositor/ThreadedDisplayRefreshMonitor.cpp + Shared/haiku/ProcessExecutablePathHaiku.cpp + Shared/haiku/ShareableBitmapHaiku.cpp + Shared/haiku/WebCoreArgumentCodersHaiku.cpp + Shared/haiku/WebMemorySamplerHaiku.cpp + Shared/haiku/AuxiliaryProcessMainHaiku.cpp + + UIProcess/API/C/haiku/WKView.cpp + UIProcess/API/haiku/APIWebsiteDataStoreHaiku.cpp + + UIProcess/DefaultUndoController.cpp + UIProcess/BackingStore.cpp + + UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp + + UIProcess/Launcher/haiku/ProcessLauncherHaiku.cpp + UIProcess/LegacySessionStateCodingNone.cpp + UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp + UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp + UIProcess/WebsiteData/haiku/WebsiteDataStoreHaiku.cpp + UIProcess/haiku/BackingStoreHaiku.cpp + UIProcess/haiku/TextCheckerHaiku.cpp + UIProcess/haiku/WebInspectorProxyHaiku.cpp + UIProcess/haiku/WebPageProxyHaiku.cpp + UIProcess/haiku/WebPreferencesHaiku.cpp + UIProcess/haiku/WebProcessPoolHaiku.cpp + UIProcess/API/haiku/WebViewBase.cpp + UIProcess/API/haiku/WebView.cpp + UIProcess/API/haiku/PageClientImplHaiku.cpp + + WebProcess/Cookies/haiku/WebCookieManagerHaiku.cpp + WebProcess/InjectedBundle/haiku/InjectedBundleHaiku.cpp + WebProcess/InjectedBundle/haiku/InjectedBundleHaiku.cpp + WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp + WebProcess/WebCoreSupport/haiku/WebContextMenuClientHaiku.cpp + WebProcess/WebCoreSupport/haiku/WebEditorClientHaiku.cpp + WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.cpp + WebProcess/WebCoreSupport/haiku/WebPopupMenuHaiku.cpp + + WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp + WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp + WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp + + WebProcess/WebPage/haiku/WebInspectorHaiku.cpp + WebProcess/WebPage/haiku/WebPageHaiku.cpp + WebProcess/WebPage/AcceleratedSurface.cpp + + WebProcess/haiku/WebProcessHaiku.cpp + WebProcess/haiku/WebProcessMainHaiku.cpp +) + +list(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBKIT_DIR}/NetworkProcess/unix" + "${WEBKIT_DIR}/Platform" + "${WEBKIT_DIR}/Platform/IPC/unix" + "${WEBKIT_DIR}/Shared/API/c/haiku" + "${WEBKIT_DIR}/Shared/CoordinatedGraphics" + "${WEBKIT_DIR}/Shared/CoordinatedGraphics/threadedcompositor" + "${WEBKIT_DIR}/Shared/unix" + "${WEBKIT_DIR}/Shared/haiku" + "${WEBKIT_DIR}/UIProcess/API/C/CoordinatedGraphics" + "${WEBKIT_DIR}/UIProcess/API/C/haiku" + "${WEBKIT_DIR}/UIProcess/API/haiku" + "${WEBKIT_DIR}/UIProcess/haiku" + "${WEBKIT_DIR}/UIProcess/CoordinatedGraphics" + "${WEBKIT_DIR}/WebProcess/unix" + "${WEBKIT_DIR}/WebProcess/WebCoreSupport/haiku" + "${WEBKIT_DIR}/WebProcess/WebPage/CoordinatedGraphics" + "${WEBKIT_DIR}/NetworkProcess/haiku" + ${LIBXML2_INCLUDE_DIR} + ${LIBXSLT_INCLUDE_DIRS} + ${SQLITE_INCLUDE_DIRS} + ${WTF_DIR} + "${DERIVED_SOURCES_WEBCORE_DIR}" + "${FORWARDING_HEADERS}" +) + +list(APPEND WebKit_LIBRARIES + ${CMAKE_DL_LIBS} + ${FONTCONFIG_LIBRARIES} + ${FREETYPE2_LIBRARIES} + ${JPEG_LIBRARIES} + ${LIBXML2_LIBRARIES} + ${OPENGL_LIBRARIES} + ${PNG_LIBRARIES} + ${SQLITE_LIBRARIES} +) + +list(APPEND WebProcess_SOURCES + WebProcess/EntryPoint/unix/WebProcessMain.cpp +) + +list(APPEND NetworkProcess_SOURCES + NetworkProcess/EntryPoint/unix/NetworkProcessMain.cpp +) + +list(APPEND WebProcess_LIBRARIES + ${LIBXML2_LIBRARIES} + ${LIBXSLT_LIBRARIES} + ${OPENGL_LIBRARIES} + ${SQLITE_LIBRARIES} +) + +add_custom_target(forwarding-headerHaiku + COMMAND ${PERL_EXECUTABLE} ${WEBKIT_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT_DIR} ${DERIVED_SOURCES_WEBKIT_DIR}/include haiku + COMMAND ${PERL_EXECUTABLE} ${WEBKIT_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT_DIR} ${DERIVED_SOURCES_WEBKIT_DIR}/include CoordinatedGraphics +) + +set(WEBKIT_EXTRA_DEPENDENCIES + forwarding-headerHaiku +) + +add_definitions( + -DLIBEXECDIR=\"${EXEC_INSTALL_DIR}\" + -DWEBPROCESSNAME=\"WebProcess\" + -DPLUGINPROCESSNAME=\"PluginProcess\" + -DNETWORKPROCESSNAME=\"NetworkProcess\" +) + +set(WebKit_FORWARDING_HEADERS_DIRECTORIES + Shared/API/c + Shared/API/c/haiku + UIProcess/API/C + Platform/IPC/unix + WebProcess/InjectedBundle/API/c +) +set(WebKit_FORWARDING_HEADERS_FILES + WebProcess/WebPage/EventDispatcher.h + + Platform/Logging.h + #Platform/classifier/ResourceLoadStatisticsClassifier.h + Platform/IPC/unix/UnixMessage.h + + UIProcess/VisitedLinkStore.h +) + +WEBKIT_CREATE_FORWARDING_HEADERS(WebKit FILES ${WebKit_FORWARDING_HEADERS_FILES} DIRECTORIES +${WebKit_FORWARDING_HEADERS_DIRECTORIES}) + diff --git a/Source/WebKit/Shared/API/c/WKBase.h b/Source/WebKit/Shared/API/c/WKBase.h index 1164c1582c41..bc059e2be7b1 100644 --- a/Source/WebKit/Shared/API/c/WKBase.h +++ b/Source/WebKit/Shared/API/c/WKBase.h @@ -34,6 +34,8 @@ #include #elif defined(BUILDING_WPE__) #include +#elif defined(BUILDING_HAIKU__) +#include #elif defined(__APPLE__) #include #elif defined(_WIN32) diff --git a/Source/WebKit/Shared/API/c/haiku/WKBaseHaiku.h b/Source/WebKit/Shared/API/c/haiku/WKBaseHaiku.h new file mode 100644 index 000000000000..9c07f8e0c8c8 --- /dev/null +++ b/Source/WebKit/Shared/API/c/haiku/WKBaseHaiku.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WKBaseEfl_h +#define WKBaseEfl_h + +#ifndef WKBase_h +#error "Please #include \"WKBase.h\" instead of this file directly." +#endif + +typedef const struct OpaqueWKView* WKViewRef; +typedef const struct OpaqueWKPopupItem* WKPopupItemRef; +typedef const struct OpaqueWKPopupMenuListener* WKPopupMenuListenerRef; +typedef const struct OpaqueWKTouchPoint* WKTouchPointRef; +typedef const struct OpaqueWKTouchEvent* WKTouchEventRef; + +#endif /* WKBaseEfl_h */ diff --git a/Source/WebKit/Shared/NativeWebKeyboardEvent.h b/Source/WebKit/Shared/NativeWebKeyboardEvent.h index c0a64e362961..5eca4746cc2f 100644 --- a/Source/WebKit/Shared/NativeWebKeyboardEvent.h +++ b/Source/WebKit/Shared/NativeWebKeyboardEvent.h @@ -47,6 +47,10 @@ struct KeypressCommand; typedef union _GdkEvent GdkEvent; #endif +#if PLATFORM(HAIKU) +#include +#endif + #if PLATFORM(IOS_FAMILY) #include OBJC_CLASS WebEvent; @@ -85,6 +89,8 @@ class NativeWebKeyboardEvent : public WebKeyboardEvent { GdkEvent* nativeEvent() const { return m_nativeEvent.get(); } const WebCore::CompositionResults& compositionResults() const { return m_compositionResults; } bool isFakeEventForComposition() const { return m_fakeEventForComposition; } +#elif PLATFORM(HAIKU) + const BMessage* nativeEvent() const { return m_nativeEvent; } #elif PLATFORM(IOS_FAMILY) ::WebEvent* nativeEvent() const { return m_nativeEvent.get(); } #elif PLATFORM(WIN) @@ -100,6 +106,8 @@ class NativeWebKeyboardEvent : public WebKeyboardEvent { GUniquePtr m_nativeEvent; WebCore::CompositionResults m_compositionResults; bool m_fakeEventForComposition; +#elif PLATFORM(HAIKU) + BMessage* m_nativeEvent; #elif PLATFORM(IOS_FAMILY) RetainPtr<::WebEvent> m_nativeEvent; #elif PLATFORM(WIN) diff --git a/Source/WebKit/Shared/NativeWebMouseEvent.h b/Source/WebKit/Shared/NativeWebMouseEvent.h index bbddd94826e4..9da509afff99 100644 --- a/Source/WebKit/Shared/NativeWebMouseEvent.h +++ b/Source/WebKit/Shared/NativeWebMouseEvent.h @@ -51,7 +51,6 @@ struct wpe_input_pointer_event; #include #endif - namespace WebKit { class NativeWebMouseEvent : public WebMouseEvent { @@ -67,6 +66,8 @@ class NativeWebMouseEvent : public WebMouseEvent { NativeWebMouseEvent(struct wpe_input_pointer_event*, float deviceScaleFactor); #elif PLATFORM(WIN) NativeWebMouseEvent(HWND, UINT message, WPARAM, LPARAM, bool); +#elif PLATFORM(HAIKU) + NativeWebMouseEvent(BMessage*); #endif #if USE(APPKIT) @@ -77,6 +78,8 @@ class NativeWebMouseEvent : public WebMouseEvent { ::WebEvent* nativeEvent() const { return m_nativeEvent.get(); } #elif PLATFORM(WIN) const MSG* nativeEvent() const { return &m_nativeEvent; } +#elif PLATFORM(HAIKU) + const BMessage* nativeEvent() const { return m_nativeEvent; } #else const void* nativeEvent() const { return nullptr; } #endif @@ -90,6 +93,8 @@ class NativeWebMouseEvent : public WebMouseEvent { RetainPtr<::WebEvent> m_nativeEvent; #elif PLATFORM(WIN) MSG m_nativeEvent; +#elif PLATFORM(HAIKU) + BMessage* m_nativeEvent; #endif }; diff --git a/Source/WebKit/Shared/NativeWebWheelEvent.h b/Source/WebKit/Shared/NativeWebWheelEvent.h index 148d709009c3..0cf45a8c6ca6 100644 --- a/Source/WebKit/Shared/NativeWebWheelEvent.h +++ b/Source/WebKit/Shared/NativeWebWheelEvent.h @@ -33,6 +33,10 @@ OBJC_CLASS NSView; #endif +#if PLATFORM(HAIKU) +#include +#endif + #if PLATFORM(GTK) #include typedef union _GdkEvent GdkEvent; @@ -66,8 +70,8 @@ class NativeWebWheelEvent : public WebWheelEvent { NSEvent* nativeEvent() const { return m_nativeEvent.get(); } #elif PLATFORM(GTK) GdkEvent* nativeEvent() const { return m_nativeEvent.get(); } -#elif PLATFORM(WIN) - const MSG* nativeEvent() const { return &m_nativeEvent; } +#elif PLATFORM(HAIKU) + const BMessage* nativeEvent() const { return m_nativeEvent; } #else const void* nativeEvent() const { return nullptr; } #endif @@ -77,8 +81,8 @@ class NativeWebWheelEvent : public WebWheelEvent { RetainPtr m_nativeEvent; #elif PLATFORM(GTK) GUniquePtr m_nativeEvent; -#elif PLATFORM(WIN) - MSG m_nativeEvent; +#elif PLATFORM(HAIKU) + const BMessage* m_nativeEvent; #endif }; diff --git a/Source/WebKit/Shared/ShareableBitmap.cpp b/Source/WebKit/Shared/ShareableBitmap.cpp index 8fc5ad6c1b29..c060e3a270ab 100644 --- a/Source/WebKit/Shared/ShareableBitmap.cpp +++ b/Source/WebKit/Shared/ShareableBitmap.cpp @@ -100,7 +100,11 @@ RefPtr ShareableBitmap::createShareable(const IntSize& size, Co if (numBytes.hasOverflowed()) return nullptr; +#if PLATFORM(HAIKU) + RefPtr sharedMemory = SharedMemory::bitmapAllocate(size); +#else RefPtr sharedMemory = SharedMemory::allocate(numBytes.unsafeGet()); +#endif if (!sharedMemory) return nullptr; diff --git a/Source/WebKit/Shared/ShareableBitmap.h b/Source/WebKit/Shared/ShareableBitmap.h index a4a3e5b81120..d9e0f16ebb57 100644 --- a/Source/WebKit/Shared/ShareableBitmap.h +++ b/Source/WebKit/Shared/ShareableBitmap.h @@ -40,6 +40,11 @@ #include #endif +#if PLATFORM(HAIKU) +#include +#include +#endif + namespace WebCore { class Image; class GraphicsContext; @@ -125,6 +130,10 @@ class ShareableBitmap : public RefCounted { // This creates a BitmapImage that directly references the shared bitmap data. // This is only safe to use when we know that the contents of the shareable bitmap won't change. RefPtr createCairoSurface(); +#elif PLATFORM(HAIKU) + // This creates a BitmapImage that directly references the shared bitmap data. + // This is only safe to use when we know that the contents of the shareable bitmap won't change. + RefPtr createBitmapSurface(); #endif private: @@ -145,6 +154,9 @@ class ShareableBitmap : public RefCounted { static void releaseSurfaceData(void* typelessBitmap); #endif +#if PLATFORM(HAIKU) + WebCore::BitmapRef* bitmapObject() const; +#endif void* data() const; size_t sizeInBytes() const { return numBytesForSize(m_size, m_configuration).unsafeGet(); } diff --git a/Source/WebKit/Shared/haiku/AuxiliaryProcessMainHaiku.cpp b/Source/WebKit/Shared/haiku/AuxiliaryProcessMainHaiku.cpp new file mode 100644 index 000000000000..533e5e69dc5c --- /dev/null +++ b/Source/WebKit/Shared/haiku/AuxiliaryProcessMainHaiku.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AuxiliaryProcessMain.h" + +#include +#include + +namespace WebKit { + +bool AuxiliaryProcessMainBase::parseCommandLine(int argc, char** argv) +{ + ASSERT(argc >= 3); + if (argc < 3) + return false; + m_parameters.processIdentifier = makeObjectIdentifier(atoll(argv[2])); + m_parameters.connectionIdentifier.connectedProcess = atoi(argv[3]); + m_parameters.connectionIdentifier.key = argv[2]; + + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit/Shared/haiku/AuxiliaryProcessMainHaiku.h b/Source/WebKit/Shared/haiku/AuxiliaryProcessMainHaiku.h new file mode 100644 index 000000000000..eb4733d0455c --- /dev/null +++ b/Source/WebKit/Shared/haiku/AuxiliaryProcessMainHaiku.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "AuxiliaryProcess.h" +#include "WebKit2Initialize.h" +#include +#include "ProcessInitHaiku.h" + +#include +#include +#include + +using namespace std; + +namespace WebKit { + +class AuxiliaryProcessMainBase { +public: + virtual bool platformInitialize(char* sig) { return true; } + virtual bool parseCommandLine(int argc, char** argv); + virtual void platformFinalize() { } + + AuxiliaryProcessInitializationParameters&& takeInitializationParameters() { return WTFMove(m_parameters); } + +protected: + AuxiliaryProcessInitializationParameters m_parameters; +}; + +class ProcessApp : public BApplication +{ + public: + + ProcessApp(char* signature):BApplication(signature) + { + } + void MessageReceived(BMessage* message) + { + switch(message->what) + { + default: + BApplication::MessageReceived(message); + + } + } + void ReadyToRun() + { + RunLoop::run(); + BHandler* handle = new ProcessInitHaiku(); + BLooper* looper = BLooper::LooperForThread(find_thread(NULL)); + looper->AddHandler(handle); + looper->SetNextHandler(handle); + } +}; + +template +void initializeAuxiliaryProcess(AuxiliaryProcessInitializationParameters&& parameters) +{ + AuxiliaryProcessType::singleton().initialize(WTFMove(parameters)); +} + +template +int AuxiliaryProcessMain(int argc, char** argv) +{ + AuxiliaryProcessMainType auxiliaryMain; + + if (!auxiliaryMain.platformInitialize(argv[1])) + return EXIT_FAILURE; + + InitializeWebKit2(); + + if (!auxiliaryMain.parseCommandLine(argc, argv)) + return EXIT_FAILURE; + + initializeAuxiliaryProcess(auxiliaryMain.takeInitializationParameters()); + + auxiliaryMain.runApp(); + + auxiliaryMain.platformFinalize(); + + return EXIT_SUCCESS; +} + +} // namespace WebKit diff --git a/Source/WebKit/Shared/haiku/NativeWebMouseEventHaiku.cpp b/Source/WebKit/Shared/haiku/NativeWebMouseEventHaiku.cpp new file mode 100644 index 000000000000..f315eac20078 --- /dev/null +++ b/Source/WebKit/Shared/haiku/NativeWebMouseEventHaiku.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Haiku Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebEventFactory.h" +#include "NativeWebMouseEvent.h" + +namespace WebKit +{ + NativeWebMouseEvent::NativeWebMouseEvent(BMessage* mouseEvent) + :WebMouseEvent(WebEventFactory::createWebMouseEvent(mouseEvent)), + m_nativeEvent(mouseEvent) + { + } +} diff --git a/Source/WebKit/Shared/haiku/ProcessExecutablePathHaiku.cpp b/Source/WebKit/Shared/haiku/ProcessExecutablePathHaiku.cpp new file mode 100644 index 000000000000..f24bd0f2b20a --- /dev/null +++ b/Source/WebKit/Shared/haiku/ProcessExecutablePathHaiku.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Copyright (C) 2014,2019 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ProcessExecutablePath.h" + +#include +#include +#include + +namespace WebKit { +using namespace std; + +String executablePathOfWebProcess() +{ + static NeverDestroyed WebKitWebProcessName("./bin/WebProcess"); + return WebKitWebProcessName; +} + +String executablePathOfPluginProcess() +{ + static NeverDestroyed WebKitPluginProcessName("./bin/PluginProcess"); + return WebKitPluginProcessName; +} + +String executablePathOfNetworkProcess() +{ + static NeverDestroyed WebKitNetworkProcessName("./bin/NetworkProcess"); + return WebKitNetworkProcessName; +} + +} // namespace WebKit + diff --git a/Source/WebKit/Shared/haiku/ProcessInitHaiku.h b/Source/WebKit/Shared/haiku/ProcessInitHaiku.h new file mode 100644 index 000000000000..64182afea5aa --- /dev/null +++ b/Source/WebKit/Shared/haiku/ProcessInitHaiku.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2019 Haiku Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +using namespace std; +namespace WebKit{ +class ProcessInitHaiku: public BHandler +{ + public: + ProcessInitHaiku() + :BHandler("process-init") + { + } + void MessageReceived(BMessage* message) + { + switch(message->what) + { + case 'inil': + LocalMessage(message); + break; + case 'inig': + GlobalMessage(message); + break; + default: + BHandler::MessageReceived(message); + } + } + + private: + void LocalMessage(BMessage* message) + { + const char* idTempStr; + BLooper* looperTemp; + message->FindString("identifier",&idTempStr); + message->FindPointer("looper",(void**)&looperTemp); + string id(idTempStr); + message = Looper()->DetachCurrentMessage(); + if(messengerMapping[id]) + { + /* + We have recieved the other process's BMessenger data just send it to our workqueue + */ + looperTemp->PostMessage(messengerMapping[id],looperTemp->PreferredHandler()); + } + else + { + /* + Messenger is not yet known save it for later use + */ + looperMapping[id] = looperTemp; + } + + } + void GlobalMessage(BMessage* message) + { + const char* idTempStr; + message->FindString("identifier",&idTempStr); + string id(idTempStr); + message = Looper()->DetachCurrentMessage(); + if(looperMapping[id]) + { + /* + We know about the looper so send the message directly then + */ + BLooper* temp = looperMapping[id]; + temp->PostMessage(message,temp->PreferredHandler()); + } + else + { + /* + We dont know about the looper yet so put in the mapping of messengers + */ + messengerMapping[id] = message; + } + } + map looperMapping; + map messengerMapping; + +}; +} diff --git a/Source/WebKit/Shared/haiku/ShareableBitmapHaiku.cpp b/Source/WebKit/Shared/haiku/ShareableBitmapHaiku.cpp new file mode 100644 index 000000000000..f9e6a13b5378 --- /dev/null +++ b/Source/WebKit/Shared/haiku/ShareableBitmapHaiku.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ShareableBitmap.h" + +#include +#include +#include +#include + +#include +#include + +using namespace WebCore; + +namespace WebKit { + +static inline RefPtr createSurfaceFromBitmap(BitmapRef* bitmap) +{ + RefPtr image = StillImage::create(bitmap); + return image; +} + +BitmapRef* ShareableBitmap::bitmapObject() const +{ + if(isBackedBySharedMemory()) + return m_sharedMemory->bitmap(); + + return NULL; +} + +std::unique_ptr ShareableBitmap::createGraphicsContext() +{ + RefPtr image = createBitmapSurface(); + + BView* surface = new BView(image->nativeImageForCurrentFrame(nullptr)->Bounds(), + "Shareable", 0, 0); + image->nativeImageForCurrentFrame(nullptr)->AddChild(surface); + surface->LockLooper(); + + return std::make_unique(surface); +} + +void ShareableBitmap::paint(GraphicsContext& context, const IntPoint& dstPoint, const IntRect& srcRect) +{ + BBitmap bitmap(BRect(B_ORIGIN,m_size),B_RGBA32,true); + status_t result = bitmap.ImportBits(data(),m_size.width()*m_size.height()*4, 4*m_size.width(),0,B_RGBA32); + + BView* viewSurface = context.platformContext(); + + viewSurface->LockLooper(); + viewSurface->DrawBitmap(&bitmap); + viewSurface->Sync(); + viewSurface->UnlockLooper(); +} + +void ShareableBitmap::paint(GraphicsContext& context, float scaleFactor, const IntPoint& dstPoint, const IntRect& srcRect) +{ + FloatRect destRect(dstPoint, srcRect.size()); + FloatRect srcRectScaled(srcRect); + srcRectScaled.scale(scaleFactor); + notImplemented(); +} + +RefPtr ShareableBitmap::createBitmapSurface() +{ + RefPtr image = createSurfaceFromBitmap(bitmapObject()); + + ref(); // Balanced by deref in releaseSurfaceData. + return image; +} + +RefPtr ShareableBitmap::createImage() +{ + RefPtr surface = createBitmapSurface(); + if (!surface) + return 0; + + return BitmapImage::create(surface->nativeImageForCurrentFrame(nullptr)); +} + +Checked ShareableBitmap::calculateBytesPerRow(WebCore::IntSize size, const ShareableBitmap::Configuration& config) +{ + unsigned bytes = calculateBytesPerPixel(config)*size.width(); + + return bytes; +} + +unsigned ShareableBitmap::calculateBytesPerPixel(const Configuration&) +{ + return 4; +} +} diff --git a/Source/WebKit/Shared/haiku/WebCoreArgumentCodersHaiku.cpp b/Source/WebKit/Shared/haiku/WebCoreArgumentCodersHaiku.cpp new file mode 100644 index 000000000000..65b0b91d58ea --- /dev/null +++ b/Source/WebKit/Shared/haiku/WebCoreArgumentCodersHaiku.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2014,2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DataReference.h" +#include "WebCoreArgumentCoders.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace WebCore; + +namespace IPC { + +void ArgumentCoder::encodePlatformData(Encoder& encoder, const ResourceRequest& resourceRequest) +{ + resourceRequest.encodePlatformData(encoder); +} + +bool ArgumentCoder::decodePlatformData(Decoder& decoder, ResourceRequest& resourceRequest) +{ + return resourceRequest.decodePlatformData(decoder); +} + +void ArgumentCoder::encode(Encoder& encoder, const CertificateInfo& certificateInfo) +{ + //nothing to encode ceriticateinfo is null +} + +bool ArgumentCoder::decode(Decoder& decoder, CertificateInfo& certificateInfo) +{ + //nothing to decode just return true + return true; +} + +void ArgumentCoder::encodePlatformData(Encoder& encoder, const ResourceError& resourceError) +{ + encoder << resourceError.domain(); + encoder << resourceError.errorCode(); + encoder << resourceError.failingURL().string(); + encoder << resourceError.localizedDescription(); +} + +bool ArgumentCoder::decodePlatformData(Decoder& decoder, ResourceError& resourceError) +{ + String domain; + if (!decoder.decode(domain)) + return false; + + int errorCode; + if (!decoder.decode(errorCode)) + return false; + + String failingURL; + if (!decoder.decode(failingURL)) + return false; + + String localizedDescription; + if (!decoder.decode(localizedDescription)) + return false; + + resourceError = ResourceError(domain, errorCode, URL(URL(), failingURL), localizedDescription); + return true; +} + +void ArgumentCoder::encodePlatformData(Encoder&, const ProtectionSpace&) +{ + ASSERT_NOT_REACHED(); +} + +bool ArgumentCoder::decodePlatformData(Decoder&, ProtectionSpace&) +{ + ASSERT_NOT_REACHED(); + return false; +} + +void ArgumentCoder::encodePlatformData(Encoder&, const Credential&) +{ + ASSERT_NOT_REACHED(); +} + +bool ArgumentCoder::decodePlatformData(Decoder&, Credential&) +{ + ASSERT_NOT_REACHED(); + return false; +} + +Optional ArgumentCoder::decodePlatformData(Decoder&, FontAttributes&) +{ + ASSERT_NOT_REACHED(); + return WTF::nullopt; +} + +bool ArgumentCoder::decodePlatformData(Decoder&, DictionaryPopupInfo&) +{ + ASSERT_NOT_REACHED(); + return false; +} + +} + + diff --git a/Source/WebKit/Shared/haiku/WebEventFactory.cpp b/Source/WebKit/Shared/haiku/WebEventFactory.cpp new file mode 100644 index 000000000000..ca9b550509bd --- /dev/null +++ b/Source/WebKit/Shared/haiku/WebEventFactory.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 Haiku Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WebEventFactory.h" +#include + +enum { + BUTTON_PRESS = 'btps', + BUTTON_RELEASE = 'btrl', + MOUSE_MOVEMENT = 'mmmv', +} +namespace WebKit +{ + static inline int clickCount(WebEvent::Type type, WebMouseEvent::Button button, const POINT& position, int64_t timeStampSeconds) + { + static int gLastClickCount; + static int64_t gLastClickTime; + static POINT lastClickPosition; + static WebMouseEvent::Button lastClickButton = WebMouseEvent::LeftButton; + + bool cancelPreviousClick = 0; + + if (type == WebEvent::MouseDown) { + if (!cancelPreviousClick && (button == lastClickButton)) + ++gLastClickCount; + else { + gLastClickCount = 1; + lastClickPosition = position; + } + gLastClickTime = timeStampSeconds; + lastClickButton = button; + } else if (type == WebEvent::MouseMove) { + if (cancelPreviousClick) { + gLastClickCount = 0; + lastClickPosition.x = 0; + lastClickPosition.y = 0; + gLastClickTime = 0; + } + } + + return gLastClickCount; + } + static inline WebMouseEvent::Button buttonForEvent(const BMessage* message) + { + int32_t buttonType; + unsigned button = 0; + message->FindInt32("button",&buttonType); + switch(buttonType) + { + case B_PRIMARY_MOUSE_BUTTON: + button = WebMouseEvent::LeftButton; + break; + case B_SECONDARY_MOUSE_BUTTON: + button = WebMouseEvent::RightButton; + break; + case B_TERTIARY_MOUSE_BUTTON: + button = WebMouseEvent::MiddleButton; + break; + } + + return static_cast(button); + } + static WebMouseEvent createWebMouseEvent(const BMessage* message) + { + WebEvent::Type type = static_cast(0); + int32_t mouseEventType; + message->FindInt32("type",&mouseEventType); + switch(mouseEventType) + { + case BUTTON_PRESS: + type = WebEvent::MouseDown; + break; + case BUTTON_RELEASE: + type = WebEvent::MouseUp; + break; + case MOUSE_MOVEMENT: + type = WebEvent::MouseMove; + break; + default: + ASSERT_NOT_REACHED(); + } + + BPoint where; + message->FindPoint("where",&where); + + int64_t when; + message->FindInt64("when",&when); + + /*return WebMouseEvent( + type,buttonForEvent(message),0,IntPoint(where),IntPoint(where), + 0,0,0, + )*/ + //it says some deltax delta y should it be added from be_deltax? + + } + +} diff --git a/Source/WebKit/Shared/haiku/WebEventFactory.h b/Source/WebKit/Shared/haiku/WebEventFactory.h new file mode 100644 index 000000000000..0957e0a41323 --- /dev/null +++ b/Source/WebKit/Shared/haiku/WebEventFactory.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2019 Haiku Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebEventFactory_h +#define WebEventFactory_h + +#include "WebEvent.h" + +class BMessage; + +namespace WebKit { + +class WebEventFactory { +public: + static WebMouseEvent createWebMouseEvent(const BMessage*); + static WebWheelEvent createWebWheelEvent(const BMessage*); + static WebKeyboardEvent createWebKeyboardEvent(const BMessage*); + +}; + +} // namespace WebKit + +#endif // WebEventFactory_h diff --git a/Source/WebKit/Shared/haiku/WebMemorySamplerHaiku.cpp b/Source/WebKit/Shared/haiku/WebMemorySamplerHaiku.cpp new file mode 100644 index 000000000000..f64528dfa2a6 --- /dev/null +++ b/Source/WebKit/Shared/haiku/WebMemorySamplerHaiku.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2014,2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebMemorySampler.h" + +#if ENABLE(MEMORY_SAMPLER) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace WebCore; +using namespace JSC; +using namespace WTF; + +namespace WebKit { + +struct ApplicationMemoryStats { + size_t totalProgramSize; + size_t residentSetSize; + size_t sharedSize; + size_t textSize; + size_t librarySize; + size_t dataStackSize; + size_t dirtyPageSize; +}; + +static inline void appendKeyValuePair(WebMemoryStatistics& stats, const String& key, size_t value) +{ + stats.keys.append(key); + stats.values.append(value); +} + +static ApplicationMemoryStats sampleMemoryAllocatedForApplication() +{ + ApplicationMemoryStats applicationStats = {0, 0, 0, 0, 0, 0, 0}; + + ssize_t cookie; + area_info area; + + while (get_next_area_info(B_CURRENT_TEAM, &cookie, &area) == B_OK) + { + applicationStats.totalProgramSize += area.size; + // TODO fill the other infos... + } + + return applicationStats; +} + +String WebMemorySampler::processName() const +{ + team_info info; + if (get_team_info(B_CURRENT_TEAM, &info) == B_OK) + return String(info.args); + return String(); +} + +WebMemoryStatistics WebMemorySampler::sampleWebKit() const +{ + WebMemoryStatistics webKitMemoryStats; + + WallTime now = WallTime::now(); + + appendKeyValuePair(webKitMemoryStats, "Timestamp"_s, now.secondsSinceEpoch().seconds()); + + ApplicationMemoryStats applicationStats = sampleMemoryAllocatedForApplication(); + + appendKeyValuePair(webKitMemoryStats, "Total Program Size"_s, applicationStats.totalProgramSize); + appendKeyValuePair(webKitMemoryStats, "RSS"_s, applicationStats.residentSetSize); + appendKeyValuePair(webKitMemoryStats, "Shared"_s, applicationStats.sharedSize); + appendKeyValuePair(webKitMemoryStats, "Text"_s, applicationStats.textSize); + appendKeyValuePair(webKitMemoryStats, "Library"_s, applicationStats.librarySize); + appendKeyValuePair(webKitMemoryStats, "Data/Stack"_s, applicationStats.dataStackSize); + appendKeyValuePair(webKitMemoryStats, "Dirty"_s, applicationStats.dirtyPageSize); + + size_t totalBytesInUse = 0; + size_t totalBytesCommitted = 0; + +#if ENABLE(GLOBAL_FASTMALLOC_NEW) + FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); + size_t fastMallocBytesInUse = fastMallocStatistics.committedVMBytes - fastMallocStatistics.freeListBytes; + size_t fastMallocBytesCommitted = fastMallocStatistics.committedVMBytes; + totalBytesInUse += fastMallocBytesInUse; + totalBytesCommitted += fastMallocBytesCommitted; + + appendKeyValuePair(webKitMemoryStats, "Fast Malloc In Use"_s, fastMallocBytesInUse); + appendKeyValuePair(webKitMemoryStats, "Fast Malloc Committed Memory"_s, fastMallocBytesCommitted); +#endif + + size_t jscHeapBytesInUse = commonVM().heap.size(); + size_t jscHeapBytesCommitted = commonVM().heap.capacity(); + totalBytesInUse += jscHeapBytesInUse; + totalBytesCommitted += jscHeapBytesCommitted; + + GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics(); + totalBytesInUse += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes; + totalBytesCommitted += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes; + + appendKeyValuePair(webKitMemoryStats, "JavaScript Heap In Use"_s, jscHeapBytesInUse); + appendKeyValuePair(webKitMemoryStats, "JavaScript Heap Commited Memory"_s, jscHeapBytesCommitted); + + appendKeyValuePair(webKitMemoryStats, "JavaScript Stack Bytes"_s, globalMemoryStats.stackBytes); + appendKeyValuePair(webKitMemoryStats, "JavaScript JIT Bytes"_s, globalMemoryStats.JITBytes); + + appendKeyValuePair(webKitMemoryStats, "Total Memory In Use"_s, totalBytesInUse); + appendKeyValuePair(webKitMemoryStats, "Total Committed Memory"_s, totalBytesCommitted); + + system_info systemInfo; + if (!get_system_info(&systemInfo)) { + appendKeyValuePair(webKitMemoryStats, "System Total Bytes"_s, systemInfo.max_pages * B_PAGE_SIZE); + appendKeyValuePair(webKitMemoryStats, "Available Bytes"_s, systemInfo.free_memory); + //appendKeyValuePair(webKitMemoryStats, "Shared Bytes"_s, systemInfo.sharedram); + appendKeyValuePair(webKitMemoryStats, "Buffer Bytes"_s, systemInfo.block_cache_pages * B_PAGE_SIZE); + appendKeyValuePair(webKitMemoryStats, "Total Swap Bytes"_s, systemInfo.max_swap_pages * B_PAGE_SIZE); + appendKeyValuePair(webKitMemoryStats, "Available Swap Bytes"_s, systemInfo.free_swap_pages * B_PAGE_SIZE); + } + + return webKitMemoryStats; +} + +void WebMemorySampler::sendMemoryPressureEvent() +{ + notImplemented(); +} + +} +#endif diff --git a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp index dbcbcda09e49..410f12983fab 100644 --- a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp +++ b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.cpp @@ -36,9 +36,9 @@ bool AuxiliaryProcessMainBase::parseCommandLine(int argc, char** argv) ASSERT(argc >= 3); if (argc < 3) return false; - - m_parameters.processIdentifier = makeObjectIdentifier(atoll(argv[1])); + m_parameters.processIdentifier = makeObjectIdentifier(atoll(argv[1])); m_parameters.connectionIdentifier = atoi(argv[2]); + return true; } diff --git a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.h b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.h index 908684654d2b..d88c6d00774e 100644 --- a/Source/WebKit/Shared/unix/AuxiliaryProcessMain.h +++ b/Source/WebKit/Shared/unix/AuxiliaryProcessMain.h @@ -56,16 +56,18 @@ int AuxiliaryProcessMain(int argc, char** argv) if (!auxiliaryMain.platformInitialize()) return EXIT_FAILURE; - + InitializeWebKit2(); if (!auxiliaryMain.parseCommandLine(argc, argv)) return EXIT_FAILURE; initializeAuxiliaryProcess(auxiliaryMain.takeInitializationParameters()); + RunLoop::run(); - auxiliaryMain.platformFinalize(); + auxiliaryMain.platformFinalize(); + return EXIT_SUCCESS; } diff --git a/Source/WebKit/UIProcess/API/C/WKAPICast.h b/Source/WebKit/UIProcess/API/C/WKAPICast.h index a30d59793b6b..d6c6aa0bb1c8 100644 --- a/Source/WebKit/UIProcess/API/C/WKAPICast.h +++ b/Source/WebKit/UIProcess/API/C/WKAPICast.h @@ -535,6 +535,10 @@ inline WKWebGLLoadPolicy toAPI(WebCore::WebGLLoadPolicy webGLLoadPolicy) #include "WKAPICastGtk.h" #endif +#if defined(BUILDING_HAIKU__) +#include "WKAPICastHaiku.h" +#endif + #if defined(BUILDING_WPE__) #include "WKAPICastWPE.h" #endif diff --git a/Source/WebKit/UIProcess/API/C/WKContextPrivate.h b/Source/WebKit/UIProcess/API/C/WKContextPrivate.h index f9c7d3296e5c..9401ced20105 100644 --- a/Source/WebKit/UIProcess/API/C/WKContextPrivate.h +++ b/Source/WebKit/UIProcess/API/C/WKContextPrivate.h @@ -31,6 +31,9 @@ #if defined(WIN32) || defined(_WIN32) typedef int WKProcessID; +#elif PLATFORM(HAIKU) +#include +typedef WTF::ProcessID WKProcessID; #else #include typedef pid_t WKProcessID; diff --git a/Source/WebKit/UIProcess/API/C/WKPagePrivate.h b/Source/WebKit/UIProcess/API/C/WKPagePrivate.h index 3d959ff889dc..bec9586c4b3a 100644 --- a/Source/WebKit/UIProcess/API/C/WKPagePrivate.h +++ b/Source/WebKit/UIProcess/API/C/WKPagePrivate.h @@ -31,6 +31,9 @@ #if defined(WIN32) || defined(_WIN32) typedef int WKProcessID; +#elif PLATFORM(HAIKU) +#include +typedef WTF::ProcessID WKProcessID; #else #include typedef pid_t WKProcessID; diff --git a/Source/WebKit/UIProcess/API/C/haiku/WKAPICastHaiku.h b/Source/WebKit/UIProcess/API/C/haiku/WKAPICastHaiku.h new file mode 100644 index 000000000000..242738a287d4 --- /dev/null +++ b/Source/WebKit/UIProcess/API/C/haiku/WKAPICastHaiku.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2014 Haiku, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WKAPICastHaiku_h +#define WKAPICastHaiku_h + +#ifndef WKAPICast_h +#error "Please #include \"WKAPICast.h\" instead of this file directly." +#endif + +namespace WebKit { + +class WebViewBase; + +WK_ADD_API_MAPPING(WKViewRef, WebViewBase) + +} + +#endif diff --git a/Source/WebKit/UIProcess/API/C/haiku/WKView.cpp b/Source/WebKit/UIProcess/API/C/haiku/WKView.cpp new file mode 100644 index 000000000000..8badb6e0e073 --- /dev/null +++ b/Source/WebKit/UIProcess/API/C/haiku/WKView.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WKView.h" + +#include "APIPageConfiguration.h" +#include "WKAPICast.h" +#include "WebViewBase.h" + + +using namespace WebCore; +using namespace WebKit; + + +WKViewRef WKViewCreate(const char* name,BRect rect,BWindow* parentWindow, + WKPageConfigurationRef pageRef) +{ + return toAPI(WebViewBase::create(name,rect,parentWindow,*toImpl(pageRef)).leakRef()); +} + + +WKPageRef WKViewGetPage(WKViewRef viewRef) +{ + return toAPI(toImpl(viewRef)->page()); +} diff --git a/Source/WebKit/UIProcess/API/C/haiku/WKView.h b/Source/WebKit/UIProcess/API/C/haiku/WKView.h new file mode 100644 index 000000000000..52fbe64d1b90 --- /dev/null +++ b/Source/WebKit/UIProcess/API/C/haiku/WKView.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKView_h +#define WKView_h + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKViewRef WKViewCreate(const char*,BRect,BWindow*,WKPageConfigurationRef pageRef); +WK_EXPORT WKPageRef WKViewGetPage(WKViewRef view); +#ifdef __cplusplus +} +#endif + +#endif /* WKView_h */ + diff --git a/Source/WebKit/UIProcess/API/haiku/APIWebsiteDataStoreHaiku.cpp b/Source/WebKit/UIProcess/API/haiku/APIWebsiteDataStoreHaiku.cpp new file mode 100644 index 000000000000..f252178d455e --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/APIWebsiteDataStoreHaiku.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIWebsiteDataStore.h" + +#include + +#include + +namespace API { + +String WebsiteDataStore::defaultApplicationCacheDirectory() +{ + notImplemented(); + return String(); +} + +String WebsiteDataStore::defaultCacheStorageDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultNetworkCacheDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultIndexedDBDatabaseDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultServiceWorkerRegistrationDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultLocalStorageDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultMediaKeysStorageDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultWebSQLDatabaseDirectory() +{ + return String(); +} + +String WebsiteDataStore::defaultResourceLoadStatisticsDirectory() +{ + return String(); +} + +String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String& directoryName) +{ + return String(); +} + +String WebsiteDataStore::websiteDataDirectoryFileSystemRepresentation(const String& directoryName) +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultApplicationCacheDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultNetworkCacheDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultWebSQLDatabaseDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultIndexedDBDatabaseDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultLocalStorageDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultMediaCacheDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultMediaKeysStorageDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory() +{ + return String(); +} + +String WebsiteDataStore::legacyDefaultJavaScriptConfigurationDirectory() +{ + return String(); +} + +} // namespace API diff --git a/Source/WebKit/UIProcess/API/haiku/PageClientImplHaiku.cpp b/Source/WebKit/UIProcess/API/haiku/PageClientImplHaiku.cpp new file mode 100644 index 000000000000..637d8be7b668 --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/PageClientImplHaiku.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" + +#include "PageClientImplHaiku.h" + +#include "DrawingAreaProxyCoordinatedGraphics.h" +#include "WebProcessProxy.h" +#include "WebViewBase.h" + +namespace WebKit +{ + using namespace WebCore; + + PageClientImpl::PageClientImpl(WebViewBase& view) + :fWebView(view) + { + } + std::unique_ptr PageClientImpl::createDrawingAreaProxy( + WebProcessProxy& process) + { + return std::make_unique(*fWebView.page(),process); + } + void PageClientImpl::setViewNeedsDisplay(const WebCore::Region& region) + { + + //fWebView.setViewNeedsDisplay(region); + } + + void PageClientImpl::requestScroll(const WebCore::FloatPoint&, const WebCore::IntPoint&) + { + notImplemented(); + } + + WebCore::FloatPoint PageClientImpl::viewScrollPosition() + { + notImplemented(); + return { }; + } + + WebCore::IntSize PageClientImpl::viewSize() + { + WebCore::IntSize stuff; + if (fWebView.page()->drawingArea()) + { + return fWebView.page()->drawingArea()->size(); + } + + return IntSize(); + } + + bool PageClientImpl::isViewWindowActive() + { + //return fWebView.isWindowActive(); + return false; + } + + bool PageClientImpl::isViewFocused() + { + //return fWebView.isFocused(); + return false; + } + + bool PageClientImpl::isViewVisible() + { + //return fWebView.isVisible(); + return false; + } + + bool PageClientImpl::isViewInWindow() + { + //return fWebView.isInWindow(); + return false; + } + + void PageClientImpl::PageClientImpl::processDidExit() + { + notImplemented(); + } + + void PageClientImpl::didRelaunchProcess() + { + notImplemented(); + } + + void PageClientImpl::toolTipChanged(const String&, const String& newToolTip) + { + //fWebView.setToolTip(newToolTip); + } + + void PageClientImpl::setCursor(const WebCore::Cursor& cursor) + { + //fWebView.setCursor(cursor); + } + + void PageClientImpl::setCursorHiddenUntilMouseMoves(bool /* hiddenUntilMouseMoves */) + { + notImplemented(); + } + + void PageClientImpl::didChangeViewportProperties(const WebCore::ViewportAttributes&) + { + notImplemented(); + } + + void PageClientImpl::registerEditCommand(Ref&& command, UndoOrRedo undoOrRedo) + { + fUndoController.registerEditCommand(WTFMove(command), undoOrRedo); + } + + void PageClientImpl::clearAllEditCommands() + { + fUndoController.clearAllEditCommands(); + } + + bool PageClientImpl::canUndoRedo(UndoOrRedo undoOrRedo) + { + return fUndoController.canUndoRedo(undoOrRedo); + } + + void PageClientImpl::executeUndoRedo(UndoOrRedo undoOrRedo) + { + fUndoController.executeUndoRedo(undoOrRedo); + } + + FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& viewRect) + { + notImplemented(); + return viewRect; + } + + FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect) + { + notImplemented(); + return viewRect; + } + + IntPoint PageClientImpl::screenToRootView(const IntPoint& point) + { + return IntPoint(); + } + + IntRect PageClientImpl::rootViewToScreen(const IntRect& rect) + { + return IntRect(); + } + + void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled) + { + notImplemented(); + } + + RefPtr PageClientImpl::createPopupMenuProxy(WebPageProxy& page) + { + fprintf(stderr,"context menu"); + notImplemented(); + //return WebPopupMenuProxyWin::create(&fWebView, page); + } + + #if ENABLE(CONTEXT_MENUS) + Ref PageClientImpl::createContextMenuProxy(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData) + { + notImplemented(); + //return WebContextMenuProxyWin::create(page, WTFMove(context), userData); + } + #endif + + //#if ENABLE(INPUT_TYPE_COLOR) + RefPtr PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color& intialColor, + const WebCore::IntRect&, Vector&&) + { + return nullptr; + } + //#endif + + void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) + { + fprintf(stderr,"\n %s \n",__PRETTY_FUNCTION__); + notImplemented(); + } + + void PageClientImpl::exitAcceleratedCompositingMode() + { + notImplemented(); + } + + void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) + { + notImplemented(); + } + + void PageClientImpl::pageClosed() + { + notImplemented(); + } + + void PageClientImpl::preferencesDidChange() + { + notImplemented(); + } + + void PageClientImpl::didChangeContentSize(const IntSize& size) + { + notImplemented(); + } + + void PageClientImpl::handleDownloadRequest(DownloadProxy& download) + { + notImplemented(); + } + + void PageClientImpl::didCommitLoadForMainFrame(const String& /* mimeType */, bool /* useCustomContentProvider */ ) + { + notImplemented(); + } + void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event) + { + notImplemented(); + } + + void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String&, const IPC::DataReference&) + { + notImplemented(); + } + + void PageClientImpl::navigationGestureDidBegin() + { + notImplemented(); + } + + void PageClientImpl::navigationGestureWillEnd(bool, WebBackForwardListItem&) + { + notImplemented(); + } + + void PageClientImpl::navigationGestureDidEnd(bool, WebBackForwardListItem&) + { + notImplemented(); + } + + void PageClientImpl::navigationGestureDidEnd() + { + notImplemented(); + } + + void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem&) + { + notImplemented(); + } + + void PageClientImpl::didRemoveNavigationGestureSnapshot() + { + notImplemented(); + } + + void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame() + { + notImplemented(); + } + + void PageClientImpl::didFinishLoadForMainFrame() + { + notImplemented(); + } + + void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) + { + notImplemented(); + } + + void PageClientImpl::didChangeBackgroundColor() + { + notImplemented(); + } + + void PageClientImpl::isPlayingAudioWillChange() + { + notImplemented(); + } + + void PageClientImpl::isPlayingAudioDidChange() + { + notImplemented(); + } + + void PageClientImpl::refView() + { + notImplemented(); + } + + void PageClientImpl::derefView() + { + notImplemented(); + } + + WebViewBase* PageClientImpl::viewWidget() + { + return &fWebView; + } + +} + diff --git a/Source/WebKit/UIProcess/API/haiku/PageClientImplHaiku.h b/Source/WebKit/UIProcess/API/haiku/PageClientImplHaiku.h new file mode 100644 index 000000000000..cf8b505542ee --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/PageClientImplHaiku.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once + +#include "PageClient.h" +#include "WebPageProxy.h" +#include "DefaultUndoController.h" +#include +#include + +namespace WebKit +{ + class WebViewBase; + class DrawingAreaProxy; + class PageClientImpl: public PageClient + { + public: + PageClientImpl(WebViewBase&); + WebViewBase* viewWidget(); + private: + //page client def's + std::unique_ptr createDrawingAreaProxy(WebProcessProxy&) override; + void setViewNeedsDisplay(const WebCore::Region&) override; + void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin) override; + WebCore::FloatPoint viewScrollPosition() override; + WebCore::IntSize viewSize() override; + bool isViewWindowActive() override; + bool isViewFocused() override; + bool isViewVisible() override; + bool isViewInWindow() override; + void processDidExit() override; + void didRelaunchProcess() override; + void pageClosed() override; + void preferencesDidChange() override; + void toolTipChanged(const WTF::String&, const WTF::String&) override; + void setCursor(const WebCore::Cursor&) override; + void setCursorHiddenUntilMouseMoves(bool) override; + void didChangeViewportProperties(const WebCore::ViewportAttributes&) override; + void registerEditCommand(Ref&&, UndoOrRedo) override; + void clearAllEditCommands() override; + bool canUndoRedo(UndoOrRedo) override; + void executeUndoRedo(UndoOrRedo) override; + WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) override; + WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override; + WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) override; + WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override; + void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override; + RefPtr createPopupMenuProxy(WebPageProxy&) override; + Ref createContextMenuProxy(WebPageProxy&, ContextMenuContextData&&, const UserData&) override; + + #if ENABLE(INPUT_TYPE_COLOR) + RefPtr createColorPicker(WebPageProxy*, const WebCore::Color& intialColor, + const WebCore::IntRect&,Vector&&) override; + #endif + + void enterAcceleratedCompositingMode(const LayerTreeContext&) override; + void exitAcceleratedCompositingMode() override; + void updateAcceleratedCompositingMode(const LayerTreeContext&) override; + + void handleDownloadRequest(DownloadProxy&) override; + void didChangeContentSize(const WebCore::IntSize&) override; + void didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider) override; + void didFailLoadForMainFrame() override { } + + + void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&) override; + void navigationGestureDidBegin() override; + void navigationGestureWillEnd(bool, WebBackForwardListItem&) override; + void navigationGestureDidEnd(bool, WebBackForwardListItem&) override; + void navigationGestureDidEnd() override; + void willRecordNavigationSnapshot(WebBackForwardListItem&) override; + void didRemoveNavigationGestureSnapshot() override; + + void didFirstVisuallyNonEmptyLayoutForMainFrame() override; + void didFinishLoadForMainFrame() override; + void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override; + + void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override; + + void didChangeBackgroundColor() override; + void isPlayingAudioWillChange() override; + void isPlayingAudioDidChange() override; + + void refView() override; + void derefView() override; + + void didRestoreScrollPosition() override { } + + WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override { return WebCore::UserInterfaceLayoutDirection::LTR; } + + void didFinishProcessingAllPendingMouseEvents() final { } + + WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint& point) final { return point; } + WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect& rect) final { return rect; } + void requestDOMPasteAccess(const WebCore::IntRect& elementRect, const String& originIdentifier, CompletionHandler&&) final {} + + private: + DefaultUndoController fUndoController; + + //haiku def + WebViewBase& fWebView; + }; + + +} diff --git a/Source/WebKit/UIProcess/API/haiku/PageLoadStateObserver.h b/Source/WebKit/UIProcess/API/haiku/PageLoadStateObserver.h new file mode 100644 index 000000000000..3e0d0ecc3c19 --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/PageLoadStateObserver.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES{} LOSS OF USE, DATA, OR PROFITS{} OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" +#include "PageLoadState.h" +#include "WebViewConstants.h" + + +#include +#include + +namespace WebKit{ +class PageLoadStateObserver final :public PageLoadState::Observer +{ + public: + PageLoadStateObserver(BLooper* looper) + :m_looper(looper) + { + } + void willChangeIsLoading() override{} + void didChangeIsLoading() override{} + + void willChangeTitle() override + { + } + void didChangeTitle() override + { + BMessage message(DID_CHANGE_TITLE); + m_looper->PostMessage(&message); + } + + void willChangeActiveURL() override{} + void didChangeActiveURL() override{} + + void willChangeHasOnlySecureContent() override{} + void didChangeHasOnlySecureContent() override{} + + void willChangeEstimatedProgress() override + { + } + void didChangeEstimatedProgress() override + { + BMessage message(DID_CHANGE_PROGRESS); + m_looper->PostMessage(&message); + } + + void willChangeCanGoBack() override{} + void didChangeCanGoBack() override{} + + void willChangeCanGoForward() override{} + void didChangeCanGoForward() override{} + + void willChangeNetworkRequestsInProgress() override{} + void didChangeNetworkRequestsInProgress() override{} + + void willChangeCertificateInfo() override{} + void didChangeCertificateInfo() override{} + + void willChangeWebProcessIsResponsive() override{} + void didChangeWebProcessIsResponsive() override{} + + void didSwapWebProcesses() override{} + private: + BLooper* m_looper; +}; +} + + diff --git a/Source/WebKit/UIProcess/API/haiku/WebView.cpp b/Source/WebKit/UIProcess/API/haiku/WebView.cpp new file mode 100644 index 000000000000..f05167b61443 --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/WebView.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + + +#include "WKPageConfigurationRef.h" +#include "WKPage.h" +#include "WKView.h" +#include "WKURL.h" +#include "WKString.h" +#include "WKContext.h" +#include "WKPreferencesRef.h" +#include "WKPageNavigationClient.h" +#include "WKPageLoaderClient.h" + +#include "wtf/RunLoop.h" + +#include "WebView.h" +#include "WebViewConstants.h" +#include "ProcessInitHaiku.h" + +BWebView::BWebView(BRect frame,BWindow* myWindow) +:fAppLooper(NULL) +{ + auto config = adoptWK(WKPageConfigurationCreate()); + auto prefs = WKPreferencesCreate(); + + + WKPreferencesSetDeveloperExtrasEnabled(prefs, true); + WKPageConfigurationSetPreferences(config.get(),prefs); + + fContext = adoptWK(WKContextCreateWithConfiguration(nullptr)); + WKPageConfigurationSetContext(config.get(),fContext.get()); + + + fViewPort = adoptWK(WKViewCreate("Webkit",frame,myWindow,config.get())); + fAppLooper = myWindow->Looper(); +} + +void BWebView::navigationCallbacks() +{ + auto page = WKViewGetPage( fViewPort.get()); + WKPageNavigationClientV0 navigationClient={}; + + navigationClient.base.version = 0; + navigationClient.base.clientInfo = this; + + navigationClient.didCommitNavigation = didCommitNavigation; + navigationClient.didFinishDocumentLoad = didFinishDocumentLoad; + navigationClient.didFailNavigation = didFailNavigation; + navigationClient.didFinishNavigation = didFinishNavigation; + navigationClient.didReceiveServerRedirectForProvisionalNavigation = didReceiveServerRedirectForProvisionalNavigation; + WKPageSetPageNavigationClient(page,&navigationClient.base); + + fObserver = new PageLoadStateObserver(fAppLooper); + getRenderView()->page()->pageLoadState().addObserver(*fObserver); + +} +void BWebView::initializeOnce() +{ + WTF::RunLoop::initializeMainRunLoop(); + WTF::RunLoop::run(); + BHandler* handle = new ProcessInitHaiku(); + BLooper* looper = BLooper::LooperForThread(find_thread(NULL)); + looper->AddHandler(handle); + looper->SetNextHandler(handle); +} +void BWebView::loadHTML() +{ + auto page = WKViewGetPage( fViewPort.get()); + WKRetainPtr uri; + uri = adoptWK(WKURLCreateWithUTF8CString("about:blank")); + WKRetainPtr str; + str = adoptWK(WKStringCreateWithUTF8CString("Hello world")); + WKPageLoadHTMLString(page,str.get(),uri.get()); + +} + +void BWebView::loadURIRequest(const char* uri) +{ + BMessage message(URL_LOAD_HANDLE); + message.AddString("url",uri); + be_app->PostMessage(&message); +} + +void BWebView::paintContent() +{ + getRenderView()->LockLooper(); + getRenderView()->Invalidate(); + getRenderView()->UnlockLooper(); +} + +void BWebView::loadURI(BMessage* message) +{ + const char* uri; + message->FindString("url",&uri); + auto page = WKViewGetPage( fViewPort.get()); + WKRetainPtr wuri; + wuri = adoptWK(WKURLCreateWithUTF8CString(uri)); + WKPageLoadURL(page,wuri.get()); +} +void BWebView::goForward() +{ + auto page = WKViewGetPage(fViewPort.get()); + WKPageGoForward(page); + BMessage message(URL_CHANGE); + message.AddString("url",BString(getCurrentURL())); + fAppLooper->PostMessage(&message); +} +void BWebView::goBackward() +{ + auto page = WKViewGetPage(fViewPort.get()); + WKPageGoBack(page); + BMessage message(URL_CHANGE); + message.AddString("url",BString(getCurrentURL())); + fAppLooper->PostMessage(&message); +} +void BWebView::stop() +{ + auto page = WKViewGetPage(fViewPort.get()); + WKPageClose(page); +} +void BWebView::didCommitNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo) +{ + BLooper* looper = ((BWebView*)clientInfo)->getAppLooper(); + BMessage message(DID_COMMIT_NAVIGATION); + looper->PostMessage(&message); +} +void BWebView::didReceiveServerRedirectForProvisionalNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo) +{ + BLooper* looper = ((BWebView*)clientInfo)->getAppLooper(); + BMessage message(URL_CHANGE); + message.AddString("url",BString(((BWebView*)clientInfo)->getCurrentURL())); + looper->PostMessage(&message); +} +void BWebView::didFinishDocumentLoad(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo) +{ +} +void BWebView::didFinishNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData,const void* clientInfo) +{ + BLooper* looper = ((BWebView*)clientInfo)->getAppLooper(); + BMessage message(DID_FINISH_NAVIGATION); + looper->PostMessage(&message); +} + +void BWebView::didFailNavigation(WKPageRef page, WKNavigationRef navigation,WKErrorRef, WKTypeRef userData,const void* clientInfo) +{ +} + +void BWebView::didFinishProgress(WKPageRef page,const void* clientInfo) +{ +} + +double BWebView::didChangeProgress() +{ + auto page = WKViewGetPage(fViewPort.get()); + return WKPageGetEstimatedProgress(page); +} +const char* BWebView::title() +{ + return getRenderView()->page()->pageLoadState().title().utf8().data(); +} diff --git a/Source/WebKit/UIProcess/API/haiku/WebView.h b/Source/WebKit/UIProcess/API/haiku/WebView.h new file mode 100644 index 000000000000..bee3ced1f349 --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/WebView.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" +#include "WKPage.h" +#include "WKView.h" +#include "WKContext.h" +#include "WKRetainPtr.h" +#include "WKAPICast.h" +#include "WebViewBase.h" +#include "PageLoadStateObserver.h" + +using namespace WebKit; + +class BWebView +{ + public: + BWebView(BRect,BWindow*); + void initializeOnce(); + void loadHTML(); + void loadURIRequest(const char*);//use this in app to load a url + void loadURI(BMessage*); + void goForward(); + void goBackward(); + void stop(); + void paintContent(); + WebViewBase* getRenderView() { return toImpl(fViewPort.get()); } + const char* getCurrentURL() { return getRenderView()->currentURL(); } + BLooper* getAppLooper() { return fAppLooper; } + + void navigationCallbacks(); + double didChangeProgress(); + const char* title(); + + private: + WKRetainPtr fViewPort; + WKRetainPtr fContext; + static void didCommitNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + static void didReceiveServerRedirectForProvisionalNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + static void didFinishDocumentLoad(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + static void didFinishProgress(WKPageRef,const void*); + static void didFinishNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData,const void* clientInfo); + static void didFailNavigation(WKPageRef page, WKNavigationRef navigation, WKErrorRef,WKTypeRef userData,const void* clientInfo); + PageLoadStateObserver* fObserver; + BLooper* fAppLooper; +}; + diff --git a/Source/WebKit/UIProcess/API/haiku/WebViewBase.cpp b/Source/WebKit/UIProcess/API/haiku/WebViewBase.cpp new file mode 100644 index 000000000000..e3ab5490f711 --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/WebViewBase.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "WebViewBase.h" +#include "APIPageConfiguration.h" +#include "DrawingAreaProxyCoordinatedGraphics.h" +#include "WebProcessPool.h" +#include "WebPageGroup.h" +#include + +using namespace WebKit; +using namespace WebCore; + +WebKit::WebViewBase::WebViewBase(const char*name,BRect rect,BWindow* parentWindow, +const API::PageConfiguration& pageConfig) +:BView(name, B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE), + fPageClient(std::make_unique(*this)) +{ + auto config = pageConfig.copy(); + auto* preferences = config->preferences(); + + if(!preferences && config->pageGroup()) + { + preferences = &config->pageGroup()->preferences(); + config->setPreferences(preferences); + } + if(preferences) + { + preferences->setAcceleratedCompositingEnabled(false); + } + + WebProcessPool* processPool = config->processPool(); + fPage = processPool->createWebPage(*fPageClient,WTFMove(config)); + fPage->initializeWebPage(); + + if(fPage->drawingArea()) + { + setSize = true; + fPage->drawingArea()->setSize(IntSize(rect.right - rect.left, + rect.bottom - rect.top)); + } +} + +void WebViewBase::paint(const IntRect& dirtyRect) +{ + +} +void WebViewBase::FrameResized(float newWidth, float newHeight) +{ + auto drawingArea = static_cast(page()->drawingArea()); + if(!drawingArea) + return; + drawingArea->setSize(IntSize(newWidth, + newHeight)); +} +void WebViewBase::Draw(BRect update) +{ + auto drawingArea = static_cast(page()->drawingArea()); + if(!drawingArea) + return; + if(!setSize) + { + setSize = true; + BRect rect = Frame(); + drawingArea->setSize(IntSize(rect.right - rect.left, + rect.bottom - rect.top)); + } + IntRect updateArea(update); + WebCore::Region unpainted; + drawingArea->paint(this,updateArea,unpainted); + +} +void WebViewBase::MouseMoved(BPoint where,uint32 code,const BMessage* dragMessage) +{ +} + diff --git a/Source/WebKit/UIProcess/API/haiku/WebViewBase.h b/Source/WebKit/UIProcess/API/haiku/WebViewBase.h new file mode 100644 index 000000000000..fccd67ba8613 --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/WebViewBase.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +#include "config.h" + +#include "APIObject.h" +#include "APIPageConfiguration.h" +#include "WebPageProxy.h" +#include "PageClientImplHaiku.h" + +using namespace WebKit; +namespace WebKit +{ + class WebViewBase:public API::ObjectImpl, + public BView + { + public: + static RefPtr create(const char*name,BRect rect, + BWindow* parentWindow,const API::PageConfiguration& config) + { + auto fWebView=adoptRef(*new WebViewBase(name,rect,parentWindow,config)); + return fWebView; + } + WebPageProxy* page() const { return fPage.get(); } + void initializeOnce(); + const char* currentURL() { return page()->pageLoadState().activeURL().utf8().data(); } + //hook methods + virtual void FrameResized(float,float); + virtual void Draw (BRect); + virtual void MouseMoved (BPoint,uint32,const BMessage*); + private: + WebViewBase(const char*,BRect,BWindow*,const API::PageConfiguration&); + + void paint(const WebCore::IntRect&); + + RefPtr fPage; + std::unique_ptr fPageClient; + + bool setSize {false}; + }; +} + + diff --git a/Source/WebKit/UIProcess/API/haiku/WebViewConstants.h b/Source/WebKit/UIProcess/API/haiku/WebViewConstants.h new file mode 100644 index 000000000000..627f94cf0dfb --- /dev/null +++ b/Source/WebKit/UIProcess/API/haiku/WebViewConstants.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _H +#define _H + +enum{ + DID_COMMIT_NAVIGATION = 'dcna', + DID_FINISH_NAVIGATION = 'dfna', + URL_CHANGE = 'urlc', + DID_CHANGE_PROGRESS = 'dcpr', + DID_CHANGE_TITLE = 'dctt', + URL_LOAD_HANDLE = 'urlh', + READY_TO_PAINT = 'retp' +}; + +#endif // _H diff --git a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h index 6b09badb8d0c..84b052e4431d 100644 --- a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h +++ b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h @@ -139,7 +139,6 @@ bool AuxiliaryProcessProxy::send(T&& message, uint64_t destinationID, OptionSet< auto encoder = std::make_unique(T::receiverName(), T::name(), destinationID); encoder->encode(message.arguments()); - return sendMessage(WTFMove(encoder), sendOptions); } diff --git a/Source/WebKit/UIProcess/BackingStore.h b/Source/WebKit/UIProcess/BackingStore.h index 987cc16d47ef..575d25a2a8c4 100644 --- a/Source/WebKit/UIProcess/BackingStore.h +++ b/Source/WebKit/UIProcess/BackingStore.h @@ -33,6 +33,12 @@ #include #endif +#if USE(HAIKU) +#include +#include +#include +#endif + namespace WebKit { class ShareableBitmap; @@ -53,6 +59,9 @@ class BackingStore { #if USE(CAIRO) typedef cairo_t* PlatformGraphicsContext; #endif +#if USE(HAIKU) + typedef BView* PlatformGraphicsContext; +#endif void paint(PlatformGraphicsContext, const WebCore::IntRect&); void incorporateUpdate(const UpdateInfo&); @@ -71,6 +80,10 @@ class BackingStore { #if USE(CAIRO) std::unique_ptr m_backend; #endif +#if PLATFORM(HAIKU) + WebCore::NativeImagePtr m_bitmap; + BView* m_surface; +#endif }; } // namespace WebKit diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp index 16fc396381eb..e3fbb8680655 100644 --- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp +++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp @@ -79,6 +79,7 @@ void DrawingAreaProxyCoordinatedGraphics::paint(BackingStore::PlatformGraphicsCo if (m_currentBackingStoreStateID < m_nextBackingStoreStateID) { // Tell the web process to do a full backing store update now, in case we previously told // it about our next state but didn't request an immediate update. + sendUpdateBackingStoreState(RespondImmediately); // If we haven't yet received our first bits from the WebProcess then don't paint anything. @@ -377,6 +378,7 @@ DrawingAreaProxyCoordinatedGraphics::DrawingMonitor::DrawingMonitor(WebPageProxy // Give redraws more priority. m_timer.setPriority(GDK_PRIORITY_REDRAW - 10); #else + m_timer.setPriority(RunLoopSourcePriority::RunLoopDispatcher); #endif #endif diff --git a/Source/WebKit/UIProcess/Launcher/ProcessLauncher.cpp b/Source/WebKit/UIProcess/Launcher/ProcessLauncher.cpp index f864ca95d838..1fb86ec1f63f 100644 --- a/Source/WebKit/UIProcess/Launcher/ProcessLauncher.cpp +++ b/Source/WebKit/UIProcess/Launcher/ProcessLauncher.cpp @@ -48,6 +48,7 @@ void ProcessLauncher::didFinishLaunchingProcess(ProcessID processIdentifier, IPC m_processIdentifier = processIdentifier; m_isLaunching = false; + if (!m_client) { // FIXME: Make Identifier a move-only object and release port rights/connections in the destructor. #if OS(DARWIN) && !PLATFORM(GTK) @@ -57,7 +58,7 @@ void ProcessLauncher::didFinishLaunchingProcess(ProcessID processIdentifier, IPC #endif return; } - + m_client->didFinishLaunching(this, identifier); } diff --git a/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h b/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h index 64b1a312bfef..9f44b99fb16a 100644 --- a/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h +++ b/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h @@ -41,7 +41,7 @@ namespace WebKit { -#if PLATFORM(GTK) || PLATFORM(WPE) +#if PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(HAIKU) enum class SandboxPermission { ReadOnly, ReadWrite, @@ -75,7 +75,7 @@ class ProcessLauncher : public ThreadSafeRefCounted, public Can bool shouldMakeProcessLaunchFailForTesting { false }; CString customWebContentServiceBundleIdentifier; -#if PLATFORM(GTK) || PLATFORM(WPE) +#if PLATFORM(GTK) || PLATFORM(WPE) || PLATFORM(HAIKU) HashMap extraWebProcessSandboxPaths; #if ENABLE(DEVELOPER_MODE) String processCmdPrefix; diff --git a/Source/WebKit/UIProcess/Launcher/haiku/ProcessLauncherHaiku.cpp b/Source/WebKit/UIProcess/Launcher/haiku/ProcessLauncherHaiku.cpp new file mode 100644 index 000000000000..8d2107650b8b --- /dev/null +++ b/Source/WebKit/UIProcess/Launcher/haiku/ProcessLauncherHaiku.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ProcessLauncher.h" + +#include "ProcessExecutablePath.h" + +#include +#include +#include +#include + +using namespace WebCore; + +namespace WebKit { + +status_t processRef(BString path, entry_ref* pathRef) +{ + BEntry pathEntry(path); + if(!pathEntry.Exists()) + return B_BAD_VALUE; + + status_t result = pathEntry.GetRef(pathRef); + if(result != B_OK) + return result; + + return B_OK; +} + +void ProcessLauncher::launchProcess() +{ + BString executablePath,executableSignature; + + switch (m_launchOptions.processType) { + case ProcessLauncher::ProcessType::Web: + executablePath = executablePathOfWebProcess(); + executableSignature = "application/x-vnd.haiku-webkit.webprocess"; + break; + case ProcessLauncher::ProcessType::Network: + executablePath = executablePathOfNetworkProcess(); + executableSignature = "application/x-vnd.haiku-webkit.networkprocess"; + break; + default: + ASSERT_NOT_REACHED(); + return; + } + + BString processIdentifier,connectionIdentifier; + IPC::Connection::Identifier processInit; + team_id connectionID = getpid(); + + connectionIdentifier.SetToFormat("%ld",connectionID); + processIdentifier.SetToFormat("%" PRIu64, m_launchOptions.processIdentifier.toUInt64()); + processInit.key = processIdentifier; + + unsigned nargs = 5; // size of the argv array for g_spawn_async() + +#if ENABLE(DEVELOPER_MODE) + Vector prefixArgs; + if (!m_launchOptions.processCmdPrefix.isNull()) { + for (auto& arg : m_launchOptions.processCmdPrefix.split(' ')) + prefixArgs.append(arg.utf8()); + nargs += prefixArgs.size(); + } +#endif + + entry_ref executableRef; + if(processRef(executablePath,&executableRef)!=B_OK) + { + return; + } + BStackOrHeapArray argv(nargs); + unsigned i = 0; +#if ENABLE(DEVELOPER_MODE) + // If there's a prefix command, put it before the rest of the args. + // FIXME this won't work with lauching using BRoster... + for (auto& arg : prefixArgs) + argv[i++] = const_cast(arg.data()); +#endif + argv[i++] = executableSignature.String(); + argv[i++] = processIdentifier.String(); + argv[i++] = connectionIdentifier.String(); + + assert(i <= nargs); + + team_id child_id; // TODO do we need to store this somewhere? + status_t result = be_roster->Launch(&executableRef, i, argv, &child_id); + + // We've finished launching the process, message back to the main run loop. + processInit.connectedProcess = child_id; + + RunLoop::main().dispatch([protectedThis = makeRef(*this), this, processInit] { + didFinishLaunchingProcess(m_processIdentifier, processInit); + }); +} + +void ProcessLauncher::terminateProcess() +{ + if (m_isLaunching) { + invalidate(); + return; + } + + if (!m_processIdentifier) + return; + + kill(m_processIdentifier, SIGKILL); + m_processIdentifier = 0; +} + +void ProcessLauncher::platformInvalidate() +{ +} + +} // namespace WebKit + diff --git a/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp b/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp index 346ac6720a65..c461c2b540e9 100644 --- a/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp +++ b/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp @@ -60,6 +60,10 @@ #include #endif +#if PLATFORM(HAIKU) +#include +#endif + #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection()) namespace WebKit { @@ -137,7 +141,6 @@ void NetworkProcessProxy::getNetworkProcessConnection(WebProcessProxy& webProces m_numPendingConnectionRequests++; return; } - bool isServiceWorkerProcess = false; RegistrableDomain registrableDomain; #if ENABLE(SERVICE_WORKER) @@ -146,8 +149,13 @@ void NetworkProcessProxy::getNetworkProcessConnection(WebProcessProxy& webProces registrableDomain = downcast(webProcessProxy).registrableDomain(); } #endif - +#if PLATFORM(HAIKU) + int64_t pid = webProcessProxy.connection()->getConnection(); + connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcessHaiku(isServiceWorkerProcess, registrableDomain,pid), + 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); +#else connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(isServiceWorkerProcess, registrableDomain), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); +#endif } void NetworkProcessProxy::synthesizeAppIsBackground(bool background) @@ -259,7 +267,6 @@ void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::De if (m_processPool.dispatchMessage(connection, decoder)) return; - didReceiveNetworkProcessProxyMessage(connection, decoder); } @@ -300,12 +307,17 @@ void NetworkProcessProxy::didCreateNetworkConnectionToWebProcess(const IPC::Atta // Grab the first pending connection reply. auto reply = m_pendingConnectionReplies.takeFirst().second; - + #if USE(UNIX_DOMAIN_SOCKETS) || OS(WINDOWS) reply(connectionIdentifier); #elif OS(DARWIN) MESSAGE_CHECK(MACH_PORT_VALID(connectionIdentifier.port())); reply(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); +#elif PLATFORM(HAIKU) + BString tempKey; + tempKey.SetToFormat("%u",connectionIdentifier.key()); + /* Reply is alias for DelayedReply; this is where it is stuck now (this is same as other platforms so it will be under their bracket)*/ + reply(connectionIdentifier); #else notImplemented(); #endif diff --git a/Source/WebKit/UIProcess/ProcessAssertion.cpp b/Source/WebKit/UIProcess/ProcessAssertion.cpp index 2fd0783a9fca..fe848ca8d631 100644 --- a/Source/WebKit/UIProcess/ProcessAssertion.cpp +++ b/Source/WebKit/UIProcess/ProcessAssertion.cpp @@ -37,7 +37,7 @@ ProcessAssertion::ProcessAssertion(ProcessID, const String&, AssertionState asse { } -ProcessAssertion::ProcessAssertion(pid_t pid, const String& name, AssertionState assertionState, AssertionReason) +ProcessAssertion::ProcessAssertion(WTF::ProcessID pid, const String& name, AssertionState assertionState, AssertionReason) : m_assertionState(assertionState) { } diff --git a/Source/WebKit/UIProcess/WebContextConnectionClient.cpp b/Source/WebKit/UIProcess/WebContextConnectionClient.cpp index 3b47d0e13003..2fda67895e9a 100644 --- a/Source/WebKit/UIProcess/WebContextConnectionClient.cpp +++ b/Source/WebKit/UIProcess/WebContextConnectionClient.cpp @@ -35,7 +35,6 @@ void WebContextConnectionClient::didCreateConnection(WebProcessPool* processPool { if (!m_client.didCreateConnection) return; - m_client.didCreateConnection(toAPI(processPool), toAPI(connection), m_client.base.clientInfo); } diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp index 303e74fb73af..4a93a1094669 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit/UIProcess/WebPageProxy.cpp @@ -805,7 +805,6 @@ void WebPageProxy::swapToWebProcess(Ref&& process, std::unique_ void WebPageProxy::finishAttachingToWebProcess(IsProcessSwap isProcessSwap) { ASSERT(m_process->state() != AuxiliaryProcessProxy::State::Terminated); - if (m_process->state() == AuxiliaryProcessProxy::State::Running) { // In the process-swap case, the ProvisionalPageProxy constructor already took care of calling webPageEnteringWebProcess() // when the process was provisional. @@ -946,7 +945,6 @@ void WebPageProxy::initializeWebPage() setDrawingArea(pageClient().createDrawingAreaProxy(m_process)); ASSERT(m_drawingArea); - process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters(m_process, *m_drawingArea)), 0); m_process->addVisitedLinkStoreUser(visitedLinkStore(), m_pageID); @@ -7685,7 +7683,7 @@ void WebPageProxy::updateBackingStoreDiscardableState() isDiscardable = false; else isDiscardable = !pageClient().isViewWindowActive() || !isViewVisible(); - + m_drawingArea->setBackingStoreIsDiscardable(isDiscardable); } diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h index d9791feebcad..7bab696d702a 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.h +++ b/Source/WebKit/UIProcess/WebPageProxy.h @@ -136,6 +136,10 @@ OBJC_CLASS _WKRemoteObjectRegistry; #include "ArgumentCodersGtk.h" #endif +#if PLATFORM(HAIKU) +#include +#endif + #if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS_FAMILY) #include #include @@ -236,6 +240,10 @@ typedef struct OpaqueJSContext* JSGlobalContextRef; typedef HWND PlatformWidget; #endif +#if PLATFORM(HAIKU) +typedef BView* PlatformWidget; +#endif + namespace WebKit { class DrawingAreaProxy; class EditableImageController; @@ -820,6 +828,9 @@ class WebPageProxy : public API::ObjectImpl #if PLATFORM(WPE) struct wpe_view_backend* viewBackend(); #endif +#if PLATFORM(HAIKU) + PlatformWidget viewWidget(); +#endif bool isProcessingMouseEvents() const; void processNextQueuedMouseEvent(); diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h index 822c3fc7637d..7044e4a6dd67 100644 --- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h +++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h @@ -269,7 +269,7 @@ WEBSITEDATASTORE_LOADOPTIMIZER_ADDITIONS_1 void platformDestroy(); static void platformRemoveRecentSearches(WallTime); -#if USE(CURL) || USE(SOUP) +#if USE(CURL) || USE(SOUP) || PLATFORM(HAIKU) void platformSetNetworkParameters(WebsiteDataStoreParameters&); #endif diff --git a/Source/WebKit/UIProcess/WebsiteData/haiku/WebsiteDataStoreHaiku.cpp b/Source/WebKit/UIProcess/WebsiteData/haiku/WebsiteDataStoreHaiku.cpp new file mode 100644 index 000000000000..9e96c1e650a4 --- /dev/null +++ b/Source/WebKit/UIProcess/WebsiteData/haiku/WebsiteDataStoreHaiku.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebsiteDataStore.h" +#include "WebsiteDataStoreParameters.h" + +#include + +namespace WebKit { + +void WebsiteDataStore::platformInitialize() +{ + notImplemented(); +} + +void WebsiteDataStore::platformDestroy() +{ + notImplemented(); +} + +void WebsiteDataStore::platformRemoveRecentSearches(WallTime) +{ + notImplemented(); +} + +void WebsiteDataStore::platformSetNetworkParameters(WebsiteDataStoreParameters&) +{ +} +} // namespace WebKit diff --git a/Source/WebKit/UIProcess/haiku/BackingStoreHaiku.cpp b/Source/WebKit/UIProcess/haiku/BackingStoreHaiku.cpp new file mode 100644 index 000000000000..9327b4fa385b --- /dev/null +++ b/Source/WebKit/UIProcess/haiku/BackingStoreHaiku.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "BackingStore.h" +#include "ShareableBitmap.h" +#include "WebViewConstants.h" + +#include +#include +#include "UpdateInfo.h" + +#include +#include +#include +#include +using namespace WebCore; + +namespace WebKit { + +void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo& updateInfo) +{ + if(!m_bitmap) + { + printf("%p has no backing bitmap yet, create it\n", this); + m_bitmap = new BitmapRef(BRect(BPoint(0,0),BSize(m_size)),B_RGBA32,true); + m_surface = new BView(m_bitmap->Bounds(),"view surface",B_FOLLOW_ALL_SIDES,B_WILL_DRAW); + m_bitmap->AddChild(m_surface); + } else { + printf("%p using existing backing store (%p %p)\n", this, &(*m_bitmap), m_surface); + } + + IntPoint updateRectLocation = updateInfo.updateRectBounds.location(); + + GraphicsContext graphicsContext(m_surface); + + for(auto const& updateRect : updateInfo.updateRects) + { + IntRect srcRect = updateRect; + srcRect.move(-updateRectLocation.x(), -updateRectLocation.y()); + bitmap->paint(graphicsContext,updateRect.location(),srcRect); + } + + BMessage sig(READY_TO_PAINT); + be_app->PostMessage(&sig); +} + +void BackingStore::paint(BView* context,const IntRect& rect) +{ + context->DrawBitmap(&(*m_bitmap)); +} + +} diff --git a/Source/WebKit/UIProcess/haiku/TextCheckerHaiku.cpp b/Source/WebKit/UIProcess/haiku/TextCheckerHaiku.cpp new file mode 100644 index 000000000000..93d036f28e66 --- /dev/null +++ b/Source/WebKit/UIProcess/haiku/TextCheckerHaiku.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TextChecker.h" + +#include "TextCheckerState.h" +#include + +namespace WebKit { +using namespace WebCore; + +TextCheckerState& checkerState() +{ + static TextCheckerState textCheckerState; + return textCheckerState; +} + +const TextCheckerState& TextChecker::state() +{ + return checkerState(); +} + +static bool testingModeEnabled = false; + +void TextChecker::setTestingMode(bool enabled) +{ + testingModeEnabled = enabled; +} + +bool TextChecker::isTestingMode() +{ + return testingModeEnabled; +} + +bool TextChecker::isContinuousSpellCheckingAllowed() +{ + return false; +} + +void TextChecker::setContinuousSpellCheckingEnabled(bool) +{ +} + +void TextChecker::setGrammarCheckingEnabled(bool) +{ +} + +void TextChecker::continuousSpellCheckingEnabledStateChanged(bool) +{ +} + +void TextChecker::grammarCheckingEnabledStateChanged(bool) +{ +} + +SpellDocumentTag TextChecker::uniqueSpellDocumentTag(WebPageProxy*) +{ + return { }; +} + +void TextChecker::closeSpellDocumentWithTag(SpellDocumentTag) +{ +} + +void TextChecker::checkSpellingOfString(SpellDocumentTag, StringView, int32_t&, int32_t&) +{ +} + +void TextChecker::checkGrammarOfString(SpellDocumentTag, StringView /* text */, Vector& /* grammarDetails */, int32_t& /* badGrammarLocation */, int32_t& /* badGrammarLength */) +{ +} + +bool TextChecker::spellingUIIsShowing() +{ + return false; +} + +void TextChecker::toggleSpellingUIIsShowing() +{ +} + +void TextChecker::updateSpellingUIWithMisspelledWord(SpellDocumentTag, const String& /* misspelledWord */) +{ +} + +void TextChecker::updateSpellingUIWithGrammarString(SpellDocumentTag, const String& /* badGrammarPhrase */, const GrammarDetail& /* grammarDetail */) +{ +} + +void TextChecker::getGuessesForWord(SpellDocumentTag, const String&, const String& /* context */, int32_t /* insertionPoint */, Vector&, bool) +{ +} + +void TextChecker::learnWord(SpellDocumentTag, const String&) +{ +} + +void TextChecker::ignoreWord(SpellDocumentTag, const String&) +{ +} + +void TextChecker::requestCheckingOfString(Ref&&, int32_t) +{ +} + +#if USE(UNIFIED_TEXT_CHECKING) + +Vector TextChecker::checkTextOfParagraph(SpellDocumentTag, StringView, int32_t, OptionSet, bool) +{ + return { }; +} + +#endif + +} // namespace WebKit diff --git a/Source/WebKit/UIProcess/haiku/WebInspectorProxyHaiku.cpp b/Source/WebKit/UIProcess/haiku/WebInspectorProxyHaiku.cpp new file mode 100644 index 000000000000..e899cfd19f42 --- /dev/null +++ b/Source/WebKit/UIProcess/haiku/WebInspectorProxyHaiku.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspectorProxy.h" + +#if ENABLE(INSPECTOR) + +#include +#include "WebProcessProxy.h" +#include +#include +#include +#include +#include +#include +#include + +namespace WebKit { + +void WebInspectorProxy::platformHide() +{ + notImplemented(); +} + +void WebInspectorProxy::platformBringToFront() +{ + notImplemented(); +} + +bool WebInspectorProxy::platformIsFront() +{ + notImplemented(); + return false; +} + +void WebInspectorProxy::platformInspectedURLChanged(const String& url) +{ + notImplemented(); +} + +String WebInspectorProxy::inspectorPageURL() +{ + StringBuilder builder; + builder.append(inspectorBaseURL()); + builder.appendLiteral("/Main.html"); + + return builder.toString(); +} + +String WebInspectorProxy::inspectorTestPageURL() +{ + StringBuilder builder; + builder.append(inspectorBaseURL()); + builder.appendLiteral("/Test.html"); + + return builder.toString(); +} + +String WebInspectorProxy::inspectorBaseURL() +{ + notImplemented(); + return "file://" /*+ WebCore::inspectorResourcePath()*/; +} + +unsigned WebInspectorProxy::platformInspectedWindowHeight() +{ + notImplemented(); + return 0; +} + +unsigned WebInspectorProxy::platformInspectedWindowWidth() +{ + notImplemented(); + return 0; +} + +void WebInspectorProxy::platformAttach() +{ + notImplemented(); +} + +void WebInspectorProxy::platformDetach() +{ + notImplemented(); +} + +void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned) +{ + notImplemented(); +} + +void WebInspectorProxy::platformSetAttachedWindowWidth(unsigned) +{ + notImplemented(); +} + +void WebInspectorProxy::platformSave(const String&, const String&, bool, bool) +{ + notImplemented(); +} + +void WebInspectorProxy::platformAppend(const String&, const String&) +{ + notImplemented(); +} + +void WebInspectorProxy::platformAttachAvailabilityChanged(bool) +{ + notImplemented(); +} + +void WebInspectorProxy::platformSetSheetRect(const WebCore::FloatRect&) +{ + notImplemented(); +} + +void WebInspectorProxy::platformStartWindowDrag() +{ + notImplemented(); +} + +void WebInspectorProxy::platformCreateFrontendWindow() +{ + notImplemented(); +} +void WebInspectorProxy::platformCloseFrontendPageAndWindow() +{ + notImplemented(); +} + +void WebInspectorProxy::platformShowCertificate(const WebCore::CertificateInfo&) +{ + notImplemented(); +} + +void WebInspectorProxy::platformDidCloseForCrash() +{ + notImplemented(); +} +void WebInspectorProxy::platformInvalidate() +{ + notImplemented(); +} +void WebInspectorProxy::platformBringInspectedPageToFront() +{ + notImplemented(); +} +WebPageProxy* WebInspectorProxy::platformCreateFrontendPage() +{ + notImplemented(); + return nullptr; +} + +} + +#endif diff --git a/Source/WebKit/UIProcess/haiku/WebPageProxyHaiku.cpp b/Source/WebKit/UIProcess/haiku/WebPageProxyHaiku.cpp new file mode 100644 index 000000000000..46d22e21fdcf --- /dev/null +++ b/Source/WebKit/UIProcess/haiku/WebPageProxyHaiku.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPageProxy.h" + +#include +#include "WebKitVersion.h" + +#include + +namespace WebKit { + +void WebPageProxy::platformInitialize() +{ +} + +String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent) +{ + String platform; + String version; + String osVersion; + String standardUserAgentString; + + platform = "Haiku"; + + version = String::number(WEBKIT_MAJOR_VERSION) + '.' + String::number(WEBKIT_MINOR_VERSION) + '+'; + struct utsname name; + if (uname(&name) != -1) + osVersion = WTF::String(name.sysname) + " " + WTF::String(name.machine); + else + osVersion = "Unknown"; + + /*standardUserAgentString = "Mozilla/5.0 (" + platform + "; " + osVersion + ") AppleWebKit/" + version + + " (KHTML, like Gecko) Version/5.0 Safari/" + version;*/ + //needs to be latest- FIXME + standardUserAgentString = "Mozilla/5.0 (Macintosh; Intel Haiku R1 x86) AppleWebKit/608.1.30 (KHTML, like Gecko) WebPositive/1.2 Version/11.1 Safari/608.1.30"; + return applicationNameForUserAgent.isEmpty() ? standardUserAgentString : standardUserAgentString + ' ' + applicationNameForUserAgent; +} + +void WebPageProxy::saveRecentSearches(const String& name, const Vector& searchItems) +{ + notImplemented(); +} + +void WebPageProxy::loadRecentSearches(const String& name, CompletionHandler&&)>&&) +{ + notImplemented(); +} + +void WebPageProxy::updateEditorState(const EditorState& editorState) +{ + m_editorState = editorState; +} + +} diff --git a/Source/WebKit/UIProcess/haiku/WebPreferencesHaiku.cpp b/Source/WebKit/UIProcess/haiku/WebPreferencesHaiku.cpp new file mode 100644 index 000000000000..5abc47b85dbb --- /dev/null +++ b/Source/WebKit/UIProcess/haiku/WebPreferencesHaiku.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPreferences.h" + +#include + +namespace WebKit { + +void WebPreferences::platformInitializeStore() +{ + notImplemented(); +} + +void WebPreferences::platformUpdateStringValueForKey(const String&, const String&) +{ + notImplemented(); +} + +void WebPreferences::platformUpdateBoolValueForKey(const String&, bool) +{ + notImplemented(); +} + +void WebPreferences::platformUpdateUInt32ValueForKey(const String&, uint32_t) +{ + notImplemented(); +} + +void WebPreferences::platformUpdateDoubleValueForKey(const String&, double) +{ + notImplemented(); +} + +void WebPreferences::platformUpdateFloatValueForKey(const String&, float) +{ + notImplemented(); +} + +bool WebPreferences::platformGetStringUserValueForKey(const String&, String&) +{ + notImplemented(); + return false; +} + +bool WebPreferences::platformGetBoolUserValueForKey(const String&, bool&) +{ + notImplemented(); + return false; +} + +bool WebPreferences::platformGetUInt32UserValueForKey(const String&, uint32_t&) +{ + notImplemented(); + return false; +} + +bool WebPreferences::platformGetDoubleUserValueForKey(const String&, double&) +{ + notImplemented(); + return false; +} + +} // namespace WebKit + diff --git a/Source/WebKit/UIProcess/haiku/WebProcessPoolHaiku.cpp b/Source/WebKit/UIProcess/haiku/WebProcessPoolHaiku.cpp new file mode 100644 index 000000000000..7a0c54c77198 --- /dev/null +++ b/Source/WebKit/UIProcess/haiku/WebProcessPoolHaiku.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessPool.h" + +#include "WebProcessCreationParameters.h" +#include + +namespace WebKit { + +void WebProcessPool::platformInitialize() +{ + notImplemented(); +} + +void WebProcessPool::platformInitializeNetworkProcess(NetworkProcessCreationParameters&) +{ + notImplemented(); +} + +void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters) +{ + notImplemented(); +} + +void WebProcessPool::platformInvalidateContext() +{ +} + +void WebProcessPool::platformResolvePathsForSandboxExtensions() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit/WebProcess/Cookies/haiku/WebCookieManagerHaiku.cpp b/Source/WebKit/WebProcess/Cookies/haiku/WebCookieManagerHaiku.cpp new file mode 100644 index 000000000000..b0060a695ed7 --- /dev/null +++ b/Source/WebKit/WebProcess/Cookies/haiku/WebCookieManagerHaiku.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebCookieManager.h" + +#include +#include + +using namespace WebCore; + +namespace WebKit { + +void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) +{ + notImplemented(); +} + +HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy() +{ + notImplemented(); + return HTTPCookieAcceptPolicyAlways; +} + +} diff --git a/Source/WebKit/WebProcess/EntryPoint/unix/WebProcessMain.cpp b/Source/WebKit/WebProcess/EntryPoint/unix/WebProcessMain.cpp index eedd4425b7fe..48d9ab8f0bc7 100644 --- a/Source/WebKit/WebProcess/EntryPoint/unix/WebProcessMain.cpp +++ b/Source/WebKit/WebProcess/EntryPoint/unix/WebProcessMain.cpp @@ -24,6 +24,7 @@ */ #include "WebProcessMainUnix.h" +#include "wtf/Platform.h" #include @@ -48,6 +49,5 @@ int main(int argc, char** argv) #if USE(GCRYPT) PAL::GCrypt::initialize(); #endif - return WebProcessMainUnix(argc, argv); } diff --git a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h index f3e27440c6f8..92e48177a693 100644 --- a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h +++ b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundle.h @@ -39,6 +39,10 @@ typedef struct _GModule GModule; #endif +#if PLATFORM(HAIKU) +#include +#endif + #if USE(FOUNDATION) OBJC_CLASS NSSet; OBJC_CLASS NSBundle; @@ -63,6 +67,8 @@ namespace WebKit { typedef NSBundle *PlatformBundle; #elif USE(GLIB) typedef ::GModule* PlatformBundle; +#elif PLATFORM(HAIKU) +typedef image_id PlatformBundle; #else typedef void* PlatformBundle; #endif diff --git a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp index 905b66e65acd..8823d221bf1c 100644 --- a/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp +++ b/Source/WebKit/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp @@ -31,7 +31,7 @@ #include "APIArray.h" #include "InjectedBundleHitTestResult.h" -#include "Logging.h" +#include "Platform/Logging.h" #include "WebContextMenuItem.h" #include "WKAPICast.h" #include "WKBundleAPICast.h" diff --git a/Source/WebKit/WebProcess/InjectedBundle/haiku/InjectedBundleHaiku.cpp b/Source/WebKit/WebProcess/InjectedBundle/haiku/InjectedBundleHaiku.cpp new file mode 100644 index 000000000000..a6e5fecd826d --- /dev/null +++ b/Source/WebKit/WebProcess/InjectedBundle/haiku/InjectedBundleHaiku.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014,2019 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InjectedBundle.h" + +#include + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundle::initialize(const WebProcessCreationParameters&, API::Object* initializationUserData) +{ + notImplemented(); +} + +void InjectedBundle::setBundleParameter(WTF::String const&, IPC::DataReference const&) +{ +} + +void InjectedBundle::setBundleParameters(const IPC::DataReference&) +{ +} +} diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp index 3dcd7e2ec199..8e302eeb2f68 100644 --- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp @@ -96,6 +96,9 @@ #include #include +#include "CertificateInfo.h" + + namespace WebKit { using namespace WebCore; @@ -227,6 +230,12 @@ bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(*webPage, *m_frame, identifier); } +bool WebFrameLoaderClient::dispatchDidReceiveInvalidCertificate(WebCore::DocumentLoader*, const WebCore::CertificateInfo&, const char* message) +{ + notImplemented(); + return true; +} + void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&) { ASSERT_NOT_REACHED(); diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h index c8fb2af21256..eb8648312d97 100644 --- a/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.h @@ -26,6 +26,7 @@ #pragma once #include +#include "CertificateInfo.h" namespace PAL { class SessionID; @@ -96,6 +97,9 @@ class WebFrameLoaderClient final : public WebCore::FrameLoaderClient { #if ENABLE(DATA_DETECTION) void dispatchDidFinishDataDetection(NSArray *detectionResults) final; #endif + + bool dispatchDidReceiveInvalidCertificate(WebCore::DocumentLoader*, const WebCore::CertificateInfo&, const char* message); + void dispatchDidChangeMainDocument() final; void dispatchWillChangeDocument(const URL& currentUrl, const URL& newUrl) final; diff --git a/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebContextMenuClientHaiku.cpp b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebContextMenuClientHaiku.cpp new file mode 100644 index 000000000000..48e880902f12 --- /dev/null +++ b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebContextMenuClientHaiku.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(CONTEXT_MENUS) + +#include "WebContextMenuClient.h" + +#include + +using namespace WebCore; + +namespace WebKit { + +void WebContextMenuClient::lookUpInDictionary(Frame*) +{ + notImplemented(); +} + +bool WebContextMenuClient::isSpeaking() +{ + notImplemented(); + return false; +} + +void WebContextMenuClient::speak(const String&) +{ + notImplemented(); +} + +void WebContextMenuClient::stopSpeaking() +{ + notImplemented(); +} + +} // namespace WebKit +#endif // ENABLE(CONTEXT_MENUS) + diff --git a/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebEditorClientHaiku.cpp b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebEditorClientHaiku.cpp new file mode 100644 index 000000000000..ac3600256f30 --- /dev/null +++ b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebEditorClientHaiku.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebEditorClient.h" + +#include + +namespace WebKit { +using namespace WebCore; + +void WebEditorClient::handleKeyboardEvent(KeyboardEvent& event) +{ + notImplemented(); +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent& event) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebErrorsHaiku.cpp b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebErrorsHaiku.cpp new file mode 100644 index 000000000000..06e5d2054d87 --- /dev/null +++ b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebErrorsHaiku.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebErrors.h" + +#include "APIError.h" +#include +#include +#include +#include +#include + +using namespace WebCore; + +namespace WebKit { + +ResourceError cancelledError(const ResourceRequest& request) +{ + return WebCore::cancelledError(request); +} + +ResourceError blockedError(const ResourceRequest& request) +{ + return WebCore::blockedError(request); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return WebCore::cannotShowURLError(request); +} + +ResourceError interruptedForPolicyChangeError(const ResourceRequest& request) +{ + return WebCore::interruptedForPolicyChangeError(request); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return WebCore::cannotShowMIMETypeError(response); +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + return WebCore::fileDoesNotExistError(response); +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + return WebCore::pluginWillHandleLoadError(response); +} + +WebCore::ResourceError internalError(const WebCore::URL& url) +{ + return ResourceError(API::Error::webKitErrorDomain(), kWKErrorInternal, url.string(), ASCIILiteral("Internal error")); +} + +} // namespace WebKit + diff --git a/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.cpp b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.cpp new file mode 100644 index 000000000000..c501746448dd --- /dev/null +++ b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebFrameNetworkingContext.h" + +#include +#include +#include "WebFrame.h" + +using namespace WebCore; + +namespace WebKit { + +WebFrameNetworkingContext::WebFrameNetworkingContext(WebFrame* frame) + : FrameNetworkingContext(frame->coreFrame()) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.h b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.h new file mode 100644 index 000000000000..2e696fef2a0b --- /dev/null +++ b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebFrameNetworkingContext.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 Haiku Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#include "HTTPCookieAcceptPolicy.h" +#include +#include + +namespace WebKit { + +class WebFrame; +class WebFrameLoaderClient; + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static Ref create(WebFrame* frame) + { + return adoptRef(*new WebFrameNetworkingContext(frame)); + } + + static void ensurePrivateBrowsingSession(PAL::SessionID); + static void setCookieAcceptPolicyForAllContexts(HTTPCookieAcceptPolicy); + + WebFrameLoaderClient* webFrameLoaderClient() const; + +private: + WebFrameNetworkingContext(WebFrame*); + + WebCore::NetworkStorageSession* storageSession() const override {return nullptr;} +}; + +} + +#endif // WebFrameNetworkingContext_h diff --git a/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebPopupMenuHaiku.cpp b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebPopupMenuHaiku.cpp new file mode 100644 index 000000000000..d84146704e02 --- /dev/null +++ b/Source/WebKit/WebProcess/WebCoreSupport/haiku/WebPopupMenuHaiku.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" +#include + +using namespace WebCore; + +namespace WebKit { + +void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData&) +{ + notImplemented(); +} + +} // namespace WebKit + diff --git a/Source/WebKit/WebProcess/WebPage/WebInspector.cpp b/Source/WebKit/WebProcess/WebPage/WebInspector.cpp index d77e6370c115..e0a3808aa147 100644 --- a/Source/WebKit/WebProcess/WebPage/WebInspector.cpp +++ b/Source/WebKit/WebProcess/WebPage/WebInspector.cpp @@ -90,6 +90,8 @@ void WebInspector::setFrontendConnection(IPC::Attachment encodedConnectionIdenti IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port()); #elif OS(WINDOWS) IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.handle()); +#elif PLATFORM(HAIKU) + IPC::Connection::Identifier connectionIdentifier({NULL,NULL}); #else notImplemented(); return; diff --git a/Source/WebKit/WebProcess/WebPage/WebInspectorUI.cpp b/Source/WebKit/WebProcess/WebPage/WebInspectorUI.cpp index bcff8e2a896f..1b2a574f0b46 100644 --- a/Source/WebKit/WebProcess/WebPage/WebInspectorUI.cpp +++ b/Source/WebKit/WebProcess/WebPage/WebInspectorUI.cpp @@ -96,12 +96,15 @@ void WebInspectorUI::updateConnection() IPC::Connection::Identifier connectionIdentifier, connClient; IPC::Connection::createServerAndClientIdentifiers(connectionIdentifier, connClient); IPC::Attachment connectionClientPort(connClient); +#elif PLATFORM(HAIKU) + IPC::Connection::Identifier connectionIdentifier; + IPC::Attachment connectionClientPort; #else notImplemented(); return; #endif -#if USE(UNIX_DOMAIN_SOCKETS) || OS(DARWIN) || PLATFORM(WIN) +#if USE(UNIX_DOMAIN_SOCKETS) || OS(DARWIN) || PLATFORM(WIN) || PLATFORM(HAIKU) m_backendConnection = IPC::Connection::createServerConnection(connectionIdentifier, *this); m_backendConnection->open(); #endif diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp index c0c2f2a791a3..694b35d0793b 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp +++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp @@ -165,7 +165,11 @@ #include #include #include + +#if ENABLE(GRAPHICS_CONTEXT_3D) #include +#endif + #include #include #include @@ -1561,9 +1565,9 @@ void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLo } void WebPage::loadData(LoadParameters&& loadParameters) -{ +{fprintf(stderr,"\n$$$$$$$$$ %s -- %d $$$$$$$$$$$\n",__PRETTY_FUNCTION__,loadParameters.baseURLString.isEmpty()); platformDidReceiveLoadParameters(loadParameters); - +fprintf(stderr,"\n$$$$$$$$$ %s -- %d $$$$$$$$$$$\n",__PRETTY_FUNCTION__,loadParameters.baseURLString.isEmpty()); auto sharedBuffer = SharedBuffer::create(reinterpret_cast(loadParameters.data.data()), loadParameters.data.size()); URL baseURL = loadParameters.baseURLString.isEmpty() ? WTF::blankURL() : URL(URL(), loadParameters.baseURLString); loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData); diff --git a/Source/WebKit/WebProcess/WebPage/haiku/WebInspectorHaiku.cpp b/Source/WebKit/WebProcess/WebPage/haiku/WebInspectorHaiku.cpp new file mode 100644 index 000000000000..7459ce25f180 --- /dev/null +++ b/Source/WebKit/WebProcess/WebPage/haiku/WebInspectorHaiku.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * Copyright (C) 2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspectorUI.h" +#include "RemoteWebInspectorUI.h" + +#if ENABLE(INSPECTOR) + +#include +#include + +namespace WebKit { + +bool WebInspectorUI::canSave() +{ + return false; +} + +String WebInspectorUI::localizedStringsURL() +{ + notImplemented(); + return "file:///localizedStrings.js"; +} + +String RemoteWebInspectorUI::localizedStringsURL() +{ + notImplemented(); + return "file:///localizedStrings.js"; +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) + diff --git a/Source/WebKit/WebProcess/WebPage/haiku/WebPageHaiku.cpp b/Source/WebKit/WebProcess/WebPage/haiku/WebPageHaiku.cpp new file mode 100644 index 000000000000..e373b836143c --- /dev/null +++ b/Source/WebKit/WebProcess/WebPage/haiku/WebPageHaiku.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPage.h" + +#include +#include +#include +#include +#include +#include + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ +} + +void WebPage::platformReinitialize() +{ +} + +void WebPage::platformDetach() +{ +} + +void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const +{ +} + +#if HAVE(ACCESSIBILITY) +void WebPage::updateAccessibilityTree() +{ + if (!m_accessibilityObject) + return; + + webPageAccessibilityObjectRefresh(m_accessibilityObject.get()); +} +#endif + +bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent) +{ + if (keyboardEvent.type() != WebEvent::KeyDown && keyboardEvent.type() != WebEvent::RawKeyDown) + return false; + + switch (keyboardEvent.windowsVirtualKeyCode()) { + case VK_BACK: + if (keyboardEvent.shiftKey()) + m_page->backForward().goForward(); + else + m_page->backForward().goBack(); + break; + case VK_SPACE: + scroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollUp : ScrollDown, ScrollByPage); + break; + case VK_LEFT: + scroll(m_page.get(), ScrollLeft, ScrollByLine); + break; + case VK_RIGHT: + scroll(m_page.get(), ScrollRight, ScrollByLine); + break; + case VK_UP: + scroll(m_page.get(), ScrollUp, ScrollByLine); + break; + case VK_DOWN: + scroll(m_page.get(), ScrollDown, ScrollByLine); + break; + case VK_HOME: + scroll(m_page.get(), ScrollUp, ScrollByDocument); + break; + case VK_END: + scroll(m_page.get(), ScrollDown, ScrollByDocument); + break; + case VK_PRIOR: + scroll(m_page.get(), ScrollUp, ScrollByPage); + break; + case VK_NEXT: + scroll(m_page.get(), ScrollDown, ScrollByPage); + break; + default: + return false; + } + + return true; +} + +bool WebPage::platformCanHandleRequest(const ResourceRequest&) +{ + notImplemented(); + return false; +} + +const char* WebPage::interpretKeyEvent(const KeyboardEvent* event) +{ + notImplemented(); + return 0; +} + +String WebPage::platformUserAgent(const URL& url) const +{ + notImplemented(); + return String(); +} + + +} // namespace WebKit diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp index 6174b0a3bb0b..73adaab67cab 100644 --- a/Source/WebKit/WebProcess/WebProcess.cpp +++ b/Source/WebKit/WebProcess/WebProcess.cpp @@ -1204,6 +1204,7 @@ void WebProcess::setInjectedBundleParameters(const IPC::DataReference& value) static IPC::Connection::Identifier getNetworkProcessConnection(IPC::Connection& connection) { IPC::Attachment encodedConnectionIdentifier; + if (!connection.sendSync(Messages::WebProcessProxy::GetNetworkProcessConnection(), Messages::WebProcessProxy::GetNetworkProcessConnection::Reply(encodedConnectionIdentifier), 0)) { #if PLATFORM(GTK) || PLATFORM(WPE) // GTK+ and WPE ports don't exit on send sync message failure. @@ -1223,6 +1224,12 @@ static IPC::Connection::Identifier getNetworkProcessConnection(IPC::Connection& return encodedConnectionIdentifier.port(); #elif OS(WINDOWS) return encodedConnectionIdentifier.handle(); +#elif PLATFORM(HAIKU) + //Maybe try cut shorting down + IPC::Connection::Identifier conn; + conn.connectedProcess = encodedConnectionIdentifier.connectionID(); + conn.key.SetToFormat("%u",encodedConnectionIdentifier.key()); + return conn; #else ASSERT_NOT_REACHED(); return IPC::Connection::Identifier(); diff --git a/Source/WebKit/WebProcess/haiku/WebProcessHaiku.cpp b/Source/WebKit/WebProcess/haiku/WebProcessHaiku.cpp new file mode 100644 index 000000000000..f89bb364e41c --- /dev/null +++ b/Source/WebKit/WebProcess/haiku/WebProcessHaiku.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014,2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY MOTOROLA INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcess.h" + +#include + +namespace WebKit { + +void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters& parameters) +{ + notImplemented(); +} + +void WebProcess::platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&&) +{ + notImplemented(); +} + +void WebProcess::platformTerminate() +{ + notImplemented(); +} + +void WebProcess::platformSetCacheModel(CacheModel cacheModel) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit/WebProcess/haiku/WebProcessMainHaiku.cpp b/Source/WebKit/WebProcess/haiku/WebProcessMainHaiku.cpp new file mode 100644 index 000000000000..918c1101765d --- /dev/null +++ b/Source/WebKit/WebProcess/haiku/WebProcessMainHaiku.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2014,2019 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessMainUnix.h" + +#include "AuxiliaryProcessMainHaiku.h" +#include "WebProcess.h" +#include + +using namespace WebCore; + +namespace WebKit { +class WebProcessMainBase: public AuxiliaryProcessMainBase +{ + public: + ProcessApp* app = nullptr; + bool platformInitialize(char* sign) override + { + app = new ProcessApp(sign); + return true; + } + void runApp() + { + app->Run(); + } +}; + +int WebProcessMainUnix(int argc, char** argv) +{ + return AuxiliaryProcessMain(argc,argv); +} + +} // namespace WebKit diff --git a/Source/WebKit/haiku/WebProcess.rdef b/Source/WebKit/haiku/WebProcess.rdef new file mode 100644 index 000000000000..025a7519299b --- /dev/null +++ b/Source/WebKit/haiku/WebProcess.rdef @@ -0,0 +1,12 @@ +resource app_signature "application/x-vnd.haiku-webkit.webprocess"; +resource app_version { + major = 1, + middle = 7, + minor = 0, + + variety = B_APPV_DEVELOPMENT, + internal = 0, + + short_info = "WebProcess backend for Haiku WebKit", + long_info = "Copyright 2014-2019 Haiku, Inc." +}; diff --git a/Source/WebKitLegacy/CMakeLists.txt b/Source/WebKitLegacy/CMakeLists.txt index 82681807dba4..067772393182 100644 --- a/Source/WebKitLegacy/CMakeLists.txt +++ b/Source/WebKitLegacy/CMakeLists.txt @@ -51,6 +51,12 @@ if (APPLE) set_target_properties(WebKitLegacy PROPERTIES LINK_FLAGS "-umbrella WebKit") endif () +if (HAIKU) + WEBKIT_POPULATE_LIBRARY_VERSION(WEBKIT) + set_target_properties(WebKitLegacy PROPERTIES VERSION ${WEBKIT_VERSION} SOVERSION ${WEBKIT_VERSION_MAJOR}) + install(TARGETS WebKitLegacy DESTINATION "${LIB_INSTALL_DIR}") +endif () + if (MSVC) add_custom_command( TARGET WebKitLegacy diff --git a/Source/WebKitLegacy/PlatformHaiku.cmake b/Source/WebKitLegacy/PlatformHaiku.cmake new file mode 100644 index 000000000000..7a014d2eab6a --- /dev/null +++ b/Source/WebKitLegacy/PlatformHaiku.cmake @@ -0,0 +1,137 @@ +LIST(APPEND WebKitLegacy_INCLUDE_DIRECTORIES + "${CMAKE_SOURCE_DIR}/Source" + "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" + "${DERIVED_SOURCES_WEBCORE_DIR}" + "${WEBKITLEGACY_DIR}/Storage" + "${WEBKITLEGACY_DIR}/haiku" + "${WEBKITLEGACY_DIR}/haiku/API" + "${WEBKITLEGACY_DIR}/haiku/WebCoreSupport" + "${WEBCORE_DIR}/contentextensions" + "${WEBCORE_DIR}/css/parser" + "${WEBCORE_DIR}/html/forms" + "${WEBCORE_DIR}/inspector" + "${WEBCORE_DIR}/loader/appcache" + "${WEBCORE_DIR}/loader/archive" + "${WEBCORE_DIR}/loader/cache" + "${WEBCORE_DIR}/loader/icon" + "${WEBCORE_DIR}/Modules/geolocation" + "${WEBCORE_DIR}/Modules/navigatorcontentutils" + "${WEBCORE_DIR}/Modules/webdatabase" + "${WEBCORE_DIR}/page/animation" + "${WEBCORE_DIR}/page/csp" + "${WEBCORE_DIR}/platform/animation" + "${WEBCORE_DIR}/platform/audio" + "${WEBCORE_DIR}/platform/graphics/filters" + "${WEBCORE_DIR}/platform/graphics/opentype" + "${WEBCORE_DIR}/platform/graphics/haiku" + "${WEBCORE_DIR}/platform/graphics/texmap" + "${WEBCORE_DIR}/platform/haiku" + "${WEBCORE_DIR}/platform/mock" + "${WEBCORE_DIR}/platform/network/haiku" + "${WEBCORE_DIR}/plugins" + "${WEBCORE_DIR}/rendering/line" + "${WEBCORE_DIR}/rendering/shapes" + "${WEBCORE_DIR}/rendering/svg" + "${WEBCORE_DIR}/svg" + "${WEBCORE_DIR}/svg/animation" + "${WEBCORE_DIR}/svg/properties" + "${WTF_DIR}" + "${LIBXML2_INCLUDE_DIR}" + "${LIBXSLT_INCLUDE_DIR}" + "${SQLITE_INCLUDE_DIR}" + "${CMAKE_BINARY_DIR}" + "${FORWARDING_HEADERS_DIR}" +) + +# These folders have includes with the same name as Haiku system ones. So we +# add them with -iquote only, as a way to reach the Haiku includes with +# #include <> +SET(WebKitLegacy_LOCAL_INCLUDE_DIRECTORIES + "${FORWARDING_HEADERS_DIR}/WebCore" + "${WEBCORE_DIR}/Modules/notifications" # Notification.h + "${WEBCORE_DIR}/platform/text" # DateTimeFormat.h +) + +foreach(inc ${WebKitLegacy_LOCAL_INCLUDE_DIRECTORIES}) + ADD_DEFINITIONS(-iquote ${inc}) +endforeach(inc) + +IF (ENABLE_VIDEO_TRACK) + LIST(APPEND WebKitLegacy_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/html/track" + ) +ENDIF () + +IF (ENABLE_NOTIFICATIONS) + LIST(APPEND WebKitLegacy_LOCAL_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/Modules/notifications" + ) +ENDIF () + +add_definitions("-include WebKitPrefix.h") + +LIST(APPEND WebKitLegacy_SOURCES + haiku/WebCoreSupport/AcceleratedCompositingContext.cpp + haiku/WebCoreSupport/BackForwardList.cpp + haiku/WebCoreSupport/ChromeClientHaiku.cpp + haiku/WebCoreSupport/ContextMenuClientHaiku.cpp + haiku/WebCoreSupport/DragClientHaiku.cpp + haiku/WebCoreSupport/DumpRenderTreeSupportHaiku.cpp + haiku/WebCoreSupport/EditorClientHaiku.cpp + haiku/WebCoreSupport/FrameLoaderClientHaiku.cpp + haiku/WebCoreSupport/FrameNetworkingContextHaiku.cpp + haiku/WebCoreSupport/IconDatabase.cpp + haiku/WebCoreSupport/InspectorClientHaiku.cpp + haiku/WebCoreSupport/NotificationClientHaiku.cpp + haiku/WebCoreSupport/PlatformStrategiesHaiku.cpp + haiku/WebCoreSupport/ProgressTrackerHaiku.cpp + haiku/WebCoreSupport/WebApplicationCache.cpp + haiku/WebCoreSupport/WebDatabaseProvider.cpp + haiku/WebCoreSupport/WebDiagnosticLoggingClient.cpp + haiku/WebCoreSupport/WebVisitedLinkStore.cpp + + haiku/API/WebDownload.cpp + haiku/API/WebDownloadPrivate.cpp + haiku/API/WebFrame.cpp + haiku/API/WebKitInfo.cpp + haiku/API/WebPage.cpp + haiku/API/WebSettings.cpp + haiku/API/WebSettingsPrivate.cpp + haiku/API/WebView.cpp + haiku/API/WebWindow.cpp + + Storage/StorageAreaImpl.cpp + Storage/StorageAreaSync.cpp + Storage/StorageNamespaceImpl.cpp + Storage/StorageSyncManager.cpp + Storage/StorageThread.cpp + Storage/StorageTracker.cpp + Storage/WebDatabaseProvider.cpp + Storage/WebStorageNamespaceProvider.cpp +) + +LIST(APPEND WebKitLegacy_LIBRARIES + ${LIBXML2_LIBRARIES} + ${SQLITE_LIBRARIES} + ${PNG_LIBRARY} + ${JPEG_LIBRARY} + ${CMAKE_DL_LIBS} + ${OPENGL_LIBRARIES} + be bnetapi shared translation tracker + WebCore +) + +INSTALL(FILES + haiku/API/WebWindow.h + haiku/API/WebViewConstants.h + haiku/API/WebView.h + haiku/API/WebSettings.h + haiku/API/WebPage.h + haiku/API/WebKitInfo.h + haiku/API/WebFrame.h + haiku/API/WebDownload.h + DESTINATION develop/headers${CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR} + COMPONENT devel +) + + diff --git a/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp b/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp index 4a94a1d85cec..962576dd9685 100644 --- a/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp +++ b/Source/WebKitLegacy/Storage/StorageNamespaceImpl.cpp @@ -28,8 +28,8 @@ #include "StorageAreaImpl.h" #include "StorageSyncManager.h" #include "StorageTracker.h" -#include -#include +#include +#include #include #include #include diff --git a/Source/WebKitLegacy/Storage/WebDatabaseProvider.h b/Source/WebKitLegacy/Storage/WebDatabaseProvider.h index 52223309b39b..835807200cea 100644 --- a/Source/WebKitLegacy/Storage/WebDatabaseProvider.h +++ b/Source/WebKitLegacy/Storage/WebDatabaseProvider.h @@ -25,7 +25,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Source/WebKitLegacy/WebCoreSupport/WebViewGroup.cpp b/Source/WebKitLegacy/WebCoreSupport/WebViewGroup.cpp index 63cae2d0ad52..6f35ae63e587 100644 --- a/Source/WebKitLegacy/WebCoreSupport/WebViewGroup.cpp +++ b/Source/WebKitLegacy/WebCoreSupport/WebViewGroup.cpp @@ -28,7 +28,7 @@ #include "WebStorageNamespaceProvider.h" #include "WebView.h" #include "WebVisitedLinkStore.h" -#include +#include #include #include diff --git a/Source/WebKitLegacy/haiku/API/DumpRenderTreeClient.h b/Source/WebKitLegacy/haiku/API/DumpRenderTreeClient.h new file mode 100644 index 000000000000..85f176d28381 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/DumpRenderTreeClient.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2013 Haiku, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef DumpRenderTreeClient_h +#define DumpRenderTreeClient_h + +#include +#include + +#include "wtf/URL.h" +#include +#include +#include +#include + +namespace WebCore { +class DOMWrapperWorld; +class Frame; +class MessagePortChannel; +} + +class BBitmap; +class BMessage; +class BWebFrame; +class BWebPage; +class BWebView; +class DumpRenderTreeApp; + + +namespace WebCore { + +class __attribute__((visibility ("default"))) DumpRenderTreeClient { +public: + virtual ~DumpRenderTreeClient() { } + virtual void didClearWindowObjectInWorld(WebCore::DOMWrapperWorld&, JSGlobalContextRef, JSObjectRef windowObject) = 0; + + void Register(BWebPage* page); + + static void setDumpRenderTreeModeEnabled(bool); + static bool dumpRenderTreeModeEnabled(); + + static unsigned pendingUnloadEventCount(const BWebFrame* frame); + static String responseMimeType(const BWebFrame* frame); + static String suitableDRTFrameName(const BWebFrame* frame); + static void setValueForUser(JSContextRef, JSValueRef nodeObject, const String& value); + static BBitmap* getOffscreen(BWebView* view); + static BList frameChildren(BWebFrame* frame); + + static void setSeamlessIFramesEnabled(bool); + + + static void garbageCollectorCollect(); + static void garbageCollectorCollectOnAlternateThread(bool waitUntilDone); + static size_t javaScriptObjectsCount(); + + static void setDeadDecodedDataDeletionInterval(double); + + static JSGlobalContextRef globalContextRefForFrame(const BWebFrame* frame); + + static void setMockScrollbarsEnabled(bool); + + static void deliverAllMutationsIfNecessary(); + static void setDomainRelaxationForbiddenForURLScheme(bool forbidden, + const String& scheme); + static void setSerializeHTTPLoads(bool); + static void setShouldTrackVisitedLinks(bool); + + static void addUserScript(const BWebView* view, const String& sourceCode, + bool runAtStart, bool allFrames); + static void clearUserScripts(const BWebView* view); + static void executeCoreCommandByName(const BWebView* view, + const BString name, const BString value); + + static void injectMouseEvent(BWebPage* target, BMessage* event); + static void injectKeyEvent(BWebPage* target, BMessage* event); +private: + static bool s_drtRun; +}; + +} + +#endif diff --git a/Source/WebKitLegacy/haiku/API/WebDownload.cpp b/Source/WebKitLegacy/haiku/API/WebDownload.cpp new file mode 100644 index 000000000000..53f55122a617 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebDownload.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebDownload.h" + +#include "WebDownloadPrivate.h" +#include +#include + +enum { + HANDLE_CANCEL = 'hdlc' +}; + +BWebDownload::BWebDownload(BPrivate::WebDownloadPrivate* data) + : fData(data) +{ + ASSERT(fData); + + if (be_app->Lock()) { + be_app->AddHandler(this); + be_app->Unlock(); + } + + fData->setDownload(this); +} + +BWebDownload::~BWebDownload() +{ + if (be_app->Lock()) { + be_app->RemoveHandler(this); + be_app->Unlock(); + } + delete fData; +} + +void BWebDownload::Start(const BPath& path) +{ + // Does not matter which thread this is invoked in, as long as the + // rest of the code is blocking... + fData->start(path); +} + +void BWebDownload::HasMovedTo(const BPath& path) +{ + fData->hasMovedTo(path); +} + +void BWebDownload::Cancel() +{ + // This is invoked from the client, within any thread, so we need to + // dispatch this asynchronously so that it is actually handled in the + // main thread. + BMessage message(HANDLE_CANCEL); + Looper()->PostMessage(&message, this); +} + +void BWebDownload::SetProgressListener(const BMessenger& listener) +{ + fData->setProgressListener(listener); +} + +const BString& BWebDownload::URL() const +{ + return fData->url(); +} + +const BPath& BWebDownload::Path() const +{ + return fData->path(); +} + +const BString& BWebDownload::Filename() const +{ + return fData->filename(); +} + +off_t BWebDownload::CurrentSize() const +{ + return fData->currentSize(); +} + +off_t BWebDownload::ExpectedSize() const +{ + return fData->expectedSize(); +} + +// #pragma mark - private + +void BWebDownload::MessageReceived(BMessage* message) +{ + switch (message->what) { + case HANDLE_CANCEL: + _HandleCancel(); + break; + default: + BHandler::MessageReceived(message); + } +} + +void BWebDownload::_HandleCancel() +{ + fData->cancel(); +} + diff --git a/Source/WebKitLegacy/haiku/API/WebDownload.h b/Source/WebKitLegacy/haiku/API/WebDownload.h new file mode 100644 index 000000000000..f9a7482db046 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebDownload.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _WEB_DOWNLOAD_H_ +#define _WEB_DOWNLOAD_H_ + +#include + + +namespace BPrivate { +class WebDownloadPrivate; +} + +class BMessenger; +class BPath; +class BString; +class BWebPage; + + +enum { + B_DOWNLOAD_STARTED = 'dwns', + B_DOWNLOAD_PROGRESS = 'dwnp' +}; + +enum { + B_DOWNLOAD_FINISHED = 0, + B_DOWNLOAD_FAILED, + B_DOWNLOAD_BLOCKED, + B_DOWNLOAD_CANNOT_SHOW_URL +}; + + +class __attribute__ ((visibility ("default"))) BWebDownload : public BHandler { +// TODO: Inherit from BReferenceable. +public: + void Start(const BPath& path); + void Cancel(); + + void HasMovedTo(const BPath& path); + + void SetProgressListener(const BMessenger& listener); + + const BString& URL() const; + const BPath& Path() const; + const BString& Filename() const; + + off_t CurrentSize() const; + off_t ExpectedSize() const; + +private: + friend class BWebPage; + friend class BPrivate::WebDownloadPrivate; + + BWebDownload(BPrivate::WebDownloadPrivate* data); + ~BWebDownload(); + +private: + virtual void MessageReceived(BMessage* message); + + void _HandleCancel(); + +private: + BPrivate::WebDownloadPrivate* fData; +}; + +#endif // _WEB_DOWNLOAD_H_ diff --git a/Source/WebKitLegacy/haiku/API/WebDownloadPrivate.cpp b/Source/WebKitLegacy/haiku/API/WebDownloadPrivate.cpp new file mode 100644 index 000000000000..e56b9e45cc4a --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebDownloadPrivate.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebDownloadPrivate.h" + +#include "NetworkingContext.h" +#include "NotImplemented.h" +#include "ResourceHandle.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include "TextEncoding.h" +#include "WebDownload.h" +#include "WebPage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace BPrivate { + +static const int kMaxMimeTypeGuessTries = 5; + +WebDownloadPrivate::WebDownloadPrivate(const ResourceRequest& request, + WebCore::NetworkingContext* context) + : m_webDownload(0) + , m_resourceHandle(ResourceHandle::create(context, request, this, false, false, false)) + , m_currentSize(0) + , m_expectedSize(0) + , m_url(request.url().string()) + , m_path("/boot/home/Desktop/") + , m_filename("Download") + , m_mimeType() + , m_mimeTypeGuessTries(kMaxMimeTypeGuessTries) + , m_file() + , m_lastProgressReportTime(0) +{ +} + +void WebDownloadPrivate::didReceiveResponseAsync(ResourceHandle*, ResourceResponse&& response, WTF::CompletionHandler&& handler) +{ + if (!response.isNull()) { + if (!response.suggestedFilename().isEmpty()) + m_filename = response.suggestedFilename(); + else { + WTF::URL url(response.url()); + url.setQuery(String()); + url.removeFragmentIdentifier(); + m_filename = WebCore::decodeURLEscapeSequences(url.lastPathComponent()).utf8().data(); + } + if (response.mimeType().length()) { + // Do some checks, as no mime type yet is always better + // than set an invalid one + BString mimeType = response.mimeType(); + BMimeType type(mimeType); + BMimeType superType; + if (type.IsValid() && type.GetSupertype(&superType) == B_OK + && superType.IsValid() + && strchr(mimeType, '*') == NULL) { + m_mimeType = mimeType; + } + } + + m_expectedSize = response.expectedContentLength(); + } + + m_url = response.url().string(); +} + +void WebDownloadPrivate::didReceiveData(ResourceHandle*, const char* data, unsigned length, int /*lengthReceived*/) +{ + if (m_file.InitCheck() != B_OK) + createFile(); + + ssize_t bytesWritten = m_file.Write(data, length); + if (bytesWritten != (ssize_t)length) { + // FIXME: Report error + return; + } + m_currentSize += length; + + if (m_currentSize > 0 && m_mimeTypeGuessTries > 0) { + // Try to guess the MIME type from its actual content + BMimeType type; + entry_ref ref; + BEntry entry(m_path.Path()); + entry.GetRef(&ref); + + if (BMimeType::GuessMimeType(&ref, &type) == B_OK + && type.Type() != B_FILE_MIME_TYPE) { + BNodeInfo info(&m_file); + info.SetType(type.Type()); + m_mimeTypeGuessTries = -1; + } else + m_mimeTypeGuessTries--; + } + + // FIXME: Report total size update, if m_currentSize greater than previous total size + BMessage message(B_DOWNLOAD_PROGRESS); + message.AddFloat("progress", m_currentSize * 100.0 / m_expectedSize); + message.AddInt64("current size", m_currentSize); + message.AddInt64("expected size", m_expectedSize); + m_progressListener.SendMessage(&message); +} + +void WebDownloadPrivate::didFinishLoading(ResourceHandle* handle) +{ + handleFinished(handle, B_DOWNLOAD_FINISHED); +} + +void WebDownloadPrivate::didFail(ResourceHandle* handle, const ResourceError& /*error*/) +{ + handleFinished(handle, B_DOWNLOAD_FAILED); +} + +void WebDownloadPrivate::wasBlocked(ResourceHandle* handle) +{ + // FIXME: Implement this when we have the new frame loader signals + // and error handling. + handleFinished(handle, B_DOWNLOAD_BLOCKED); +} + +void WebDownloadPrivate::cannotShowURL(ResourceHandle* handle) +{ + // FIXME: Implement this when we have the new frame loader signals + // and error handling. + handleFinished(handle, B_DOWNLOAD_CANNOT_SHOW_URL); +} + +void WebDownloadPrivate::setDownload(BWebDownload* download) +{ + m_webDownload = download; +} + +void WebDownloadPrivate::start(const BPath& path) +{ + if (path.InitCheck() == B_OK) + m_path = path; +} + +void WebDownloadPrivate::hasMovedTo(const BPath& path) +{ + m_path = path; +} + +void WebDownloadPrivate::cancel() +{ + m_resourceHandle->cancel(); +} + +void WebDownloadPrivate::setProgressListener(const BMessenger& listener) +{ + m_progressListener = listener; +} + +// #pragma mark - private + +void WebDownloadPrivate::handleFinished(WebCore::ResourceHandle* handle, uint32 /*status*/) +{ + if (m_mimeTypeGuessTries != -1 && m_mimeType.Length() > 0) { + // In last resort, use the MIME type provided + // by the response, which pass our validation + BNodeInfo info(&m_file); + info.SetType(m_mimeType); + } + + if (m_progressListener.IsValid()) { + BMessage message(B_DOWNLOAD_REMOVED); + message.AddPointer("download", m_webDownload); + // Block until the listener has released the object on it's side... + BMessage reply; + m_progressListener.SendMessage(&message, &reply); + } + delete m_webDownload; +} + +void WebDownloadPrivate::createFile() +{ + // Don't overwrite existing files + findAvailableFilename(); + + if (m_file.SetTo(m_path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY) == B_OK) + m_file.WriteAttrString("META:url", &m_url); + + if (m_progressListener.IsValid()) { + BMessage message(B_DOWNLOAD_STARTED); + message.AddString("path", m_path.Path()); + m_progressListener.SendMessage(&message); + } +} + +void WebDownloadPrivate::findAvailableFilename() +{ + BPath filePath = m_path; + BString fileName = m_filename; + filePath.Append(fileName.String()); + + // Make sure the parent directory exists. + BPath parent; + if (filePath.GetParent(&parent) == B_OK) + create_directory(parent.Path(), 0755); + + // Find a name that doesn't exists in the directoy yet + BEntry entry(filePath.Path()); + for (int32 i = 0; entry.InitCheck() == B_OK && entry.Exists(); i++) { + // Use original file name in each iteration + BString baseName = m_filename; + + // Separate extension and base file name + int32 extensionStart = baseName.FindLast('.'); + BString extension; + if (extensionStart > 0) + baseName.MoveInto(extension, extensionStart, baseName.CountChars() - extensionStart); + + // Add i to file name before the extension + char num[10]; + snprintf(num, sizeof(num), "-%ld", i); + baseName.Append(num).Append(extension); + fileName = baseName; + filePath = m_path; + filePath.Append(fileName); + entry.SetTo(filePath.Path()); + } + m_filename = fileName; + m_path = filePath; +} + +} // namespace BPrivate + diff --git a/Source/WebKitLegacy/haiku/API/WebDownloadPrivate.h b/Source/WebKitLegacy/haiku/API/WebDownloadPrivate.h new file mode 100644 index 000000000000..cb691bb7e503 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebDownloadPrivate.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebDownload_h +#define WebDownload_h + +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include +#include +#include +#include +#include +#include + +namespace WebCore { +class NetworkingContext; +class ResourceError; +class ResourceRequest; +class ResourceResponse; +} + +using WebCore::ResourceError; +using WebCore::ResourceHandle; +using WebCore::ResourceRequest; +using WebCore::ResourceResponse; + +class BWebDownload; +class BWebPage; + +namespace BPrivate { + +class WebDownloadPrivate : public WebCore::ResourceHandleClient { + WTF_MAKE_NONCOPYABLE(WebDownloadPrivate); +public: + WebDownloadPrivate(const ResourceRequest&, WebCore::NetworkingContext*); + + // ResourceHandleClient implementation + virtual void didReceiveResponseAsync(ResourceHandle*, ResourceResponse&&, WTF::CompletionHandler&&) override; + virtual void didReceiveData(ResourceHandle*, const char*, unsigned, int) override; + virtual void didFinishLoading(ResourceHandle*) override; + virtual void didFail(ResourceHandle*, const ResourceError&) override; + virtual void wasBlocked(ResourceHandle*) override; + virtual void cannotShowURL(ResourceHandle*) override; + void willSendRequestAsync(ResourceHandle*, ResourceRequest&&, ResourceResponse&&, CompletionHandler&&) override {} + + void setDownload(BWebDownload*); + void start(const BPath& path); + void hasMovedTo(const BPath& path); + void cancel(); + void setProgressListener(const BMessenger&); + + const BString& url() const { return m_url; } + const BString& filename() const { return m_filename; } + const BPath& path() const { return m_path; } + off_t currentSize() const { return m_currentSize; } + off_t expectedSize() const { return m_expectedSize; } + +private: + void handleFinished(WebCore::ResourceHandle* handle, uint32 status); + void createFile(); + void findAvailableFilename(); + +private: + BWebDownload* m_webDownload; + + RefPtr m_resourceHandle; + off_t m_currentSize; + off_t m_expectedSize; + BString m_url; + BPath m_path; + BString m_filename; + BString m_mimeType; + int m_mimeTypeGuessTries; + BFile m_file; + bigtime_t m_lastProgressReportTime; + + BMessenger m_progressListener; +}; + +} // namespace BPrivate + +#endif // WebDownload_h diff --git a/Source/WebKitLegacy/haiku/API/WebFrame.cpp b/Source/WebKitLegacy/haiku/API/WebFrame.cpp new file mode 100644 index 000000000000..30376a12b468 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebFrame.cpp @@ -0,0 +1,453 @@ +/* + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebFrame.h" + +#include "Document.h" +#include "DocumentLoader.h" +#include "Editor.h" +#include "EditorClientHaiku.h" +#include "Element.h" +#include "Frame.h" +#include "FrameLoadRequest.h" +#include "FrameLoader.h" +#include "FrameLoaderClientHaiku.h" +#include "FrameView.h" +#include "HTMLFrameOwnerElement.h" +#include "Page.h" +#include "ProgressTracker.h" +#include "ProgressTrackerHaiku.h" +#include "RenderObject.h" +#include "RenderTreeAsText.h" +#include "RenderView.h" +#include "wtf/URL.h" +#include "WebFramePrivate.h" +#include "WebPage.h" +#include "markup.h" +#include +#include +#include + +#include +#include + +static const float kMinimumZoomFactorMultiplier = 0.5; +static const float kMaximumZoomFactorMultiplier = 3; +static const float kZoomFactorMultiplierRatio = 1.1; + +using namespace WebCore; + +BWebFrame::BWebFrame(BWebPage* webPage, BWebFrame* parentFrame, + WebFramePrivate* data) + : fZoomFactor(1.0) + , fIsEditable(false) + , fTitle(0) + , fData(data) +{ + if (!parentFrame) { + // No parent, we are creating the main BWebFrame. + // mainframe is already created in WebCore::Page, just use it. + fData->frame = &webPage->page()->mainFrame(); + fData->loaderClient = std::unique_ptr(static_cast( + &fData->frame->loader().client())); + fData->loaderClient->setFrame(this); + + fData->frame->init(); + fData->frame->tree().setName(fData->name); + } else { + // Will be initialized in BWebFrame::AddChild + } +} + +BWebFrame::~BWebFrame() +{ + delete fData; +} + + +bool +WebFramePrivate::Init(WebCore::Page* page, BWebFrame* frame, + std::unique_ptr frameLoaderClient) +{ + if(!this->frame) { + loaderClient = std::move(frameLoaderClient); + loaderClient->setFrame(frame); + this->page = page; + return true; + } + + // Frame is already initialized. + return false; +} + + +void BWebFrame::SetListener(const BMessenger& listener) +{ + fData->loaderClient->setDispatchTarget(listener); +} + +void BWebFrame::LoadURL(BString urlString) +{ + WTF::URL url; + if (BEntry(urlString.String()).Exists()) { + url.setProtocol("file"); + url.setPath(urlString); + } else + url = WTF::URL(WTF::URL(), urlString.Trim()); + + if (!url.isValid()) { + BString fixedUrl("http://"); + fixedUrl << urlString.Trim(); + url = WTF::URL(WTF::URL(), fixedUrl); + } + LoadURL(url); +} + +void BWebFrame::LoadURL(WTF::URL url) +{ + if (url.isEmpty()) + return; + + if (!fData->frame) + return; + + fData->requestedURL = url.string(); + + WebCore::ResourceRequest req(url); + fData->frame->loader().load(WebCore::FrameLoadRequest(*fData->frame, req, + ShouldOpenExternalURLsPolicy::ShouldNotAllow)); +} + +void BWebFrame::StopLoading() +{ + if (fData->frame) + fData->frame->loader().stop(); +} + +void BWebFrame::Reload() +{ + if (fData->frame) + fData->frame->loader().reload(); +} + +BString BWebFrame::URL() const +{ + if (fData->frame->document() == NULL) + return ""; + return fData->frame->document()->url().string(); +} + +BString BWebFrame::RequestedURL() const +{ + return fData->requestedURL; +} + +bool BWebFrame::CanCopy() const +{ + if (fData->frame && fData->frame->view()) + return fData->frame->editor().canCopy() || fData->frame->editor().canDHTMLCopy(); + + return false; +} + +bool BWebFrame::CanCut() const +{ + if (fData->frame && fData->frame->view()) + return fData->frame->editor().canCut() || fData->frame->editor().canDHTMLCut(); + + return false; +} + +bool BWebFrame::CanPaste() const +{ + if (fData->frame && fData->frame->view()) + return fData->frame->editor().canPaste() || fData->frame->editor().canDHTMLPaste(); + + return false; +} + +void BWebFrame::Copy() +{ + if (CanCopy()) + fData->frame->editor().copy(); +} + +void BWebFrame::Cut() +{ + if (CanCut()) + fData->frame->editor().cut(); +} + +void BWebFrame::Paste() +{ + if (CanPaste()) + fData->frame->editor().paste(); +} + +bool BWebFrame::CanUndo() const +{ + if (fData->frame) + return fData->frame->editor().canUndo(); + + return false; +} + +bool BWebFrame::CanRedo() const +{ + if (fData->frame) + return fData->frame->editor().canRedo(); + + return false; +} + +void BWebFrame::Undo() +{ + if (CanUndo()) + return fData->frame->editor().undo(); +} + +void BWebFrame::Redo() +{ + if (CanRedo()) + return fData->frame->editor().redo(); +} + +bool BWebFrame::AllowsScrolling() const +{ + if (fData->frame && fData->frame->view()) + return fData->frame->view()->canHaveScrollbars(); + + return false; +} + +void BWebFrame::SetAllowsScrolling(bool flag) +{ + if (fData->frame && fData->frame->view()) + fData->frame->view()->setCanHaveScrollbars(flag); +} + +BPoint BWebFrame::ScrollPosition() +{ + return fData->frame->view()->scrollPosition(); +} + +/*! + Returns the frame's content as HTML, enclosed in HTML and BODY tags. +*/ +BString BWebFrame::FrameSource() const +{ + if (fData->frame) { + WebCore::Document* document = fData->frame->document(); + + if (document) + return BString(serializePreservingVisualAppearance(document->createRange())); + } + + return BString(); +} + +void BWebFrame::SetFrameSource(const BString& /*source*/) +{ + // FIXME: see QWebFrame::setHtml/setContent +} + +void BWebFrame::SetTransparent(bool transparent) +{ + if (fData->frame && fData->frame->view()) + fData->frame->view()->setTransparent(transparent); +} + +bool BWebFrame::IsTransparent() const +{ + if (fData->frame && fData->frame->view()) + return fData->frame->view()->isTransparent(); + + return false; +} + +BString BWebFrame::InnerText() const +{ + FrameView* view = fData->frame->view(); + + WebCore::Element *documentElement = fData->frame->document()->documentElement(); + + if (!documentElement) + return String(); + + return documentElement->innerText(); +} + +BString BWebFrame::AsMarkup() const +{ + if (!fData->frame->document()) + return BString(); + + return serializePreservingVisualAppearance(fData->frame->document()->createRange()); +} + +BString BWebFrame::ExternalRepresentation() const +{ + FrameView* view = fData->frame->view(); + + return externalRepresentation(fData->frame); +} + +bool BWebFrame::FindString(const BString& string, WebCore::FindOptions options) +{ + if (fData->page) + return fData->page->findString(string, options); + return false; +} + +bool BWebFrame::CanIncreaseZoomFactor() const +{ + if (fData->frame) { + if (fZoomFactor * kZoomFactorMultiplierRatio <= kMaximumZoomFactorMultiplier) + return true; + } + + return false; +} + +bool BWebFrame::CanDecreaseZoomFactor() const +{ + if (fData->frame) + return fZoomFactor / kZoomFactorMultiplierRatio >= kMinimumZoomFactorMultiplier; + + return false; +} + +void BWebFrame::IncreaseZoomFactor(bool textOnly) +{ + if (CanIncreaseZoomFactor()) { + fZoomFactor = fZoomFactor * kZoomFactorMultiplierRatio; + if (textOnly) + fData->frame->setTextZoomFactor(fZoomFactor); + else + fData->frame->setPageAndTextZoomFactors(fZoomFactor, fZoomFactor); + } +} + +void BWebFrame::DecreaseZoomFactor(bool textOnly) +{ + if (CanDecreaseZoomFactor()) { + fZoomFactor = fZoomFactor / kZoomFactorMultiplierRatio; + if (textOnly) + fData->frame->setTextZoomFactor(fZoomFactor); + else + fData->frame->setPageAndTextZoomFactors(fZoomFactor, fZoomFactor); + } +} + +void BWebFrame::ResetZoomFactor() +{ + if (fZoomFactor == 1) + return; + + fZoomFactor = 1; + + if (fData->frame) + fData->frame->setPageAndTextZoomFactors(fZoomFactor, fZoomFactor); +} + +void BWebFrame::SetEditable(bool editable) +{ + fIsEditable = editable; +} + +bool BWebFrame::IsEditable() const +{ + return fIsEditable; +} + +void BWebFrame::SetTitle(const BString& title) +{ + if (fTitle == title) + return; + + fTitle = title; +} + +const BString& BWebFrame::Title() const +{ + return fTitle; +} + +// #pragma mark - private + + +const char* BWebFrame::Name() const +{ + fName = WTF::String(Frame()->tree().uniqueName()).utf8().data(); + return fName.String(); +} + + +WebCore::Frame* BWebFrame::Frame() const +{ + return fData->frame; +} + + +BWebFrame* BWebFrame::AddChild(BWebPage* page, BString name, + WebCore::HTMLFrameOwnerElement* ownerElement) +{ + WebFramePrivate* data = new WebFramePrivate(); + data->name = name; + data->ownerElement = ownerElement; + + BWebFrame* frame = new(std::nothrow) BWebFrame(page, this, data); + + if (!frame) + return nullptr; + + if (!data->Init(fData->page, frame, + std::make_unique(page))) { + delete frame; + return nullptr; + } + + RefPtr coreFrame = WebCore::Frame::create(fData->page, + ownerElement, data->loaderClient.get()); + // We don't keep the reference to the Frame, see WebFramePrivate.h. + data->frame = coreFrame.get(); + coreFrame->tree().setName(name.String()); + + if (ownerElement) + ownerElement->document().frame()->tree().appendChild(*coreFrame.get()); + data->frame->init(); + // TODO? evas_object_smart_member_add(frame, ewkFrame); + + // The creation of the frame may have run arbitrary JavaScript that removed + // it from the page already. + if (!coreFrame->page()) { + return nullptr; + } + return frame; +} diff --git a/Source/WebKitLegacy/haiku/API/WebFrame.h b/Source/WebKitLegacy/haiku/API/WebFrame.h new file mode 100644 index 000000000000..8de6ce48f59c --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebFrame.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _WEB_FRAME_H_ +#define _WEB_FRAME_H_ + + +#include +#include + +#include "FindOptions.h" + +class BMessenger; +class BWebPage; + +namespace WebCore { +class AcceleratedCompositingContext; +class ChromeClientHaiku; +class DumpRenderTreeClient; +class Frame; +class FrameLoaderClientHaiku; +class HTMLFrameOwnerElement; +} + +namespace WTF { +class URL; +} + +class WebFramePrivate; + + +class __attribute__ ((visibility ("default"))) BWebFrame { +public: + void SetListener(const BMessenger& listener); + + void LoadURL(BString url); + + void StopLoading(); + void Reload(); + + BString RequestedURL() const; + BString URL() const; + + bool CanCopy() const; + bool CanCut() const; + bool CanPaste() const; + + void Copy(); + void Cut(); + void Paste(); + + bool CanUndo() const; + bool CanRedo() const; + + void Undo(); + void Redo(); + + bool AllowsScrolling() const; + void SetAllowsScrolling(bool enable); + BPoint ScrollPosition(); + + BString FrameSource() const; + void SetFrameSource(const BString& source); + + void SetTransparent(bool transparent); + bool IsTransparent() const; + + BString InnerText() const; + BString AsMarkup() const; + BString ExternalRepresentation() const; + + bool FindString(const BString& string, + WebCore::FindOptions options); + + bool CanIncreaseZoomFactor() const; + bool CanDecreaseZoomFactor() const; + + void IncreaseZoomFactor(bool textOnly); + void DecreaseZoomFactor(bool textOnly); + + void ResetZoomFactor(); + + void SetEditable(bool editable); + bool IsEditable() const; + + void SetTitle(const BString& title); + const BString& Title() const; + + const char* Name() const; +private: + friend class BWebView; + friend class BWebPage; + + friend class WebCore::ChromeClientHaiku; + friend class WebCore::DumpRenderTreeClient; + friend class WebCore::FrameLoaderClientHaiku; + friend class WebCore::AcceleratedCompositingContext; + + BWebFrame(BWebPage* webPage, + BWebFrame* parentFrame, + WebFramePrivate* data); + ~BWebFrame(); + + void LoadURL(WTF::URL); + WebCore::Frame* Frame() const; + + BWebFrame* AddChild(BWebPage* page, BString name, + WebCore::HTMLFrameOwnerElement* ownerElement); + +private: + float fZoomFactor; + bool fIsEditable; + BString fTitle; +mutable BString fName; + + WebFramePrivate* fData; +}; + +#endif // _WEB_FRAME_H_ diff --git a/Source/WebKitLegacy/haiku/API/WebFramePrivate.h b/Source/WebKitLegacy/haiku/API/WebFramePrivate.h new file mode 100644 index 000000000000..ea2c457e0229 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebFramePrivate.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebFramePrivate_h +#define WebFramePrivate_h + +#include +#include + +class BMessenger; +class BWebPage; + +namespace WebCore { +class Frame; +class FrameLoaderClientHaiku; +class HTMLFrameOwnerElement; +class Page; +} + +class WebFramePrivate { +public: + WebFramePrivate() + : ownerElement(nullptr) + , page(nullptr) + , frame(nullptr) + , loaderClient(nullptr) + {} + + bool Init(WebCore::Page* page, BWebFrame* frame, + std::unique_ptr frameLoaderClient); + + + WTF::String name; + WTF::String requestedURL; + WebCore::HTMLFrameOwnerElement* ownerElement; + WebCore::Page* page; + // NOTE: We don't keep a reference pointer for the WebCore::Frame, since + // that will leave us with one too many references, which will in turn + // prevent the shutdown mechanism from working, since that one is only + // triggered from the FrameLoader destructor, i.e. when there are no more + // references around. (FrameLoader and Frame used to be one class, they + // can be considered as one object as far as object life-time goes.) + WebCore::Frame* frame; + std::unique_ptr loaderClient; +}; + +#endif // WebFramePrivate_h diff --git a/Source/WebKitLegacy/haiku/API/WebKitInfo.cpp b/Source/WebKitLegacy/haiku/API/WebKitInfo.cpp new file mode 100644 index 000000000000..fc016c8b2dc7 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebKitInfo.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2012, Alexandre Deckner, alexandre.deckner@uzzl.com. + * Distributed under the terms of the MIT License. + */ + + +#include "WebKitInfo.h" + +#include "WebKitVersion.h" + +#include + + +/*static*/ BString +WebKitInfo::HaikuWebKitVersion() +{ + return HAIKU_WEBKIT_VERSION; +} + + +/*static*/ BString +WebKitInfo::WebKitVersion() +{ + return BString() << WEBKIT_MAJOR_VERSION << "." << WEBKIT_MINOR_VERSION << "." << WEBKIT_TINY_VERSION; +} + + +/*static*/ int +WebKitInfo::WebKitMajorVersion() +{ + return WEBKIT_MAJOR_VERSION; +} + + +/*static*/ int +WebKitInfo::WebKitMinorVersion() +{ + return WEBKIT_MINOR_VERSION; +} + + +/*static*/ int +WebKitInfo::WebKitTinyVersion() +{ + return WEBKIT_TINY_VERSION; +} diff --git a/Source/WebKitLegacy/haiku/API/WebKitInfo.h b/Source/WebKitLegacy/haiku/API/WebKitInfo.h new file mode 100644 index 000000000000..ca7713f90615 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebKitInfo.h @@ -0,0 +1,21 @@ +/* + * Copyright 2012, Alexandre Deckner, alexandre.deckner@uzzl.com. + * Distributed under the terms of the MIT License. + */ +#ifndef WEBKIT_INFO_H_ +#define WEBKIT_INFO_H_ + +#include + + +class __attribute__ ((visibility ("default"))) WebKitInfo { +public: + static BString HaikuWebKitVersion(); + static BString WebKitVersion(); + static int WebKitMajorVersion(); + static int WebKitMinorVersion(); + static int WebKitTinyVersion(); +}; + + +#endif // WEBKIT_INFO_H_ diff --git a/Source/WebKitLegacy/haiku/API/WebPage.cpp b/Source/WebKitLegacy/haiku/API/WebPage.cpp new file mode 100644 index 000000000000..0ba1ff2e3b01 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebPage.cpp @@ -0,0 +1,1469 @@ +/* + * Copyright (C) 2010 Ryan Leavengood + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "config.h" +#include "WebPage.h" + + +#include "BackForwardController.h" +#include "BackForwardList.h" +#include "CacheStorageProvider.h" +#include "Chrome.h" +#include "ChromeClientHaiku.h" +#include "ContextMenu.h" +#include "ContextMenuClientHaiku.h" +#include "ContextMenuController.h" +#include "CookieJar.h" +#include "Cursor.h" +#include "DeviceOrientationClientMock.h" +#include "DiagnosticLoggingClient.h" +#include "DOMTimer.h" +#include "DragClientHaiku.h" +#include "Editor.h" +#include "EditorClientHaiku.h" +#include "EmptyClients.h" +#include "EventHandler.h" +#include "FileChooser.h" +#include "FocusController.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameLoaderClientHaiku.h" +#include "FrameView.h" +#include "GeolocationClientMock.h" +#include "GraphicsContext.h" +#include "IconDatabase.h" +#include "InspectorClientHaiku.h" +#include "LibWebRTCProvider.h" +#include "LogInitialization.h" +#include "MemoryCache.h" +#include "WebNavigatorContentUtilsClient.h" +#include "NotificationClientHaiku.h" +#include "MHTMLArchive.h" +#include "Page.h" +#include "PageCache.h" +#include "PageConfiguration.h" +#include "PageGroup.h" +#include "PageStorageSessionProvider.h" +#include "PlatformKeyboardEvent.h" +#include "PlatformMouseEvent.h" +#include "PlatformStrategiesHaiku.h" +#include "PlatformWheelEvent.h" +#include "PlugInClient.h" +#include "PluginInfoProvider.h" +#include "PointerLockController.h" +#include "ProgressTrackerClient.h" +#include "ProgressTrackerHaiku.h" +#include "ResourceHandle.h" +#include "ResourceRequest.h" +#include "ScriptController.h" +#include "Settings.h" +#include "SocketProvider.h" +#include "TextEncoding.h" +#include "UserContentController.h" +#include "WebApplicationCache.h" +#include "WebDatabaseProvider.h" +#include "WebDiagnosticLoggingClient.h" +#include "WebDownload.h" +#include "WebDownloadPrivate.h" +#include "WebFrame.h" +#include "WebFramePrivate.h" +#include "WebSettings.h" +#include "WebStorageNamespaceProvider.h" +#include "WebView.h" +#include "WebViewConstants.h" +#include "WebViewGroup.h" +#include "WebVisitedLinkStore.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* + The basic idea here is to dispatch all public methods to the BLooper + to which the handler is attached (should be the be_app), such that + the calls into WebCore code happen from within that thread *only*. + In current WebCore with pthread threading backend, this must be the + same thread that called WTF::initializeThreading(), respectively the + initializeOnce() method of this class. + */ + +enum { + HANDLE_SHUTDOWN = 'sdwn', + + HANDLE_LOAD_URL = 'lurl', + HANDLE_RELOAD = 'reld', + HANDLE_GO_BACK = 'back', + HANDLE_GO_FORWARD = 'fwrd', + HANDLE_STOP_LOADING = 'stop', + + HANDLE_FOCUSED = 'focs', + HANDLE_ACTIVATED = 'actd', + + HANDLE_SET_VISIBLE = 'vsbl', + HANDLE_DRAW = 'draw', + HANDLE_FRAME_RESIZED = 'rszd', + + HANDLE_CHANGE_ZOOM_FACTOR = 'zmfr', + HANDLE_FIND_STRING = 'find', + + HANDLE_SET_STATUS_MESSAGE = 'stsm', + HANDLE_RESEND_NOTIFICATIONS = 'rsnt', + HANDLE_SEND_EDITING_CAPABILITIES = 'sedc', + HANDLE_SEND_PAGE_SOURCE = 'spsc' +}; + +using namespace WebCore; + +class EmptyPluginInfoProvider final : public PluginInfoProvider { + void refreshPlugins() final { }; + Vector pluginInfo(Page&, WTF::Optional>&) final { return { }; } + Vector webVisiblePluginInfo(Page&, const URL&) final { return { }; } +}; + +BMessenger BWebPage::sDownloadListener; + +/*static*/ void BWebPage::InitializeOnce() +{ + // NOTE: This needs to be called when the BApplication is ready. + // It won't work as static initialization. +#if !LOG_DISABLED + WebCore::initializeLogChannelsIfNecessary(); +#endif + PlatformStrategiesHaiku::initialize(); + +#if USE(GCRYPT) + // Call gcry_check_version() before any other libgcrypt call, ignoring the + // returned version string. + gcry_check_version(nullptr); + + // Pre-allocate 16kB of secure memory and finish the initialization. + gcry_control(GCRYCTL_INIT_SECMEM, 16384, nullptr); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, nullptr); +#endif + + ScriptController::initializeThreading(); + WTF::initializeMainThread(); + WTF::AtomicString::init(); + WebCore::UTF8Encoding(); + + WebVisitedLinkStore::setShouldTrackVisitedLinks(true); + + RunLoop::initializeMainRunLoop(); + RunLoop::run(); // This attaches it to the existing be_app looper +} + +/*static*/ void BWebPage::ShutdownOnce() +{ + WebKit::iconDatabase().close(); +} + +/*static*/ void BWebPage::SetCacheModel(BWebKitCacheModel model) +{ + // FIXME: Add disk cache handling when CURL has the API + uint32 cacheTotalCapacity; + uint32 cacheMinDeadCapacity; + uint32 cacheMaxDeadCapacity; + WTF::Seconds deadDecodedDataDeletionInterval; + uint32 pageCacheCapacity; + + switch (model) { + case B_WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER: + pageCacheCapacity = 0; + cacheTotalCapacity = 0; + cacheMinDeadCapacity = 0; + cacheMaxDeadCapacity = 0; + deadDecodedDataDeletionInterval = WTF::Seconds(0); + break; + case B_WEBKIT_CACHE_MODEL_WEB_BROWSER: + pageCacheCapacity = 3; + cacheTotalCapacity = 32 * 1024 * 1024; + cacheMinDeadCapacity = cacheTotalCapacity / 4; + cacheMaxDeadCapacity = cacheTotalCapacity / 2; + deadDecodedDataDeletionInterval = WTF::Seconds(60); + break; + default: + return; + } + + MemoryCache::singleton().setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); + MemoryCache::singleton().setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); + PageCache::singleton().setMaxSize(pageCacheCapacity); +} + +BWebPage::BWebPage(BWebView* webView, BUrlContext* context) + : BHandler("BWebPage") + , fWebView(webView) + , fMainFrame(NULL) + , fSettings(NULL) + , fContext(context) + , fPage(NULL) + , fDumpRenderTree(NULL) + , fLoadingProgress(100) + , fStatusMessage() + , fDisplayedStatusMessage() + , fPageVisible(true) + , fPageDirty(false) + , fToolbarsVisible(true) + , fStatusbarVisible(true) + , fMenubarVisible(true) +{ + fProgressTracker = new ProgressTrackerClientHaiku(this); + + // FIXME we should get this from the page settings, but they are created + // after the page, and we need this before the page is created. + BPath storagePath; + find_directory(B_USER_SETTINGS_DIRECTORY, &storagePath); + + storagePath.Append("WebKit/LocalStorage"); + + RefPtr viewGroup = WebViewGroup::getOrCreate("default", + storagePath.Path()); + + auto storageProvider = PageStorageSessionProvider::create(); + PageConfiguration pageClients( + makeUniqueRef(this), + SocketProvider::create(), + makeUniqueRef(), + CacheStorageProvider::create(), + BackForwardList::create(), CookieJar::create(storageProvider.copyRef())); + + // alternativeText + pageClients.chromeClient = new ChromeClientHaiku(this, webView); + pageClients.contextMenuClient = new ContextMenuClientHaiku(this); + pageClients.dragClient = new DragClientHaiku(webView); + pageClients.inspectorClient = new InspectorClientHaiku(); + pageClients.loaderClientForMainFrame = new FrameLoaderClientHaiku(this); + pageClients.progressTrackerClient = fProgressTracker; + pageClients.diagnosticLoggingClient = std::make_unique(); + pageClients.applicationCacheStorage = &WebApplicationCache::storage(); + pageClients.databaseProvider = &WebDatabaseProvider::singleton(); + // performanceLogging + // pluginInClient + pageClients.pluginInfoProvider = adoptRef(*new EmptyPluginInfoProvider); + pageClients.storageNamespaceProvider = &viewGroup->storageNamespaceProvider(); + pageClients.userContentProvider = &viewGroup->userContentController(); + // validationMessage * + pageClients.visitedLinkStore = &viewGroup->visitedLinkStore(); + // webGLStateTracker * + + fPage = new Page(WTFMove(pageClients)); + storageProvider->setPage(*fPage); + +#if ENABLE(GEOLOCATION) + WebCore::provideGeolocationTo(fPage, new GeolocationClientMock()); +#endif +#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) + WebCore::provideNotification(fPage, new NotificationClientHaiku(this)); +#endif +#if ENABLE(DEVICE_ORIENTATION) + // No actual support, we only want to get the html5test points... + WebCore::provideDeviceOrientationTo(fPage, new DeviceOrientationClientMock()); +#endif +#if ENABLE(MEDIA_STREAM) + WebCore::provideUserMediaTo(fPage, new WebUserMediaClient(this)); +#endif +#if ENABLE(NAVIGATOR_CONTENT_UTILS) + WebCore::provideNavigatorContentUtilsTo(fPage, + std::make_unique()); +#endif + +#if ENABLE(REMOTE_INSPECTOR) + fPage->setRemoteInspectionAllowed(true); +#endif + + fSettings = new BWebSettings(&fPage->settings()); +} + +BWebPage::~BWebPage() +{ + // We need to make sure there are no more timers running, since those + // arrive to a different, global handler (the timer handler), and the + // timer functions would then operate on stale pointers. + // Calling detachFromParent() on the FrameLoader will recursively detach + // all child frames, as well as stop all loaders before doing that. + if (fMainFrame && fMainFrame->Frame()) + fMainFrame->Frame()->loader().detachFromParent(); + + // NOTE: The m_webFrame member will be deleted by the + // FrameLoaderClientHaiku, when the WebCore::Frame/FrameLoader instance is + // free'd. For sub-frames, we don't maintain them anyway, and for the + // main frame, the same mechanism is used. + delete fSettings; + delete fPage; +} + +// #pragma mark - public + +void BWebPage::Init() +{ + WebFramePrivate* data = new WebFramePrivate; + data->page = fPage; + + fMainFrame = new BWebFrame(this, 0, data); +} + +void BWebPage::Shutdown() +{ + Looper()->PostMessage(HANDLE_SHUTDOWN, this); +} + +void BWebPage::SetListener(const BMessenger& listener) +{ + fListener = listener; + fMainFrame->SetListener(listener); + fProgressTracker->setDispatchTarget(listener); +} + +void BWebPage::SetDownloadListener(const BMessenger& listener) +{ + sDownloadListener = listener; +} + +BUrlContext* BWebPage::GetContext() +{ + return fContext; +} + +void BWebPage::LoadURL(const char* urlString) +{ + BMessage message(HANDLE_LOAD_URL); + message.AddString("url", urlString); + Looper()->PostMessage(&message, this); +} + +void BWebPage::Reload() +{ + Looper()->PostMessage(HANDLE_RELOAD, this); +} + +void BWebPage::GoBack() +{ + Looper()->PostMessage(HANDLE_GO_BACK, this); +} + +void BWebPage::GoForward() +{ + Looper()->PostMessage(HANDLE_GO_FORWARD, this); +} + +void BWebPage::StopLoading() +{ + Looper()->PostMessage(HANDLE_STOP_LOADING, this); +} + +void BWebPage::ChangeZoomFactor(float increment, bool textOnly) +{ + BMessage message(HANDLE_CHANGE_ZOOM_FACTOR); + message.AddFloat("increment", increment); + message.AddBool("text only", textOnly); + Looper()->PostMessage(&message, this); +} + +void BWebPage::FindString(const char* string, bool forward, bool caseSensitive, + bool wrapSelection, bool startInSelection) +{ + BMessage message(HANDLE_FIND_STRING); + message.AddString("string", string); + message.AddBool("forward", forward); + message.AddBool("case sensitive", caseSensitive); + message.AddBool("wrap selection", wrapSelection); + message.AddBool("start in selection", startInSelection); + Looper()->PostMessage(&message, this); +} + +void BWebPage::SetDeveloperExtrasEnabled(bool enable) +{ + page()->settings().setDeveloperExtrasEnabled(enable); +} + +void BWebPage::SetStatusMessage(const BString& status) +{ + BMessage message(HANDLE_SET_STATUS_MESSAGE); + message.AddString("string", status); + Looper()->PostMessage(&message, this); +} + +void BWebPage::ResendNotifications() +{ + Looper()->PostMessage(HANDLE_RESEND_NOTIFICATIONS, this); +} + +void BWebPage::SendEditingCapabilities() +{ + Looper()->PostMessage(HANDLE_SEND_EDITING_CAPABILITIES, this); +} + +void BWebPage::SendPageSource() +{ + Looper()->PostMessage(HANDLE_SEND_PAGE_SOURCE, this); +} + +void BWebPage::RequestDownload(const BString& url) +{ + ResourceRequest request(url); + requestDownload(request, false); +} + +BWebFrame* BWebPage::MainFrame() const +{ + return fMainFrame; +}; + +BWebSettings* BWebPage::Settings() const +{ + return fSettings; +}; + +BWebView* BWebPage::WebView() const +{ + return fWebView; +} + +BString BWebPage::MainFrameTitle() const +{ + return fMainFrame->Title(); +} + +BString BWebPage::MainFrameRequestedURL() const +{ + return fMainFrame->RequestedURL(); +} + +BString BWebPage::MainFrameURL() const +{ + return fMainFrame->URL(); +} + +status_t BWebPage::GetContentsAsMHTML(BDataIO& output) +{ + RefPtr buffer = MHTMLArchive::generateMHTMLData(fPage); + ssize_t size = output.Write(buffer->data(), buffer->size()); + if (size < 0) + return size; + if ((size_t)size == buffer->size()) + return B_OK; + return B_ERROR; +} + +// #pragma mark - BWebView API + +void BWebPage::setVisible(bool visible) +{ + BMessage message(HANDLE_SET_VISIBLE); + message.AddBool("visible", visible); + Looper()->PostMessage(&message, this); +} + +void BWebPage::draw(const BRect& updateRect) +{ + BMessage message(HANDLE_DRAW); + message.AddPointer("target", this); + message.AddRect("update rect", updateRect); + Looper()->PostMessage(&message, this); +} + +void BWebPage::frameResized(float width, float height) +{ + BMessage message(HANDLE_FRAME_RESIZED); + message.AddPointer("target", this); + message.AddFloat("width", width); + message.AddFloat("height", height); + Looper()->PostMessage(&message, this); +} + +void BWebPage::focused(bool focused) +{ + BMessage message(HANDLE_FOCUSED); + message.AddBool("focused", focused); + Looper()->PostMessage(&message, this); +} + +void BWebPage::activated(bool activated) +{ + BMessage message(HANDLE_ACTIVATED); + message.AddBool("activated", activated); + Looper()->PostMessage(&message, this); +} + +void BWebPage::mouseEvent(const BMessage* message, + const BPoint& /*where*/, const BPoint& /*screenWhere*/) +{ + BMessage copiedMessage(*message); + copiedMessage.AddPointer("target", this); + Looper()->PostMessage(&copiedMessage, this); +} + +void BWebPage::mouseWheelChanged(const BMessage* message, + const BPoint& where, const BPoint& screenWhere) +{ + BMessage copiedMessage(*message); + copiedMessage.AddPoint("be:view_where", where); + copiedMessage.AddPoint("screen_where", screenWhere); + copiedMessage.AddInt32("modifiers", modifiers()); + Looper()->PostMessage(&copiedMessage, this); +} + +void BWebPage::keyEvent(const BMessage* message) +{ + BMessage copiedMessage(*message); + Looper()->PostMessage(&copiedMessage, this); +} + +void BWebPage::standardShortcut(const BMessage* message) +{ + // Simulate a B_KEY_DOWN event. The message is not complete, + // but enough to trigger short cut generation in EditorClientHaiku. + const char* bytes = 0; + switch (message->what) { + case B_SELECT_ALL: + bytes = "a"; + break; + case B_CUT: + bytes = "x"; + break; + case B_COPY: + bytes = "c"; + break; + case B_PASTE: + bytes = "v"; + break; + case B_UNDO: + bytes = "z"; + break; + case B_REDO: + bytes = "Z"; + break; + } + BMessage keyDownMessage(B_KEY_DOWN); + keyDownMessage.AddInt32("modifiers", modifiers() | B_COMMAND_KEY); + keyDownMessage.AddString("bytes", bytes); + keyDownMessage.AddInt64("when", system_time()); + Looper()->PostMessage(&keyDownMessage, this); +} + + +// #pragma mark - WebCoreSupport methods + +WebCore::Page* BWebPage::page() const +{ + return fPage; +} + +WebCore::Page* BWebPage::createNewPage(BRect frame, bool modalDialog, + bool resizable, bool activate) +{ + // Creating the BWebView in the application thread is exactly what we need anyway. + BWebView* view = new BWebView("web view"); + BWebPage* page = view->WebPage(); + + BMessage message(NEW_PAGE_CREATED); + message.AddPointer("view", view); + if (frame.IsValid()) + message.AddRect("frame", frame); + message.AddBool("modal", modalDialog); + message.AddBool("resizable", resizable); + message.AddBool("activate", activate); + + // Block until some window has embedded this view. + BMessage reply; + fListener.SendMessage(&message, &reply); + + return page->page(); +} + +BRect BWebPage::windowFrame() +{ + BRect frame; + if (fWebView->LockLooper()) { + frame = fWebView->Window()->Frame(); + fWebView->UnlockLooper(); + } + return frame; +} + +BRect BWebPage::windowBounds() +{ + return windowFrame().OffsetToSelf(B_ORIGIN); +} + +void BWebPage::setWindowBounds(const BRect& bounds) +{ + BMessage message(RESIZING_REQUESTED); + message.AddRect("rect", bounds); + BMessenger windowMessenger(fWebView->Window()); + if (windowMessenger.IsValid()) { + // Better make this synchronous, since I don't know if it is + // perhaps meant to be (called from ChromeClientHaiku::setWindowRect()). + BMessage reply; + windowMessenger.SendMessage(&message, &reply); + } +} + +BRect BWebPage::viewBounds() +{ + BRect bounds; + if (fWebView->LockLooper()) { + bounds = fWebView->Bounds(); + fWebView->UnlockLooper(); + } + return bounds; +} + +void BWebPage::setViewBounds(const BRect& /*bounds*/) +{ + if (fWebView->LockLooper()) { + // TODO: Implement this with layout management, i.e. SetExplicitMinSize() or something... + fWebView->UnlockLooper(); + } +} + +void BWebPage::setToolbarsVisible(bool flag) +{ + fToolbarsVisible = flag; + + BMessage message(TOOLBARS_VISIBILITY); + message.AddBool("flag", flag); + dispatchMessage(message); +} + +void BWebPage::setStatusbarVisible(bool flag) +{ + fStatusbarVisible = flag; + + BMessage message(STATUSBAR_VISIBILITY); + message.AddBool("flag", flag); + dispatchMessage(message); +} + +void BWebPage::setMenubarVisible(bool flag) +{ + fMenubarVisible = flag; + + BMessage message(MENUBAR_VISIBILITY); + message.AddBool("flag", flag); + dispatchMessage(message); +} + +void BWebPage::setResizable(bool flag) +{ + BMessage message(SET_RESIZABLE); + message.AddBool("flag", flag); + dispatchMessage(message); +} + +void BWebPage::closeWindow() +{ + BMessage message(CLOSE_WINDOW_REQUESTED); + dispatchMessage(message); +} + +void BWebPage::linkHovered(const BString& url, const BString& /*title*/, const BString& /*content*/) +{ + if (url.Length()) + setDisplayedStatusMessage(url); + else + setDisplayedStatusMessage(fStatusMessage); +} + +void BWebPage::requestDownload(const WebCore::ResourceRequest& request, + bool isAsynchronousRequest) +{ + BWebDownload* download = new BWebDownload(new BPrivate::WebDownloadPrivate( + request, MainFrame()->Frame()->loader().networkingContext())); + downloadCreated(download, isAsynchronousRequest); +} + +/*static*/ void BWebPage::downloadCreated(BWebDownload* download, + bool isAsynchronousRequest) +{ + if (sDownloadListener.IsValid()) { + BMessage message(B_DOWNLOAD_ADDED); + message.AddPointer("download", download); + if (isAsynchronousRequest) { + // Block until the listener has pulled all the information... + BMessage reply; + sDownloadListener.SendMessage(&message, &reply); + } else { + sDownloadListener.SendMessage(&message); + } + } else { + BPath desktopPath; + find_directory(B_DESKTOP_DIRECTORY, &desktopPath); + download->Start(desktopPath); + } +} + +void BWebPage::paint(BRect rect, bool immediate) +{ + if (!rect.IsValid()) + return; + // Block any drawing as long as the BWebView is hidden + // (should be extended to when the containing BWebWindow is not + // currently on screen either...) + if (!fPageVisible) { + fPageDirty = true; + return; + } + + // NOTE: fMainFrame can be 0 because init() eventually ends up calling + // paint()! BWebFrame seems to cause an initial page to be loaded, maybe + // this ought to be avoided also for start-up speed reasons! + if (!fMainFrame) + return; + WebCore::Frame* frame = fMainFrame->Frame(); + WebCore::FrameView* view = frame->view(); + + if (!view || !frame->contentRenderer()) + return; + view->updateLayoutAndStyleIfNeededRecursive(); + + if (!fWebView->LockLooper()) + return; + BView* offscreenView = fWebView->OffscreenView(); + + // Lock the offscreen bitmap while we still have the + // window locked. This cannot deadlock and makes sure + // the window is not deleting the offscreen view right + // after we unlock it and before locking the bitmap. + if (offscreenView == NULL || !offscreenView->LockLooper()) { + fWebView->UnlockLooper(); + return; + } + + // FIXME workaround for sometimes badly calculated update rectangle somewhere + // in WebCore. In some cases we get asked to redraw only a small part of the + // page, instead of everything. + //rect = fWebView->Bounds(); + + fWebView->UnlockLooper(); + + BRegion region(rect); + internalPaint(offscreenView, view, ®ion); + MainFrame()->Frame()->view()->flushCompositingStateIncludingSubframes(); + + offscreenView->Sync(); + offscreenView->UnlockLooper(); + + // Notify the window that it can now pull the bitmap in its own thread + fWebView->SetOffscreenViewClean(rect, immediate); + + fPageDirty = false; +} + + +void BWebPage::internalPaint(BView* offscreenView, + WebCore::FrameView* frameView, BRegion* dirty) +{ + ASSERT(!frameView->needsLayout()); + + offscreenView->PushState(); + offscreenView->ConstrainClippingRegion(dirty); + + WebCore::GraphicsContext context(offscreenView); + frameView->paint(context, IntRect(dirty->Frame())); + + offscreenView->PopState(); +} + + +void BWebPage::scroll(int xOffset, int yOffset, const BRect& rectToScroll, + const BRect& clipRect) +{ + if (!rectToScroll.IsValid() || !clipRect.IsValid() + || (xOffset == 0 && yOffset == 0) || !fWebView->LockLooper()) { + return; + } + + BBitmap* bitmap = fWebView->OffscreenBitmap(); + BView* offscreenView = fWebView->OffscreenView(); + + // Lock the offscreen bitmap while we still have the + // window locked. This cannot deadlock and makes sure + // the window is not deleting the offscreen view right + // after we unlock it and before locking the bitmap. + if (!bitmap->Lock()) { + fWebView->UnlockLooper(); + return; + } + fWebView->UnlockLooper(); + + BRect clip = offscreenView->Bounds(); + if (clipRect.IsValid()) + clip = clip & clipRect; + + BRect rectAtSrc = rectToScroll; + BRect rectAtDst = rectAtSrc.OffsetByCopy(xOffset, yOffset); + + // remember the part that will be clean + BRegion repaintRegion(rectAtSrc); + repaintRegion.Exclude(rectAtDst); + BRegion clipRegion(clip); + repaintRegion.IntersectWith(&clipRegion); + + if (clip.Intersects(rectAtSrc) && clip.Intersects(rectAtDst)) { + // clip source rect + rectAtSrc = rectAtSrc & clip; + // clip dest rect + rectAtDst = rectAtDst & clip; + + // move dest back over source and clip source to dest + rectAtDst.OffsetBy(-xOffset, -yOffset); + rectAtSrc = rectAtSrc & rectAtDst; + rectAtDst.OffsetBy(xOffset, yOffset); + + offscreenView->CopyBits(rectAtSrc, rectAtDst); + } + + if (repaintRegion.Frame().IsValid()) { + WebCore::Frame* frame = fMainFrame->Frame(); + WebCore::FrameView* view = frame->view(); + + internalPaint(offscreenView, view, &repaintRegion); + } + + offscreenView->Sync(); + bitmap->Unlock(); +} + + +void BWebPage::setLoadingProgress(float progress) +{ + fLoadingProgress = progress; + + BMessage message(LOAD_PROGRESS); + message.AddFloat("progress", progress); + dispatchMessage(message); +} + +void BWebPage::setStatusMessage(const BString& statusMessage) +{ + if (fStatusMessage == statusMessage) + return; + + fStatusMessage = statusMessage; + + setDisplayedStatusMessage(statusMessage); +} + +void BWebPage::setDisplayedStatusMessage(const BString& statusMessage, bool force) +{ + if (fDisplayedStatusMessage == statusMessage && !force) + return; + + fDisplayedStatusMessage = statusMessage; + + BMessage message(SET_STATUS_TEXT); + message.AddString("text", statusMessage); + dispatchMessage(message); +} + + +void BWebPage::runJavaScriptAlert(const BString& text) +{ + BMessage message(SHOW_JS_ALERT); + message.AddString("text", text); + dispatchMessage(message); +} + + +bool BWebPage::runJavaScriptConfirm(const BString& text) +{ + BMessage message(SHOW_JS_CONFIRM); + message.AddString("text", text); + BMessage reply; + dispatchMessage(message, &reply); + + return reply.FindBool("result"); +} + + +void BWebPage::addMessageToConsole(const BString& source, int lineNumber, + int columnNumber, const BString& text) +{ + BMessage message(ADD_CONSOLE_MESSAGE); + message.AddString("source", source); + message.AddInt32("line", lineNumber); + message.AddInt32("column", columnNumber); + message.AddString("string", text); + dispatchMessage(message); +} + + + +// #pragma mark - private + +void BWebPage::MessageReceived(BMessage* message) +{ + switch (message->what) { + case HANDLE_SHUTDOWN: + // NOTE: This message never arrives here when the BApplication is already + // processing B_QUIT_REQUESTED. Then the view will be detached and instruct + // the BWebPage handler to shut itself down, but BApplication will not + // process additional messages. That's why the windows containing WebViews + // are detaching the views already in their QuitRequested() hooks and + // LauncherApp calls these hooks already in its own QuitRequested() hook. + Looper()->RemoveHandler(this); + delete this; + // TOAST! + return; + case HANDLE_LOAD_URL: + handleLoadURL(message); + break; + case HANDLE_RELOAD: + handleReload(message); + break; + case HANDLE_GO_BACK: + handleGoBack(message); + break; + case HANDLE_GO_FORWARD: + handleGoForward(message); + break; + case HANDLE_STOP_LOADING: + handleStop(message); + break; + + case HANDLE_SET_VISIBLE: + handleSetVisible(message); + break; + + case HANDLE_DRAW: { + bool first = true; + BMessageQueue* queue = Looper()->MessageQueue(); + BRect updateRect; + message->FindRect("update rect", &updateRect); + int32 index = 0; + while (BMessage* nextMessage = queue->FindMessage(message->what, index)) { + BHandler* target = 0; + nextMessage->FindPointer("target", reinterpret_cast(&target)); + if (target != this) { + index++; + continue; + } + + if (!first) { + delete message; + first = false; + } + + message = nextMessage; + queue->RemoveMessage(message); + + BRect rect; + message->FindRect("update rect", &rect); + updateRect = updateRect | rect; + } + paint(updateRect, false); + break; + } + case HANDLE_FRAME_RESIZED: + skipToLastMessage(message); + handleFrameResized(message); + break; + + case HANDLE_FOCUSED: + handleFocused(message); + break; + case HANDLE_ACTIVATED: + handleActivated(message); + break; + + case B_MOUSE_MOVED: + skipToLastMessage(message); + // fall through + case B_MOUSE_DOWN: + case B_MOUSE_UP: + handleMouseEvent(message); + break; + case B_MOUSE_WHEEL_CHANGED: + handleMouseWheelChanged(message); + break; + case B_KEY_DOWN: + case B_KEY_UP: + handleKeyEvent(message); + break; + + case HANDLE_CHANGE_ZOOM_FACTOR: + handleChangeZoomFactor(message); + break; + case HANDLE_FIND_STRING: + handleFindString(message); + break; + + case HANDLE_SET_STATUS_MESSAGE: { + BString status; + if (message->FindString("string", &status) == B_OK) + setStatusMessage(status); + break; + } + + case HANDLE_RESEND_NOTIFICATIONS: + handleResendNotifications(message); + break; + case HANDLE_SEND_EDITING_CAPABILITIES: + handleSendEditingCapabilities(message); + break; + case HANDLE_SEND_PAGE_SOURCE: + handleSendPageSource(message); + break; + + case B_REFS_RECEIVED: { + FileChooser* chooser; + if (message->FindPointer("chooser", reinterpret_cast(&chooser)) == B_OK) { + entry_ref ref; + BPath path; + Vector filenames; + for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { + path.SetTo(&ref); + filenames.append(String(path.Path())); + } + chooser->chooseFiles(filenames); + } + break; + } + case B_CANCEL: { + int32 oldWhat; + BFilePanel* panel; + if (message->FindPointer("source", reinterpret_cast(&panel)) == B_OK + && message->FindInt32("old_what", &oldWhat) == B_OK + && oldWhat == B_REFS_RECEIVED) { + + // Remember the directory so we can reuse it next time we open a + // file panel + entry_ref panelDirectory; + panel->GetPanelDirectory(&panelDirectory); + static_cast(fPage->chrome().client()) + .setPanelDirectory(panelDirectory); + + // Delete the panel, it can't be reused because we can switch + // between multi- and single-file modes. + delete panel; + } + break; + } + + default: + BHandler::MessageReceived(message); + } +} + +void BWebPage::skipToLastMessage(BMessage*& message) +{ + // NOTE: All messages that are fast-forwarded like this + // need to be flagged with the intended target BWebPage, + // or else we steal or process messages intended for another + // BWebPage here! + bool first = true; + BMessageQueue* queue = Looper()->MessageQueue(); + int32 index = 0; + while (BMessage* nextMessage = queue->FindMessage(message->what, index)) { + BHandler* target = 0; + nextMessage->FindPointer("target", reinterpret_cast(&target)); + if (target != this) { + index++; + continue; + } + if (!first) + delete message; + message = nextMessage; + queue->RemoveMessage(message); + first = false; + } +} + +void BWebPage::handleLoadURL(const BMessage* message) +{ + const char* urlString; + if (message->FindString("url", &urlString) != B_OK) + return; + + fMainFrame->LoadURL(urlString); +} + +void BWebPage::handleReload(const BMessage*) +{ + fMainFrame->Reload(); +} + +void BWebPage::handleGoBack(const BMessage*) +{ + fPage->backForward().goBack(); +} + +void BWebPage::handleGoForward(const BMessage*) +{ + fPage->backForward().goForward(); +} + +void BWebPage::handleStop(const BMessage*) +{ + fMainFrame->StopLoading(); +} + +void BWebPage::handleSetVisible(const BMessage* message) +{ + message->FindBool("visible", &fPageVisible); + if (fMainFrame->Frame()->view()) + fMainFrame->Frame()->view()->setParentVisible(fPageVisible); + // Trigger an internal repaint if the page was supposed to be repainted + // while it was invisible. + if (fPageVisible && fPageDirty) + paint(viewBounds(), false); +} + +void BWebPage::handleFrameResized(const BMessage* message) +{ + float width; + float height; + message->FindFloat("width", &width); + message->FindFloat("height", &height); + + WebCore::Frame* frame = fMainFrame->Frame(); + frame->view()->resize(width + 1, height + 1); + frame->view()->forceLayout(); + frame->view()->adjustViewSize(); +} + +void BWebPage::handleFocused(const BMessage* message) +{ + bool focused; + message->FindBool("focused", &focused); + + FocusController& focusController = fPage->focusController(); + focusController.setFocused(focused); + if (focused && !focusController.focusedFrame()) + focusController.setFocusedFrame(fMainFrame->Frame()); +} + +void BWebPage::handleActivated(const BMessage* message) +{ + bool activated; + message->FindBool("activated", &activated); + + FocusController& focusController = fPage->focusController(); + focusController.setActive(activated); +} + + +static BPopUpMenu* +createPlatformContextMenu(ContextMenu& contents) +{ + const Vector& items = contents.items(); + BPopUpMenu* menu = new BPopUpMenu("ContextMenu"); + + for (auto& item: items) { + BMessage* message = new BMessage(item.action()); + message->AddPointer("ContextMenuItem", &item); + BMenuItem* native = nullptr; + if (item.type() == SeparatorType) + { + native = new BSeparatorItem(message); + } else { + native = new BMenuItem(item.title().utf8().data(), message); + native->SetEnabled(item.enabled()); + native->SetMarked(item.checked()); + } + + if (native) { + menu->AddItem(native); + } else { + delete message; + } + } + + return menu; +} + + +void BWebPage::handleMouseEvent(const BMessage* message) +{ + WebCore::Frame* frame = fMainFrame->Frame(); + if (!frame->view() || !frame->document()) + return; + + PlatformMouseEvent event(message); + switch (message->what) { + case B_MOUSE_DOWN: +#if ENABLE(POINTER_LOCK) + if (WebView()->EventMask() & B_POINTER_EVENTS) + { + // We are in mouse lock mode. Events are redirected to pointer lock. + page()->pointerLockController().dispatchLockedMouseEvent(event, + eventNames().mousedownEvent); + break; + } +#endif + + // Handle context menus, if necessary. + if (event.button() == RightButton) { + fPage->contextMenuController().clearContextMenu(); + + WebCore::Frame& focusedFrame = fPage->focusController().focusedOrMainFrame(); + if (!focusedFrame.eventHandler().sendContextMenuEvent(event)) { + // event is swallowed. + return; + } + // If the web page implements it's own context menu handling, then + // the contextMenu() pointer will be zero. In this case, we should + // also swallow the event. + ContextMenu* contextMenu = fPage->contextMenuController().contextMenu(); + if (contextMenu) { + BPopUpMenu* platformMenu = createPlatformContextMenu(*contextMenu); + if (platformMenu) { + BPoint screenLocation(event.globalPosition().x() + 2, + event.globalPosition().y() + 2); + BMenuItem* item = platformMenu->Go(screenLocation, false, + true); + if (item) { + BMessage* message = item->Message(); + ContextMenuItem* itemHandle; + message->FindPointer("ContextMenuItem", (void**)&itemHandle); + fPage->contextMenuController().contextMenuItemSelected( + itemHandle->action(), itemHandle->title()); + } + } + } + } + // Handle regular mouse events. + frame->eventHandler().handleMousePressEvent(event); + break; + case B_MOUSE_UP: +#if ENABLE(POINTER_LOCK) + if (WebView()->EventMask() & B_POINTER_EVENTS) + { + // We are in mouse lock mode. Events are redirected to pointer lock. + page()->pointerLockController().dispatchLockedMouseEvent(event, + eventNames().mouseupEvent); + break; + } +#endif + + frame->eventHandler().handleMouseReleaseEvent(event); + break; + case B_MOUSE_MOVED: +#if ENABLE(POINTER_LOCK) + if (WebView()->EventMask() & B_POINTER_EVENTS) + { + // We are in mouse lock mode. Events are redirected to pointer lock. + page()->pointerLockController().dispatchLockedMouseEvent(event, + eventNames().mousemoveEvent); + break; + } +#endif + + default: + frame->eventHandler().mouseMoved(event); + break; + } +} + +void BWebPage::handleMouseWheelChanged(BMessage* message) +{ + WebCore::Frame* frame = fMainFrame->Frame(); + if (!frame->view() || !frame->document()) + return; + + PlatformWheelEvent event(message); + frame->eventHandler().handleWheelEvent(event); +} + +void BWebPage::handleKeyEvent(BMessage* message) +{ + WebCore::Frame& frame = fPage->focusController().focusedOrMainFrame(); + if (!frame.view() || !frame.document()) + return; + + PlatformKeyboardEvent event(message); + // Try to let WebCore handle this event + if (!frame.eventHandler().keyEvent(event) && message->what == B_KEY_DOWN) { + // Handle keyboard scrolling (probably should be extracted to a method.) + ScrollDirection direction; + ScrollGranularity granularity; + BString bytes = message->FindString("bytes"); + switch (bytes.ByteAt(0)) { + case B_UP_ARROW: + granularity = ScrollByLine; + direction = ScrollUp; + break; + case B_DOWN_ARROW: + granularity = ScrollByLine; + direction = ScrollDown; + break; + case B_LEFT_ARROW: + granularity = ScrollByLine; + direction = ScrollLeft; + break; + case B_RIGHT_ARROW: + granularity = ScrollByLine; + direction = ScrollRight; + break; + case B_HOME: + granularity = ScrollByDocument; + direction = ScrollUp; + break; + case B_END: + granularity = ScrollByDocument; + direction = ScrollDown; + break; + case B_PAGE_UP: + granularity = ScrollByPage; + direction = ScrollUp; + break; + case B_PAGE_DOWN: + granularity = ScrollByPage; + direction = ScrollDown; + break; + default: + return; + } + frame.eventHandler().scrollRecursively(direction, granularity); + } +} + +void BWebPage::handleChangeZoomFactor(BMessage* message) +{ + float increment; + if (message->FindFloat("increment", &increment) != B_OK) + increment = 0; + + bool textOnly; + if (message->FindBool("text only", &textOnly) != B_OK) + textOnly = true; + + if (increment > 0) + fMainFrame->IncreaseZoomFactor(textOnly); + else if (increment < 0) + fMainFrame->DecreaseZoomFactor(textOnly); + else + fMainFrame->ResetZoomFactor(); +} + +void BWebPage::handleFindString(BMessage* message) +{ + BMessage reply(B_FIND_STRING_RESULT); + + BString string; + bool forward; + bool caseSensitive; + bool wrapSelection; + bool startInSelection; + if (message->FindString("string", &string) != B_OK + || message->FindBool("forward", &forward) != B_OK + || message->FindBool("case sensitive", &caseSensitive) != B_OK + || message->FindBool("wrap selection", &wrapSelection) != B_OK + || message->FindBool("start in selection", &startInSelection) != B_OK) { + message->SendReply(&reply); + } + + WebCore::FindOptions options; + if (!forward) + options.add(WebCore::Backwards); + if (!caseSensitive) + options.add(WebCore::CaseInsensitive); + if (wrapSelection) + options.add(WebCore::WrapAround); + if (startInSelection) + options.add(WebCore::StartInSelection); + + bool result = fMainFrame->FindString(string, options); + + reply.AddBool("result", result); + message->SendReply(&reply); +} + +void BWebPage::handleResendNotifications(BMessage*) +{ + // Prepare navigation capabilities notification + BMessage message(UPDATE_NAVIGATION_INTERFACE); + message.AddBool("can go backward", fPage->backForward().canGoBackOrForward(-1)); + message.AddBool("can go forward", fPage->backForward().canGoBackOrForward(1)); + WebCore::FrameLoader& loader = fMainFrame->Frame()->loader(); + message.AddBool("can stop", loader.isLoading()); + dispatchMessage(message); + // Send loading progress and status text notifications + setLoadingProgress(fLoadingProgress); + setDisplayedStatusMessage(fStatusMessage, true); + // TODO: Other notifications... +} + +void BWebPage::handleSendEditingCapabilities(BMessage*) +{ + bool canCut = false; + bool canCopy = false; + bool canPaste = false; + + WebCore::Frame& frame = fPage->focusController().focusedOrMainFrame(); + WebCore::Editor& editor = frame.editor(); + + canCut = editor.canCut() || editor.canDHTMLCut(); + canCopy = editor.canCopy() || editor.canDHTMLCopy(); + canPaste = editor.canPaste() || editor.canDHTMLPaste(); + + BMessage message(B_EDITING_CAPABILITIES_RESULT); + message.AddBool("can cut", canCut); + message.AddBool("can copy", canCopy); + message.AddBool("can paste", canPaste); + + dispatchMessage(message); +} + +void BWebPage::handleSendPageSource(BMessage*) +{ + BMessage message(B_PAGE_SOURCE_RESULT); + message.AddString("source", fMainFrame->FrameSource()); + message.AddString("url", fMainFrame->URL()); + + dispatchMessage(message); +} + +// #pragma mark - + +status_t BWebPage::dispatchMessage(BMessage& message, BMessage* reply) const +{ + message.AddPointer("view", fWebView); + if (reply) + return fListener.SendMessage(&message, reply); + else + return fListener.SendMessage(&message); +} + diff --git a/Source/WebKitLegacy/haiku/API/WebPage.h b/Source/WebKitLegacy/haiku/API/WebPage.h new file mode 100644 index 000000000000..245f0fade882 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebPage.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _WEB_PAGE_H +#define _WEB_PAGE_H + +#include +#include +#include +#include + +class BNetworkCookieJar; +class BRegion; +class BUrlContext; +class BView; +class BWebDownload; +class BWebFrame; +class BWebSettings; +class BWebView; + +namespace WebCore { +class ChromeClientHaiku; +class ContextMenuClientHaiku; +class DragClientHaiku; +class DumpRenderTreeClient; +class EditorClientHaiku; +class FrameLoaderClientHaiku; +class InspectorClientHaiku; +class ProgressTrackerClientHaiku; + +class FrameView; +class Page; +class ResourceHandle; +class ResourceRequest; +class ResourceResponse; +}; + +namespace BPrivate { +class WebDownloadPrivate; +}; + +enum { + B_FIND_STRING_RESULT = 'fsrs', + B_DOWNLOAD_ADDED = 'dwna', + B_DOWNLOAD_REMOVED = 'dwnr', + B_EDITING_CAPABILITIES_RESULT = 'cedr', + B_PAGE_SOURCE_RESULT = 'psrc' +}; + +typedef enum { + B_WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER = 0, + B_WEBKIT_CACHE_MODEL_WEB_BROWSER +} BWebKitCacheModel; + +class __attribute__ ((visibility ("default"))) BWebPage : private BHandler { +public: + static void InitializeOnce(); + static void ShutdownOnce(); + static void SetCacheModel(BWebKitCacheModel model); + + void Init(); + void Shutdown(); + + void SetListener(const BMessenger& listener); + static void SetDownloadListener(const BMessenger& listener); + + BWebFrame* MainFrame() const; + BWebSettings* Settings() const; + BWebView* WebView() const; + // NOTE: Using the BWebView requires locking it's looper! + + void LoadURL(const char* urlString); + void Reload(); + void GoBack(); + void GoForward(); + void StopLoading(); + + BString MainFrameTitle() const; + BString MainFrameRequestedURL() const; + BString MainFrameURL() const; + + status_t GetContentsAsMHTML(BDataIO& output); + + void ChangeZoomFactor(float increment, + bool textOnly); + void FindString(const char* string, + bool forward = true, + bool caseSensitive = false, + bool wrapSelection = true, + bool startInSelection = false); + + void SetDeveloperExtrasEnabled(bool enable); + void SetStatusMessage(const BString& status); + void ResendNotifications(); + + void SendEditingCapabilities(); + void SendPageSource(); + + void RequestDownload(const BString& url); + +private: + friend class BWebFrame; + friend class BWebView; + friend class BPrivate::WebDownloadPrivate; + + BWebPage(BWebView* webView, BUrlContext* context); + + // These calls are private, since they are called from the BWebView only. + void setVisible(bool visible); + void draw(const BRect& updateRect); + void frameResized(float width, float height); + void focused(bool focused); + void activated(bool activated); + void mouseEvent(const BMessage* message, const BPoint& where, + const BPoint& screenWhere); + void mouseWheelChanged(const BMessage* message, const BPoint& where, + const BPoint& screenWhere); + void keyEvent(const BMessage* message); + void standardShortcut(const BMessage* message); + + void internalPaint(BView* offscree, WebCore::FrameView*, BRegion*); + void scroll(int scrollDeltaX, int scrollDeltaY, const BRect& rectToScroll, + const BRect& clipRect); + +private: + // The following methods are only supposed to be called by the + // ChromeClientHaiku and FrameLoaderHaiku code! Not from within the window + // thread! This coud go into a private class. + friend class WebCore::ChromeClientHaiku; + friend class WebCore::ContextMenuClientHaiku; + friend class WebCore::DragClientHaiku; + friend class WebCore::DumpRenderTreeClient; + friend class WebCore::EditorClientHaiku; + friend class WebCore::FrameLoaderClientHaiku; + friend class WebCore::ProgressTrackerClientHaiku; + friend class WebCore::InspectorClientHaiku; + + WebCore::Page* page() const; + + WebCore::Page* createNewPage(BRect frame = BRect(), + bool modalDialog = false, bool resizable = true, + bool activate = true); + + BUrlContext* GetContext(); + BRect windowFrame(); + BRect windowBounds(); + void setWindowBounds(const BRect& bounds); + BRect viewBounds(); + void setViewBounds(const BRect& bounds); + + void setToolbarsVisible(bool); + bool areToolbarsVisible() const { return fToolbarsVisible; } + + void setStatusbarVisible(bool); + bool isStatusbarVisible() const { return fStatusbarVisible; } + + void setMenubarVisible(bool); + bool isMenubarVisible() const { return fMenubarVisible; } + + void setResizable(bool); + void closeWindow(); + void linkHovered(const BString&, const BString&, const BString&); + + friend class BWebDownload; + + static void downloadCreated(BWebDownload* download, + bool isAsynchronousRequest); + + void paint(BRect rect, bool immediate); + + void setLoadingProgress(float progress); + void setStatusMessage(const BString& message); + void setDisplayedStatusMessage(const BString& message, bool force = false); + void addMessageToConsole(const BString& source, int lineNumber, + int columnNumber, const BString& message); + void runJavaScriptAlert(const BString& message); + bool runJavaScriptConfirm(const BString& message); + void requestDownload(const WebCore::ResourceRequest& request, + bool isAsynchronousRequest = true); + +private: + virtual ~BWebPage(); + virtual void MessageReceived(BMessage* message); + + void skipToLastMessage(BMessage*& message); + + void handleLoadURL(const BMessage* message); + void handleReload(const BMessage* message); + void handleGoBack(const BMessage* message); + void handleGoForward(const BMessage* message); + void handleStop(const BMessage* message); + void handleSetVisible(const BMessage* message); + void handleFrameResized(const BMessage* message); + void handleFocused(const BMessage* message); + void handleActivated(const BMessage* message); + void handleMouseEvent(const BMessage* message); + void handleMouseWheelChanged(BMessage* message); + void handleKeyEvent(BMessage* message); + void handleChangeZoomFactor(BMessage* message); + void handleFindString(BMessage* message); + void handleResendNotifications(BMessage* message); + void handleSendEditingCapabilities(BMessage* message); + void handleSendPageSource(BMessage* message); + + status_t dispatchMessage(BMessage& message, BMessage* reply = NULL) const; + +private: + BMessenger fListener; + static BMessenger sDownloadListener; + BWebView* fWebView; + BWebFrame* fMainFrame; + BWebSettings* fSettings; + BUrlContext* fContext; + WebCore::Page* fPage; + WebCore::DumpRenderTreeClient* fDumpRenderTree; + WebCore::ProgressTrackerClientHaiku* fProgressTracker; + + float fLoadingProgress; + BString fStatusMessage; + BString fDisplayedStatusMessage; + + bool fPageVisible; + bool fPageDirty; + bool fLayoutingView; + + bool fToolbarsVisible; + bool fStatusbarVisible; + bool fMenubarVisible; +}; + +#endif // _WEB_PAGE_H diff --git a/Source/WebKitLegacy/haiku/API/WebSettings.cpp b/Source/WebKitLegacy/haiku/API/WebSettings.cpp new file mode 100644 index 000000000000..9f6a359d4510 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebSettings.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebSettings.h" + +#include "ApplicationCacheStorage.h" +#include "BitmapImage.h" +#include "DatabaseTracker.h" +#include "FontPlatformData.h" +#include "FrameNetworkingContextHaiku.h" +#include "IconDatabase.h" +#include "Image.h" +#include "IntSize.h" +#include "Settings.h" +#include "WebSettingsPrivate.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + HANDLE_SET_PERSISTENT_STORAGE_PATH = 'hspp', + HANDLE_SET_ICON_DATABASE_PATH = 'hsip', + HANDLE_CLEAR_ICON_DATABASE = 'hcli', + HANDLE_SEND_ICON_FOR_URL = 'sifu', + HANDLE_SET_OFFLINE_STORAGE_PATH = 'hsop', + HANDLE_SET_OFFLINE_STORAGE_DEFAULT_QUOTA = 'hsoq', + HANDLE_SET_OFFLINE_WEB_APPLICATION_CACHE_PATH = 'hsap', + HANDLE_SET_OFFLINE_WEB_APPLICATION_CACHE_QUOTA = 'hsaq', + HANDLE_SET_LOCAL_STORAGE_PATH = 'hslp', + HANDLE_SET_FONT = 'hsfn', + HANDLE_SET_FONT_SIZE = 'hsfs', + HANDLE_SET_PROXY_INFO = 'hspi', + HANDLE_SET_JAVASCRIPT_ENABLED = 'jsen', + HANDLE_APPLY = 'hapl' +}; + +enum { + SERIF_FONT = 0, + SANS_SERIF_FONT, + FIXED_FONT, + STANDARD_FONT, +}; + +enum { + STANDARD_FONT_SIZE = 0, + FIXED_FONT_SIZE, +}; + +BWebSettings::BWebSettings() + : fData(new BPrivate::WebSettingsPrivate()) +{ + // This constructor is used only for the default (global) settings. + if (be_app->Lock()) { + be_app->AddHandler(this); + be_app->Unlock(); + } +} + +BWebSettings::BWebSettings(WebCore::Settings* settings) + : fData(new BPrivate::WebSettingsPrivate(settings)) +{ + if (be_app->Lock()) { + be_app->AddHandler(this); + be_app->Unlock(); + } +} + +BWebSettings::~BWebSettings() +{ + if (be_app->Lock()) { + be_app->RemoveHandler(this); + be_app->Unlock(); + } + delete fData; +} + +BWebSettings* BWebSettings::Default() +{ + static BWebSettings defaultInstance; + return &defaultInstance; +} + +void BWebSettings::SetIconDatabasePath(const BString& path) +{ + _PostSetPath(Default(), HANDLE_SET_ICON_DATABASE_PATH, path); +} + +void BWebSettings::ClearIconDatabase() +{ + Default()->Looper()->PostMessage(HANDLE_CLEAR_ICON_DATABASE, Default()); +} + +void BWebSettings::SendIconForURL(const BString& url, const BMessage& reply, + const BMessenger& target) +{ + BMessage message(HANDLE_SEND_ICON_FOR_URL); + message.AddString("url", url.String()); + message.AddMessage("reply", &reply); + message.AddMessenger("target", target); + Default()->Looper()->PostMessage(&message, Default()); +} + + +void BWebSettings::SetPersistentStoragePath(const BString& path) +{ + _PostSetPath(Default(), HANDLE_SET_PERSISTENT_STORAGE_PATH, path); +} + +void BWebSettings::SetOfflineStoragePath(const BString& path) +{ + _PostSetPath(Default(), HANDLE_SET_OFFLINE_STORAGE_PATH, path); +} + +void BWebSettings::SetOfflineStorageDefaultQuota(int64 maximumSize) +{ + _PostSetQuota(Default(), HANDLE_SET_OFFLINE_STORAGE_DEFAULT_QUOTA, maximumSize); +} + +void BWebSettings::SetOfflineWebApplicationCachePath(const BString& path) +{ + _PostSetPath(Default(), HANDLE_SET_OFFLINE_WEB_APPLICATION_CACHE_PATH, path); +} + +void BWebSettings::SetOfflineWebApplicationCacheQuota(int64 maximumSize) +{ + _PostSetQuota(Default(), HANDLE_SET_OFFLINE_WEB_APPLICATION_CACHE_QUOTA, maximumSize); +} + +void BWebSettings::SetLocalStoragePath(const BString& path) +{ + _PostSetPath(this, HANDLE_SET_LOCAL_STORAGE_PATH, path); +} + +void BWebSettings::SetSerifFont(const BFont& font) +{ + _PostFont(SERIF_FONT, font); +} + +void BWebSettings::SetSansSerifFont(const BFont& font) +{ + _PostFont(SANS_SERIF_FONT, font); +} + +void BWebSettings::SetFixedFont(const BFont& font) +{ + _PostFont(FIXED_FONT, font); +} + +void BWebSettings::SetStandardFont(const BFont& font) +{ + _PostFont(STANDARD_FONT, font); +} + +void BWebSettings::SetDefaultStandardFontSize(float size) +{ + _PostFontSize(STANDARD_FONT_SIZE, size); +} + +void BWebSettings::SetDefaultFixedFontSize(float size) +{ + _PostFontSize(FIXED_FONT_SIZE, size); +} + +void BWebSettings::SetJavascriptEnabled(bool enabled) +{ + BMessage message(HANDLE_SET_JAVASCRIPT_ENABLED); + message.AddBool("enable", enabled); + _PostMessage(Default(), &message); +} + +void BWebSettings::SetProxyInfo(const BString& host, uint32 port, + BProxyType type, const BString& username, const BString& password) +{ + BMessage message(HANDLE_SET_PROXY_INFO); + message.AddString("host", host); + message.AddUInt32("port", port); + message.AddUInt32("type", type); + message.AddString("username", username); + message.AddString("password", password); + _PostMessage(Default(), &message); +} + +void BWebSettings::Apply() +{ + Looper()->PostMessage(HANDLE_APPLY, this); +} + +// #pragma mark - private + +void BWebSettings::_PostSetPath(BHandler* handler, uint32 what, const BString& path) +{ + BMessage message(what); + message.AddString("path", path.String()); + _PostMessage(handler, &message); +} + +void BWebSettings::_PostSetQuota(BHandler* handler, uint32 what, int64 maximumSize) +{ + BMessage message(what); + message.AddInt64("quota", maximumSize); + _PostMessage(handler, &message); +} + +void BWebSettings::_PostFont(uint32 which, const BFont& font) +{ + BMessage message(HANDLE_SET_FONT); + message.AddInt32("which", which); + + font_family family; + font_style style; + font.GetFamilyAndStyle(&family, &style); + BString string(family); +// NOTE: WebCore is not interested in the style here, since it manages styles by itself. +// Only the family is of interest to reference a font. +// string << ' ' << style; + message.AddString("font", string.String()); + + _PostMessage(this, &message); +} + +void BWebSettings::_PostFontSize(uint32 which, float size) +{ + BMessage message(HANDLE_SET_FONT_SIZE); + message.AddInt32("which", which); + message.AddFloat("size", size); + _PostMessage(this, &message); +} + +void BWebSettings::_PostMessage(BHandler* handler, BMessage* message) +{ + if (find_thread(0) == handler->Looper()->Thread()) + handler->MessageReceived(message); + else + handler->Looper()->PostMessage(message, handler); +} + +// #pragma mark - + +void BWebSettings::MessageReceived(BMessage* message) +{ + switch (message->what) { + case HANDLE_SET_PERSISTENT_STORAGE_PATH: { + BString path; + if (message->FindString("path", &path) == B_OK) + _HandleSetPersistentStoragePath(path); + break; + } + case HANDLE_SET_ICON_DATABASE_PATH: { + BString path; + if (message->FindString("path", &path) == B_OK) + _HandleSetIconDatabasePath(path); + break; + } + case HANDLE_CLEAR_ICON_DATABASE: + _HandleClearIconDatabase(); + break; + case HANDLE_SEND_ICON_FOR_URL: { + _HandleSendIconForURL(message); + break; + } + case HANDLE_SET_OFFLINE_STORAGE_PATH: { + BString path; + if (message->FindString("path", &path) == B_OK) + _HandleSetOfflineStoragePath(path); + break; + } + case HANDLE_SET_OFFLINE_STORAGE_DEFAULT_QUOTA: { + int64 maximumSize; + if (message->FindInt64("quota", &maximumSize) == B_OK) + _HandleSetOfflineStorageDefaultQuota(maximumSize); + break; + } + case HANDLE_SET_OFFLINE_WEB_APPLICATION_CACHE_PATH: { + BString path; + if (message->FindString("path", &path) == B_OK) + _HandleSetWebApplicationCachePath(path); + break; + } + case HANDLE_SET_OFFLINE_WEB_APPLICATION_CACHE_QUOTA: { + int64 maximumSize; + if (message->FindInt64("quota", &maximumSize) == B_OK) + _HandleSetWebApplicationCacheQuota(maximumSize); + break; + } + case HANDLE_SET_LOCAL_STORAGE_PATH: { + BString path; + if (message->FindString("path", &path) == B_OK) + _HandleSetLocalStoragePath(path); + break; + } + case HANDLE_SET_FONT: + _HandleSetFont(message); + break; + case HANDLE_SET_FONT_SIZE: + _HandleSetFontSize(message); + break; + + case HANDLE_SET_JAVASCRIPT_ENABLED: + _HandleSetJavascriptEnabled(message->FindBool("enable")); + break; + + case HANDLE_SET_PROXY_INFO: + _HandleSetProxyInfo(message); + break; + + case HANDLE_APPLY: + _HandleApply(); + break; + default: + BHandler::MessageReceived(message); + } +} + +void BWebSettings::_HandleSetPersistentStoragePath(const BString& path) +{ + BPath storagePath; + + if (!path.Length()) + find_directory(B_USER_DATA_DIRECTORY, &storagePath); + else + storagePath.SetTo(path.String()); + + create_directory(storagePath.Path(), 0777); + + _HandleSetIconDatabasePath(storagePath.Path()); + _HandleSetWebApplicationCachePath(storagePath.Path()); + BPath dataBasePath(storagePath); + dataBasePath.Append("Databases"); + _HandleSetOfflineStoragePath(dataBasePath.Path()); + BPath localStoragePath(storagePath); + dataBasePath.Append("LocalStorage"); + Default()->_HandleSetLocalStoragePath(localStoragePath.Path()); + + Default()->fData->localStorageEnabled = true; + Default()->fData->databasesEnabled = true; + Default()->fData->offlineWebApplicationCacheEnabled = true; + Default()->fData->apply(); +} + +void BWebSettings::_HandleSetOfflineStoragePath(const BString& path) +{ +} + +void BWebSettings::_HandleSetOfflineStorageDefaultQuota(int64 maximumSize) +{ + fData->offlineStorageDefaultQuota = maximumSize; +} + +void BWebSettings::_HandleSetWebApplicationCachePath(const BString& path) +{ +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + WebCore::cacheStorage().setCacheDirectory(path); +#endif +} + +void BWebSettings::_HandleSetIconDatabasePath(const BString& path) +{ + WebKit::IconDatabase::delayDatabaseCleanup(); + + if (path.Length()) { + WebKit::iconDatabase().setEnabled(true); + BEntry entry(path.String()); + if (entry.IsDirectory()) + WebKit::iconDatabase().open(path, WebKit::IconDatabase::defaultDatabaseFilename()); + } else { + WebKit::iconDatabase().setEnabled(false); + WebKit::iconDatabase().close(); + } +} + +void BWebSettings::_HandleClearIconDatabase() +{ + if (WebKit::iconDatabase().isEnabled() && WebKit::iconDatabase().isOpen()) + WebKit::iconDatabase().removeAllIcons(); +} + +void BWebSettings::_HandleSendIconForURL(BMessage* message) +{ + BString url; + BMessage reply; + BMessenger target; + if (message->FindString("url", &url) != B_OK + || message->FindMessage("reply", &reply) != B_OK + || message->FindMessenger("target", &target) != B_OK) { + return; + } + + reply.RemoveName("url"); + reply.RemoveName("icon"); + reply.AddString("url", url); + + std::pair icon + = WebKit::iconDatabase().synchronousIconForPageURL(url, WebCore::IntSize(16, 16)); + BMessage iconArchive; + if (icon.second == WebKit::IconDatabase::IsKnownIcon::Yes + && icon.first != NULL && icon.first->Archive(&iconArchive) == B_OK) + reply.AddMessage("icon", &iconArchive); + + target.SendMessage(&reply); +} + + +void BWebSettings::_HandleSetWebApplicationCacheQuota(int64 maximumSize) +{ +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + WebCore::cacheStorage().setMaximumSize(maximumSize); +#endif +} + +void BWebSettings::_HandleSetLocalStoragePath(const BString& path) +{ + if (!fData->settings) + return; + + fData->localStoragePath = path; + fData->apply(); +} + +void BWebSettings::_HandleSetFont(BMessage* message) +{ + int32 which; + if (message->FindInt32("which", &which) != B_OK) + return; + BString font; + if (message->FindString("font", &font) != B_OK) + return; + switch (which) { + case SERIF_FONT: + fData->serifFontFamily = font; + fData->serifFontFamilySet = true; + WebCore::FontPlatformData::SetFallBackSerifFont(font); + break; + case SANS_SERIF_FONT: + fData->sansSerifFontFamily = font; + fData->sansSerifFontFamilySet = true; + WebCore::FontPlatformData::SetFallBackSansSerifFont(font); + break; + case FIXED_FONT: + fData->fixedFontFamily = font; + fData->fixedFontFamilySet = true; + WebCore::FontPlatformData::SetFallBackFixedFont(font); + break; + case STANDARD_FONT: + fData->standardFontFamily = font; + fData->standardFontFamilySet = true; + WebCore::FontPlatformData::SetFallBackStandardFont(font); + break; + } +} + +void BWebSettings::_HandleSetFontSize(BMessage* message) +{ + int32 which; + if (message->FindInt32("which", &which) != B_OK) + return; + float size; + if (message->FindFloat("size", &size) != B_OK) + return; + switch (which) { + case STANDARD_FONT_SIZE: + fData->defaultFontSize = size; + fData->defaultFontSizeSet = true; + break; + case FIXED_FONT_SIZE: + fData->defaultFixedFontSize = size; + fData->defaultFixedFontSizeSet = true; + break; + } +} + + +void BWebSettings::_HandleSetJavascriptEnabled(bool enable) +{ + fData->javascriptEnabled = enable; +} + + +void BWebSettings::_HandleSetProxyInfo(BMessage* message) +{ + BString host; + uint32 port; + BProxyType type; + BString username; + BString password; + if (message->FindString("host", &host) != B_OK + || message->FindUInt32("port", &port) != B_OK + || message->FindUInt32("type", reinterpret_cast(&type)) != B_OK + || message->FindString("username", &username) != B_OK + || message->FindString("password", &password) != B_OK) + return; + + // TODO handle SOCKS proxy and authentication + // TODO there could be a cleaner way of accessing the default context from here. + RefPtr context + = WebCore::FrameNetworkingContextHaiku::create(nullptr, nullptr); + context->context()->SetProxy(host, port); +} + +void BWebSettings::_HandleApply() +{ + fData->apply(); +} diff --git a/Source/WebKitLegacy/haiku/API/WebSettings.h b/Source/WebKitLegacy/haiku/API/WebSettings.h new file mode 100644 index 000000000000..a85e2f566d70 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebSettings.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _WEB_SETTINGS_H_ +#define _WEB_SETTINGS_H_ + +#include +#include + + +class BBitmap; +class BFont; +class BMessenger; +class BWebPage; + +namespace WebCore { +class Settings; +} + +namespace BPrivate { +class WebSettingsPrivate; +} + + +enum BProxyType { + B_PROXY_TYPE_HTTP = 0, + B_PROXY_TYPE_SOCKS4 = 1, + B_PROXY_TYPE_SOCKS4A = 2, + B_PROXY_TYPE_SOCKS5 = 3, + B_PROXY_TYPE_SOCKS5_HOSTNAME = 4 +}; + + +class __attribute__ ((visibility ("default"))) BWebSettings : public BHandler { +// TODO: Inherit from BReferenceable. +public: + static BWebSettings* Default(); + + // This will call all the storage methods below with default paths relative to + // the given path. An empty path will use the default B_USER_DATA_DIRECTORY. + static void SetPersistentStoragePath(const BString& path = BString()); + + static void SetIconDatabasePath(const BString& path); + static void ClearIconDatabase(); + + // This method triggers sending the provided message when the favicon + // for the given URL can be found. + // It is dispatched to the BMessenger provided to SendIconForURL(). + // The icon will be stored as archived BBitmap "icon" in the message, which is + // otherwise a copy of the provided message + static void SendIconForURL(const BString& url, + const BMessage& reply, + const BMessenger& target); + + static void SetOfflineStoragePath(const BString& path); + static void SetOfflineStorageDefaultQuota(int64 maximumSize); + + static void SetOfflineWebApplicationCachePath(const BString& path); + static void SetOfflineWebApplicationCacheQuota(int64 maximumSize); + + void SetLocalStoragePath(const BString& path); + + void SetSerifFont(const BFont& font); + void SetSansSerifFont(const BFont& font); + void SetFixedFont(const BFont& font); + void SetStandardFont(const BFont& font); + + void SetDefaultStandardFontSize(float size); + void SetDefaultFixedFontSize(float size); + + void SetJavascriptEnabled(bool enable); + + static void SetProxyInfo(const BString& host = "", + uint32 port = 0, + BProxyType type = B_PROXY_TYPE_HTTP, + const BString& username = "", + const BString& password = ""); + + void Apply(); + +private: + friend class BWebPage; + friend class BPrivate::WebSettingsPrivate; + + BWebSettings(); + BWebSettings(WebCore::Settings* settings); + virtual ~BWebSettings(); + +private: + static void _PostSetPath(BHandler* handler, uint32 what, const BString& path); + static void _PostSetQuota(BHandler* handler, uint32 what, int64 maximumSize); + void _PostFont(uint32 which, const BFont& font); + void _PostFontSize(uint32 which, float size); + static void _PostMessage(BHandler* handler, BMessage* message); + + virtual void MessageReceived(BMessage* message); + + void _HandleSetPersistentStoragePath(const BString& path); + void _HandleSetIconDatabasePath(const BString& path); + void _HandleClearIconDatabase(); + void _HandleSendIconForURL(BMessage* message); + void _HandleSetOfflineStoragePath(const BString& path); + void _HandleSetOfflineStorageDefaultQuota(int64 maximumSize); + void _HandleSetWebApplicationCachePath(const BString& path); + void _HandleSetWebApplicationCacheQuota(int64 maximumSize); + void _HandleSetLocalStoragePath(const BString& path); + void _HandleSetFont(BMessage* message); + void _HandleSetFontSize(BMessage* message); + void _HandleSetProxyInfo(BMessage* message); + void _HandleSetJavascriptEnabled(bool); + void _HandleApply(); +private: + BPrivate::WebSettingsPrivate* fData; +}; + +#endif // _WEB_SETTINGS_H_ diff --git a/Source/WebKitLegacy/haiku/API/WebSettingsPrivate.cpp b/Source/WebKitLegacy/haiku/API/WebSettingsPrivate.cpp new file mode 100644 index 000000000000..4a0172e32a45 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebSettingsPrivate.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "WebSettingsPrivate.h" + +#include "PageCache.h" +#include "Settings.h" +#include "WebSettings.h" + +#include +#include + +namespace BPrivate { + +BList WebSettingsPrivate::sAllSettings(128); + +WebSettingsPrivate::WebSettingsPrivate(WebCore::Settings* settings) + : settings(settings) + , localStoragePath() + , offlineStorageDefaultQuota(5 * 1024 * 1024) + , serifFontFamilySet(false) + , sansSerifFontFamilySet(false) + , fixedFontFamilySet(false) + , standardFontFamilySet(false) + , defaultFontSizeSet(false) + , defaultFixedFontSizeSet(false) + , javascriptEnabled(true) + , localStorageEnabled(false) + , databasesEnabled(false) + , offlineWebApplicationCacheEnabled(false) +{ + apply(); + if (settings) + sAllSettings.AddItem(this); + else { + // Initialize some default settings + // TODO: Get these from the system settings. + font_family ff; + font_style fs; + + be_plain_font->GetFamilyAndStyle(&ff, &fs); + sansSerifFontFamily = ff; + + be_fixed_font->GetFamilyAndStyle(&ff, &fs); + fixedFontFamily = ff; + + serifFontFamily = "Noto Serif Display"; + standardFontFamily = serifFontFamily; + defaultFontSize = 14; + defaultFixedFontSize = 14; + } +} + +WebSettingsPrivate::~WebSettingsPrivate() +{ + if (settings) + sAllSettings.RemoveItem(this); +} + +void WebSettingsPrivate::apply() +{ + if (settings) { + WebSettingsPrivate* global = BWebSettings::Default()->fData; + // Apply default values + settings->setLoadsImagesAutomatically(true); + settings->setMinimumFontSize(5); + settings->setMinimumLogicalFontSize(5); + settings->setShouldPrintBackgrounds(true); + settings->setScriptEnabled(javascriptEnabled); +// settings->setShowsURLsInToolTips(true); + settings->setEditingBehaviorType(WebCore::EditingMacBehavior); + settings->setLocalStorageEnabled(global->localStorageEnabled); + settings->setLocalStorageDatabasePath(global->localStoragePath); + settings->setDefaultTextEncodingName("UTF-8"); + settings->setUsesPageCache(WebCore::PageCache::singleton().maxSize()); + settings->setNeedsSiteSpecificQuirks(true); + + char path[256]; + status_t result = find_path((void*)&WebSettingsPrivate::apply, + B_FIND_PATH_DATA_DIRECTORY, + "/WebKit/Directory Listing Template.html", path, 256); + if (result != B_OK) { + find_directory(B_SYSTEM_NONPACKAGED_DATA_DIRECTORY, 0, false, path, + 256); + strcat(path, "/WebKit/Directory Listing Template.html"); + } + settings->setFTPDirectoryTemplatePath(path); + +// settings->setShowDebugBorders(true); + + // Apply local or global settings + if (defaultFontSizeSet) + settings->setDefaultFontSize(defaultFontSize); + else + settings->setDefaultFontSize(global->defaultFontSize); + + if (defaultFixedFontSizeSet) + settings->setDefaultFixedFontSize(defaultFixedFontSize); + else + settings->setDefaultFixedFontSize(global->defaultFixedFontSize); + + if (serifFontFamilySet) + settings->setSerifFontFamily(serifFontFamily.String()); + else + settings->setSerifFontFamily(global->serifFontFamily.String()); + + if (sansSerifFontFamilySet) + settings->setSansSerifFontFamily(sansSerifFontFamily.String()); + else + settings->setSansSerifFontFamily(global->sansSerifFontFamily.String()); + + if (fixedFontFamilySet) + settings->setFixedFontFamily(fixedFontFamily.String()); + else + settings->setFixedFontFamily(global->fixedFontFamily.String()); + + if (standardFontFamilySet) + settings->setStandardFontFamily(standardFontFamily.String()); + else + settings->setStandardFontFamily(global->standardFontFamily.String()); + } else { + int32 count = sAllSettings.CountItems(); + for (int32 i = 0; i < count; i++) { + WebSettingsPrivate* webSettings = reinterpret_cast( + sAllSettings.ItemAtFast(i)); + if (webSettings != this) + webSettings->apply(); + } + } +} + +} // namespace BPrivate diff --git a/Source/WebKitLegacy/haiku/API/WebSettingsPrivate.h b/Source/WebKitLegacy/haiku/API/WebSettingsPrivate.h new file mode 100644 index 000000000000..7f1bbaec67d7 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebSettingsPrivate.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebSettingsPrivate_h +#define WebSettingsPrivate_h + +#include +#include + +namespace WebCore { +class Settings; +} + +namespace BPrivate { + +class WebSettingsPrivate { +public: + WebSettingsPrivate(WebCore::Settings* settings = 0); + ~WebSettingsPrivate(); + + void apply(); + + WebCore::Settings* settings; + + BString localStoragePath; + int64 offlineStorageDefaultQuota; + + BString serifFontFamily; + BString sansSerifFontFamily; + BString fixedFontFamily; + BString standardFontFamily; + float defaultFontSize; + float defaultFixedFontSize; + + bool serifFontFamilySet : 1; + bool sansSerifFontFamilySet : 1; + bool fixedFontFamilySet : 1; + bool standardFontFamilySet : 1; + bool defaultFontSizeSet : 1; + bool defaultFixedFontSizeSet : 1; + bool javascriptEnabled : 1; + bool localStorageEnabled : 1; + bool databasesEnabled : 1; + bool offlineWebApplicationCacheEnabled : 1; + +private: + static BList sAllSettings; +}; + +} // namespace BPrivate + +#endif // WebSettingsPrivate_h diff --git a/Source/WebKitLegacy/haiku/API/WebView.cpp b/Source/WebKitLegacy/haiku/API/WebView.cpp new file mode 100644 index 000000000000..b51708862c81 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebView.cpp @@ -0,0 +1,622 @@ +/* + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "WebView.h" + +#include "AcceleratedCompositingContext.h" +#include "Frame.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "InspectorController.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PointerLockController.h" +#include "ScrollableArea.h" +#include "Scrollbar.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebViewConstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace WebCore; + + +static const int32 kMsgNavigateArrow = '_NvA'; + + +BWebView::UserData::~UserData() +{ +} + + +BWebView::BWebView(const char* name, BUrlContext* urlContext) + : BView(name, B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE + | B_NAVIGABLE | B_PULSE_NEEDED) + , fLastMouseButtons(0) + , fLastMouseMovedTime(-2000000) + , fLastMousePos(0, 0) + , fAutoHidePointer(false) + , fOffscreenBitmap(nullptr) + , fOffscreenView(nullptr) + , fWebPage(new BWebPage(this, urlContext)) + , fUserData(nullptr) +{ +#if USE(TEXTURE_MAPPER) + fCompositor = std::make_unique(this); +#endif + + fWebPage->Init(); + + // TODO: Should add this to the "current" looper, but that looper needs to + // stay around regardless of windows opening/closing. Adding it to the + // app looper is the safest bet for now. + if (be_app->Lock()) { + be_app->AddHandler(fWebPage); + be_app->Unlock(); + } + + FrameResized(Bounds().Width(), Bounds().Height()); + + SetViewColor(B_TRANSPARENT_COLOR); +} + +BWebView::~BWebView() +{ + delete fWebPage; + fWebPage = nullptr; + +#if USE(TEXTURE_MAPPER) + fCompositor = nullptr; +#endif + + if (fOffscreenBitmap) { + fOffscreenBitmap->Lock(); + delete fOffscreenBitmap; + } + + SetUserData(0); +} + +void BWebView::Shutdown() +{ + if (Window()) + RemoveSelf(); + fWebPage->Shutdown(); +} + +// #pragma mark - BView hooks + +void BWebView::AttachedToWindow() +{ + fWebPage->SetListener(BMessenger(Window())); + fWebPage->activated(Window()->IsActive()); + + // Setup some shortcuts. WebKit would handle those fine if we passed the + // KeyDown events even when B_COMMAND_KEY is pressed, but we don't. + BMessage* message; + char string[2]; + string[1] = 0; + + // Word-wise navigation shortcuts + if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_COMMAND_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + string[0] = B_LEFT_ARROW; + message->AddString("bytes", string); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY, message, this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + string[0] = B_RIGHT_ARROW; + message->AddString("bytes", string); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY, message, this); + } + + // Word-wise selection shortcuts + if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, + B_COMMAND_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + string[0] = B_LEFT_ARROW; + message->AddString("bytes", string); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, + message, this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + string[0] = B_RIGHT_ARROW; + message->AddString("bytes", string); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, + message, this); + } + +#if 0 + if (!Window()->HasShortcut(B_UP_ARROW, B_OPTION_KEY) + && !Window()->HasShortcut(B_DOWN_ARROW, B_OPTION_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_UP_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY); + Window()->AddShortcut(B_UP_ARROW, B_OPTION_KEY, message, this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_DOWN_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY); + Window()->AddShortcut(B_DOWN_ARROW, B_OPTION_KEY, message, this); + } + if (!Window()->HasShortcut(B_UP_ARROW, B_OPTION_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_DOWN_ARROW, + B_OPTION_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_UP_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_UP_ARROW, B_OPTION_KEY | B_SHIFT_KEY, + message, this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_DOWN_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_DOWN_ARROW, B_OPTION_KEY | B_SHIFT_KEY, + message, this); + } + + if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY) + && !Window()->HasShortcut(B_END, B_COMMAND_KEY)) { + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_HOME); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_HOME, B_COMMAND_KEY, message, this); + + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_END); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_END, B_COMMAND_KEY, message, this); + } + if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_HOME); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY, + message, this); + + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_END); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY, + message, this); + } +#endif +} + +void BWebView::DetachedFromWindow() +{ +} + +void BWebView::Show() +{ + BView::Show(); + fWebPage->setVisible(true); +} + +void BWebView::Hide() +{ + fWebPage->setVisible(false); + BView::Hide(); +} + +void BWebView::Draw(BRect rect) +{ + // Draw the page that was already rendered as an offscreen bitmap + if (fOffscreenBitmap == NULL || !fOffscreenBitmap->Lock()) { + SetHighColor(255, 255, 255); + FillRect(rect); + return; + } + + DrawBitmap(fOffscreenBitmap, rect, rect); + + fOffscreenBitmap->Unlock(); + + GraphicsContext g(this); + + // Draw some stuff for the web inspector +#if ENABLE(INSPECTOR) + if (fWebPage) { + WebCore::InspectorController& controller = fWebPage->page()->inspectorController(); + if (controller.highlightedNode()) { + controller.drawHighlight(g); + } + } +#endif +} + +void BWebView::FrameResized(float width, float height) +{ + _ResizeOffscreenView(width + 1, height + 1); + fWebPage->frameResized(width, height); +} + +void BWebView::GetPreferredSize(float* width, float* height) +{ + // This needs to be implemented, since the default BView implementation + // is to return the current width/height of the view. The default + // implementations for Min/Max/PreferredSize() will then work for us. + if (width) + *width = 100; + if (height) + *height = 100; +} + +void BWebView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case B_MOUSE_WHEEL_CHANGED: { + BPoint where; + uint32 buttons; + GetMouse(&where, &buttons); + BPoint screenWhere = ConvertToScreen(where); + fWebPage->mouseWheelChanged(message, where, screenWhere); + break; + } + + case B_SELECT_ALL: + case B_COPY: + case B_CUT: + case B_PASTE: + case B_UNDO: + case B_REDO: + fWebPage->standardShortcut(message); + break; + + case B_FIND_STRING_RESULT: + Window()->PostMessage(message); + break; + + case kMsgNavigateArrow: + message->what = B_KEY_DOWN; + _DispatchKeyEvent(B_KEY_DOWN); + break; + + case 'inva': + Invalidate(message->FindRect("bounds")); + break; + +#if ENABLE(POINTER_LOCK) + case 'plok': + { + status_t result = SetEventMask(B_POINTER_EVENTS, + B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS); + if (result == B_OK) + WebPage()->page()->pointerLockController().didAcquirePointerLock(); + else + WebPage()->page()->pointerLockController().didNotAcquirePointerLock(); + break; + } + + case 'pulk': + { + SetEventMask(0, 0); + WebPage()->page()->pointerLockController().didLosePointerLock(); + break; + } +#endif + + default: + BView::MessageReceived(message); + break; + } +} + +void BWebView::MakeFocus(bool focused) +{ + BView::MakeFocus(focused); + fWebPage->focused(focused); +} + +void BWebView::WindowActivated(bool activated) +{ + fWebPage->activated(activated); +} + +void BWebView::MouseMoved(BPoint where, uint32, const BMessage*) +{ + fLastMousePos = where; + fLastMouseMovedTime = system_time(); + _DispatchMouseEvent(where, B_MOUSE_MOVED); +} + +void BWebView::MouseDown(BPoint where) +{ + MakeFocus(true); + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + _DispatchMouseEvent(where, B_MOUSE_DOWN); +} + +void BWebView::MouseUp(BPoint where) +{ + _DispatchMouseEvent(where, B_MOUSE_UP); +} + +void BWebView::KeyDown(const char*, int32) +{ + if (Bounds().Contains(fLastMousePos)) + be_app->ObscureCursor(); + HideToolTip(); + + _DispatchKeyEvent(B_KEY_DOWN); +} + +void BWebView::KeyUp(const char*, int32) +{ + _DispatchKeyEvent(B_KEY_UP); +} + +void BWebView::Pulse() +{ + if (!fAutoHidePointer || !IsFocus() || !Window()->IsActive()) + return; + + if (Bounds().Contains(fLastMousePos) + && system_time() - fLastMouseMovedTime > 800000) { + be_app->ObscureCursor(); + } +} + +// #pragma mark - public API + +BString BWebView::MainFrameTitle() const +{ + return fWebPage->MainFrameTitle(); +} + +BString BWebView::MainFrameRequestedURL() const +{ + return fWebPage->MainFrameRequestedURL(); +} + +BString BWebView::MainFrameURL() const +{ + return fWebPage->MainFrameURL(); +} + +void BWebView::LoadURL(const char* urlString, bool aquireFocus) +{ + fWebPage->LoadURL(urlString); + // Always focus the web view after firing off a load request. + // This behavior is also observed in Firefox. + if (LockLooper()) { + if (aquireFocus && !IsFocus()) + MakeFocus(true); + UnlockLooper(); + } +} + +void BWebView::Reload() +{ + fWebPage->Reload(); +} + +void BWebView::GoBack() +{ + fWebPage->GoBack(); +} + +void BWebView::GoForward() +{ + fWebPage->GoForward(); +} + +void BWebView::StopLoading() +{ + fWebPage->StopLoading(); +} + +void BWebView::IncreaseZoomFactor(bool textOnly) +{ + fWebPage->ChangeZoomFactor(1, textOnly); +} + +void BWebView::DecreaseZoomFactor(bool textOnly) +{ + fWebPage->ChangeZoomFactor(-1, textOnly); +} + +void BWebView::ResetZoomFactor() +{ + fWebPage->ChangeZoomFactor(0, false); +} + +void BWebView::FindString(const char* string, bool forward , + bool caseSensitive, bool wrapSelection, bool startInSelection) +{ + fWebPage->FindString(string, forward, caseSensitive, + wrapSelection, startInSelection); +} + +void BWebView::SetAutoHidePointer(bool doIt) +{ + fAutoHidePointer = doIt; +} + +void BWebView::SetUserData(BWebView::UserData* userData) +{ + if (fUserData == userData) + return; + + delete fUserData; + fUserData = userData; +} + +BWebView::UserData* BWebView::GetUserData() const +{ + return fUserData; +} + + +void BWebView::SetInspectorView(BWebView* inspector) +{ + fInspectorView = inspector; +} + + +BWebView* BWebView::GetInspectorView() +{ + return fInspectorView; +} + + +void BWebView::SetRootLayer(WebCore::GraphicsLayer* layer) +{ +#if USE(TEXTURE_MAPPER) + fCompositor->setRootGraphicsLayer(layer); +#endif +} + + +// #pragma mark - API for WebPage only + +void BWebView::SetOffscreenViewClean(BRect cleanRect, bool immediate) +{ +#if USE(TEXTURE_MAPPER) + if (IsComposited()) + fCompositor->flushAndRenderLayers(); +#endif + + if (LockLooper()) { + if (immediate) + Draw(cleanRect); + else if(!IsComposited()) + Invalidate(cleanRect); + UnlockLooper(); + } +} + + +bool BWebView::IsComposited() +{ +#if USE(TEXTURE_MAPPER) + return fCompositor->isValid(); +#else + return false; +#endif +} + +// #pragma mark - private + +void BWebView::_ResizeOffscreenView(int width, int height) +{ + if (width <= 1 || height <= 1) + return; + + BRect bounds(0, 0, width - 1, height - 1); + + if (fOffscreenBitmap) { + fOffscreenBitmap->Lock(); + if (fOffscreenBitmap->Bounds().Contains(bounds)) { + // Just resize the view and clear the exposed parts, but never + // shrink the bitmap). + BRect oldViewBounds(fOffscreenView->Bounds()); + fOffscreenView->ResizeTo(width - 1, height - 1); + BRegion exposed(fOffscreenView->Bounds()); + exposed.Exclude(oldViewBounds); + fOffscreenView->FillRegion(&exposed, B_SOLID_LOW); + fOffscreenBitmap->Unlock(); + return; + } + } + BBitmap* oldBitmap = fOffscreenBitmap; + BView* oldView = fOffscreenView; + + fOffscreenBitmap = new BBitmap(bounds, B_RGB32, true); + if (fOffscreenBitmap->InitCheck() != B_OK) { + BAlert* alert = new BAlert("Internal error", "Unable to create off-screen bitmap for WebKit contents.", "OK"); + alert->Go(); + exit(1); + } + fOffscreenView = new BView(bounds, "WebKit offscreen view", 0, 0); + fOffscreenBitmap->Lock(); + fOffscreenBitmap->AddChild(fOffscreenView); + + if (oldBitmap) { + // Transfer the old bitmap contents (just the visible part) and + // clear the rest. + BRegion region(fOffscreenView->Bounds()); + BRect oldViewBounds = oldView->Bounds(); + region.Exclude(oldViewBounds); + fOffscreenView->DrawBitmap(oldBitmap, oldViewBounds, oldViewBounds); + fOffscreenView->FillRegion(®ion, B_SOLID_LOW); + delete oldBitmap; + // Takes care of old fOffscreenView too. + } + + fOffscreenBitmap->Unlock(); +} + + +void BWebView::_DispatchMouseEvent(const BPoint& where, uint32 sanityWhat) +{ + BMessage* message = Looper()->CurrentMessage(); + if (!message || message->what != sanityWhat) + return; + + if (sanityWhat == B_MOUSE_UP) { + // the activation click may contain no previous buttons + if (!fLastMouseButtons) + return; + + message->AddInt32("previous buttons", fLastMouseButtons); + } else + message->FindInt32("buttons", (int32*)&fLastMouseButtons); + + fWebPage->mouseEvent(message, where, ConvertToScreen(where)); +} + +void BWebView::_DispatchKeyEvent(uint32 sanityWhat) +{ + BMessage* message = Looper()->CurrentMessage(); + if (!message || message->what != sanityWhat) + return; + + fWebPage->keyEvent(message); +} + diff --git a/Source/WebKitLegacy/haiku/API/WebView.h b/Source/WebKitLegacy/haiku/API/WebView.h new file mode 100644 index 000000000000..ea824d616e68 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebView.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _WEB_VIEW_H_ +#define _WEB_VIEW_H_ + + +#include +#include + +#include + +class BUrlContext; +class BWebPage; + +namespace WebCore { + class ChromeClientHaiku; + class DumpRenderTreeClient; + class GraphicsLayer; + class AcceleratedCompositingContext; +} + + +class __attribute__ ((visibility ("default"))) BWebView : public BView { +public: + class UserData { + public: + virtual ~UserData(); + }; + +public: + BWebView(const char* name, BUrlContext* context = nullptr); + virtual ~BWebView(); + + // The BWebView needs to be deleted by the BWebPage instance running + // on the application thread in order to prevent possible race conditions. + // Call Shutdown() to initiate the deletion. + void Shutdown(); + + // BView hooks + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + + virtual void Show(); + virtual void Hide(); + + virtual void Draw(BRect); + virtual void FrameResized(float width, float height); + virtual void GetPreferredSize(float* width, float* height); + virtual void MessageReceived(BMessage* message); + + virtual void MakeFocus(bool focused = true); + virtual void WindowActivated(bool activated); + + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage); + virtual void MouseDown(BPoint where); + virtual void MouseUp(BPoint where); + + virtual void KeyDown(const char* bytes, int32 numBytes); + virtual void KeyUp(const char* bytes, int32 numBytes); + + virtual void Pulse(); + + // BWebPage API exposure + BWebPage* WebPage() const { return fWebPage; } + + BString MainFrameTitle() const; + BString MainFrameRequestedURL() const; + BString MainFrameURL() const; + + void LoadURL(const char* urlString, + bool aquireFocus = true); + void Reload(); + void GoBack(); + void GoForward(); + void StopLoading(); + + void IncreaseZoomFactor(bool textOnly); + void DecreaseZoomFactor(bool textOnly); + void ResetZoomFactor(); + + void FindString(const char* string, + bool forward = true, + bool caseSensitive = false, + bool wrapSelection = true, + bool startInSelection = false); + + // BWebview API + void SetAutoHidePointer(bool doIt); + + void SetUserData(UserData* cookie); + UserData* GetUserData() const; + + void SetInspectorView(BWebView* inspector); + BWebView* GetInspectorView(); + + void SetRootLayer(WebCore::GraphicsLayer* layer); +private: + friend class BWebPage; + friend class WebCore::DumpRenderTreeClient; + friend class WebCore::ChromeClientHaiku; + friend class WebCore::AcceleratedCompositingContext; + + inline BBitmap* OffscreenBitmap() const + { return fOffscreenBitmap; } + inline BView* OffscreenView() const + { return fOffscreenView; } + void SetOffscreenViewClean(BRect cleanRect, + bool immediate); + + bool IsComposited(); + +private: + void _ResizeOffscreenView(int width, int height); + void _DispatchMouseEvent(const BPoint& where, + uint32 sanityWhat); + void _DispatchKeyEvent(uint32 sanityWhat); +private: + uint32 fLastMouseButtons; + bigtime_t fLastMouseMovedTime; + BPoint fLastMousePos; + bool fAutoHidePointer; + + BBitmap* fOffscreenBitmap; + BView* fOffscreenView; + + std::unique_ptr + fCompositor; + + BWebPage* fWebPage; + + UserData* fUserData; + BWebView* fInspectorView; +}; + +#endif // _WEB_VIEW_H_ diff --git a/Source/WebKitLegacy/haiku/API/WebViewConstants.h b/Source/WebKitLegacy/haiku/API/WebViewConstants.h new file mode 100644 index 000000000000..3401658909e1 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebViewConstants.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2009 Maxime Simon + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebViewConstants_h +#define WebViewConstants_h + +enum { + LOAD_ONLOAD_HANDLE = 300, + LOAD_NEGOTIATING = 301, + TITLE_CHANGED = 302, + LOAD_COMMITTED = 303, + LOAD_PROGRESS = 304, + LOAD_DOC_COMPLETED = 305, + LOAD_DL_COMPLETED = 306, + LOAD_FAILED = 307, + LOAD_FINISHED = 308, + NEW_WINDOW_REQUESTED = 309, + NEW_PAGE_CREATED = 310, + NAVIGATION_REQUESTED = 311, + JAVASCRIPT_WINDOW_OBJECT_CLEARED = 312, + UPDATE_HISTORY = 313, + UPDATE_NAVIGATION_INTERFACE = 314, + AUTHENTICATION_CHALLENGE = 315, + ICON_RECEIVED = 316, + CLOSE_WINDOW_REQUESTED = 317, + MAIN_DOCUMENT_ERROR = 318, + LOAD_STARTED = 319, + RESPONSE_RECEIVED = 320, + ICON_CHANGED = 321, + SSL_CERT_ERROR = 322 +}; + +enum { + WebKitErrorCannotShowMIMEType = 100, + WebKitErrorCannotShowURL = 101, + WebKitErrorFrameLoadInterruptedByPolicyChange = 102, + WebKitErrorCannotUseRestrictedPort = 103, + WebKitErrorCannotFindPlugIn = 200, + WebKitErrorPlugInWillHandleLoad = 201, + WebKitErrorJavaUnavailable = 202 +}; + +enum { + TOOLBARS_VISIBILITY = 401, + STATUSBAR_VISIBILITY = 402, + MENUBAR_VISIBILITY = 403, + SET_RESIZABLE = 405, + SET_STATUS_TEXT = 406, + RESIZING_REQUESTED = 407, + ADD_CONSOLE_MESSAGE = 408, + SHOW_JS_ALERT = 409, + SHOW_JS_CONFIRM = 410, +}; + +enum { + EDITOR_DELETE_RANGE = 500, + EDITOR_BEGIN_EDITING = 501, + EDITOR_EDITING_BEGAN = 502, + EDITOR_EDITING_ENDED = 503, + EDITOR_END_EDITING = 504, + EDITOR_INSERT_NODE = 505, + EDITOR_INSERT_TEXT = 506, + EDITOR_CHANGE_SELECTED_RANGE = 507, + EDITOR_APPLY_STYLE = 508, + EDITOR_SELECTION_CHANGED = 509, + EDITOR_CONTENTS_CHANGED = 510 +}; + +#endif // WebViewConstants_h diff --git a/Source/WebKitLegacy/haiku/API/WebWindow.cpp b/Source/WebKitLegacy/haiku/API/WebWindow.cpp new file mode 100644 index 000000000000..d2a1ccdcf4a1 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebWindow.cpp @@ -0,0 +1,508 @@ +/* + * Copyright (C) 2007 Andrea Anzani + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebWindow.h" + +#include "wtf/CompletionHandler.h" +#include "wtf/MainThread.h" +#include "WebSettings.h" +#include "WebView.h" +#include "WebViewConstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum { + ICON_FOR_URL_RECEIVED = 'icfu' +}; + +BWebWindow::BWebWindow(BRect frame, const char* title, window_look look, + window_feel feel, uint32 flags, uint32 workspace) + : BWindow(frame, title, look, feel, flags, workspace) + , fWebView(0) +{ + SetLayout(new BGroupLayout(B_HORIZONTAL)); + + // NOTE: Do NOT change these because you think Redo should be on Cmd-Y! + AddShortcut('Z', B_COMMAND_KEY, new BMessage(B_UNDO), NULL); + AddShortcut('Y', B_COMMAND_KEY, new BMessage(B_UNDO), NULL); + AddShortcut('Z', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(B_REDO), NULL); + AddShortcut('Y', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(B_REDO), NULL); +} + +BWebWindow::~BWebWindow() +{ +} + +void BWebWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case LOAD_ONLOAD_HANDLE: + // NOTE: Supposedly this notification is sent when the so-called + // "onload" event has been passed and executed to scripts in the + // site. + break; + case LOAD_DL_COMPLETED: + // NOTE: All loading has finished. We currently handle this via + // the progress notification. But it doesn't hurt to call the hook + // one more time. + LoadProgress(100, _WebViewForMessage(message)); + break; + case LOAD_DOC_COMPLETED: { + // NOTE: This events means the DOM document is ready. + BString url; + if (message->FindString("url", &url) == B_OK) + LoadFinished(url, _WebViewForMessage(message)); + break; + } + case JAVASCRIPT_WINDOW_OBJECT_CLEARED: + // NOTE: No idea what this event actually means. + break; + case NAVIGATION_REQUESTED: { + BString url; + if (message->FindString("url", &url) == B_OK) { + NavigationRequested(url, _WebViewForMessage(message)); + } + break; + } + case UPDATE_HISTORY: { + BString url; + if (message->FindString("url", &url) == B_OK) + UpdateGlobalHistory(url); + break; + } + case NEW_WINDOW_REQUESTED: { + bool primaryAction = false; + message->FindBool("primary", &primaryAction); + BString url; + if (message->FindString("url", &url) == B_OK) + NewWindowRequested(url, primaryAction); + break; + } + case NEW_PAGE_CREATED: { + // The FrameLoaderClient blocks until we have processed the message + // and sent a default reply. That's why the pointer is guaranteed + // to be still valid. + BWebView* view; + if (message->FindPointer("view", reinterpret_cast(&view)) != B_OK) + break; + BRect windowFrame; + message->FindRect("frame", &windowFrame); + bool modalDialog; + if (message->FindBool("modal", &modalDialog) != B_OK) + modalDialog = false; + bool resizable; + if (message->FindBool("resizable", &resizable) != B_OK) + resizable = true; + bool activate; + if (message->FindBool("activate", &activate) != B_OK) + activate = true; + + NewPageCreated(view, windowFrame, modalDialog, resizable, activate); + break; + } + case CLOSE_WINDOW_REQUESTED: + CloseWindowRequested(_WebViewForMessage(message)); + break; + case LOAD_NEGOTIATING: { + BString url; + if (message->FindString("url", &url) == B_OK) { + LoadNegotiating(url, _WebViewForMessage(message)); + } + + WTF::CompletionHandler* handler; + if (message->FindPointer("completionHandler", (void**)&handler) == B_OK) { + callOnMainThread([handler] { + (*handler)(); + delete handler; + }); + } + break; + } + case LOAD_COMMITTED: { + BString url; + if (message->FindString("url", &url) == B_OK) + LoadCommitted(url, _WebViewForMessage(message)); + break; + } + case LOAD_PROGRESS: { + float progress; + if (message->FindFloat("progress", &progress) == B_OK) + LoadProgress(progress, _WebViewForMessage(message)); + break; + } + case LOAD_FAILED: { + BString url; + if (message->FindString("url", &url) == B_OK) + LoadFailed(url, _WebViewForMessage(message)); + break; + } + case LOAD_FINISHED: { + break; + } + case MAIN_DOCUMENT_ERROR: { + BString failingURL; + BString localizedErrorString; + if (message->FindString("url", &failingURL) == B_OK + && message->FindString("error", &localizedErrorString) == B_OK) { + MainDocumentError(failingURL, localizedErrorString, + _WebViewForMessage(message)); + } + break; + } + case TITLE_CHANGED: { + BString title; + if (message->FindString("title", &title) == B_OK) + TitleChanged(title, _WebViewForMessage(message)); + break; + } + case ICON_RECEIVED: { + // The icon is now in the database. + BString url; + if (message->FindString("url", &url) == B_OK) + _FetchIconForURL(url, *message); + break; + } + case ICON_FOR_URL_RECEIVED: { + BMessage iconArchive; + if (message->FindMessage("icon", &iconArchive) == B_OK) { + BBitmap icon(&iconArchive); + IconReceived(&icon, _WebViewForMessage(message)); + } else + IconReceived(NULL, _WebViewForMessage(message)); + break; + } + case RESIZING_REQUESTED: { + BRect rect; + if (message->FindRect("rect", &rect) == B_OK) + ResizeRequested(rect.Width(), rect.Height(), _WebViewForMessage(message)); + break; + } + case SET_STATUS_TEXT: { + BString text; + if (message->FindString("text", &text) == B_OK) + StatusChanged(text, _WebViewForMessage(message)); + break; + } + case ADD_CONSOLE_MESSAGE: { + BString source = message->FindString("source"); + int32 lineNumber = message->FindInt32("line"); + int32 columnNumber = message->FindInt32("column"); + BString text = message->FindString("string"); + printf("MESSAGE %s:%li:%li: %s\n", source.String(), lineNumber, + columnNumber, text.String()); + + break; + } + case SHOW_JS_ALERT: { + BString text = message->FindString("text"); + BAlert* alert = new BAlert("JavaScript", text, "OK"); + alert->Go(); + break; + } + case SHOW_JS_CONFIRM: { + BString text = message->FindString("text"); + BAlert* alert = new BAlert("JavaScript", text, "Yes", "No"); + BMessage reply; + reply.AddBool("result", !alert->Go()); + message->SendReply(&reply); + break; + } + case UPDATE_NAVIGATION_INTERFACE: { + bool canGoBackward = false; + bool canGoForward = false; + bool canStop = false; + message->FindBool("can go backward", &canGoBackward); + message->FindBool("can go forward", &canGoForward); + message->FindBool("can stop", &canStop); + NavigationCapabilitiesChanged(canGoBackward, canGoForward, canStop, _WebViewForMessage(message)); + break; + } + case AUTHENTICATION_CHALLENGE: { + BString text; + bool rememberCredentials = false; + uint32 failureCount = 0; + BString user; + BString password; + + message->FindString("text", &text); + message->FindString("user", &user); + message->FindString("password", &password); + message->FindUInt32("failureCount", &failureCount); + + if (!AuthenticationChallenge(text, user, password, rememberCredentials, + failureCount, _WebViewForMessage(message))) { + message->SendReply((uint32)0); + break; + } + + BMessage reply; + reply.AddString("user", user); + reply.AddString("password", password); + reply.AddBool("rememberCredentials", rememberCredentials); + message->SendReply(&reply); + break; + } + case SSL_CERT_ERROR: { + BString text; + + message->FindString("text", &text); + + BAlert* alert = new BAlert("Unsecure SSL certificate", text, + "Continue", "Stop", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); + // TODO add information about the certificate to the alert + // (in a "details" area or so) + // (but this can be done in WebPositive as well) + + int button = alert->Go(); + BMessage reply; + reply.AddBool("continue", button == 0); + message->SendReply(&reply); + break; + } + + + case TOOLBARS_VISIBILITY: { + bool flag; + if (message->FindBool("flag", &flag) == B_OK) + SetToolBarsVisible(flag, _WebViewForMessage(message)); + break; + } + case STATUSBAR_VISIBILITY: { + bool flag; + if (message->FindBool("flag", &flag) == B_OK) + SetStatusBarVisible(flag, _WebViewForMessage(message)); + break; + } + case MENUBAR_VISIBILITY: { + bool flag; + if (message->FindBool("flag", &flag) == B_OK) + SetMenuBarVisible(flag, _WebViewForMessage(message)); + break; + } + case SET_RESIZABLE: { + bool flag; + if (message->FindBool("flag", &flag) == B_OK) + SetResizable(flag, _WebViewForMessage(message)); + break; + } + + case B_MOUSE_WHEEL_CHANGED: + if (fWebView) + fWebView->MessageReceived(message); + break; + + default: + BWindow::MessageReceived(message); + break; + } +} + +bool BWebWindow::QuitRequested() +{ + // Do this here, so WebKit tear down happens earlier. + if (fWebView) + fWebView->Shutdown(); + + return true; +} + +// #pragma mark - + +void BWebWindow::SetCurrentWebView(BWebView* view) +{ + fWebView = view; +} + +BWebView* BWebWindow::CurrentWebView() const +{ + return fWebView; +} + +// #pragma mark - Notification API + +void BWebWindow::NavigationRequested(const BString& /*url*/, BWebView* /*view*/) +{ +} + +void BWebWindow::NewWindowRequested(const BString& /*url*/, bool /*primaryAction*/) +{ +} + +void BWebWindow::NewPageCreated(BWebView* view, BRect windowFrame, + bool modalDialog, bool resizable, bool /*activate*/) +{ + if (!windowFrame.IsValid()) + windowFrame = Frame().OffsetByCopy(10, 10); + + uint32 flags = Flags(); + + window_look look; + window_feel feel; + if (modalDialog) { + feel = B_MODAL_APP_WINDOW_FEEL; + look = B_BORDERED_WINDOW_LOOK; + } else { + look = B_TITLED_WINDOW_LOOK; + feel = B_NORMAL_WINDOW_FEEL; + } + if (!resizable) + flags |= B_NOT_RESIZABLE; + + BWebWindow* window = new BWebWindow(windowFrame, "WebKit window", + look, feel, flags); + + window->AddChild(view); + window->SetCurrentWebView(view); + + window->Show(); +} + +void BWebWindow::CloseWindowRequested(BWebView* /*view*/) +{ + PostMessage(B_QUIT_REQUESTED); +} + +void BWebWindow::LoadNegotiating(const BString& /*url*/, BWebView* /*view*/) +{ +} + +void BWebWindow::LoadCommitted(const BString& /*url*/, BWebView* /*view*/) +{ +} + +void BWebWindow::LoadProgress(float /*progress*/, BWebView* /*view*/) +{ +} + +void BWebWindow::LoadFailed(const BString& /*url*/, BWebView* /*view*/) +{ +} + +void BWebWindow::LoadFinished(const BString& /*url*/, BWebView* /*view*/) +{ +} + +void BWebWindow::MainDocumentError(const BString& failingURL, + const BString& localizedDescription, BWebView* /*view*/) +{ + BString errorString("Error loading "); + errorString << failingURL; + errorString << ":\n\n"; + errorString << localizedDescription; + BAlert* alert = new BAlert("Main document error", errorString.String(), + "OK"); + alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); + alert->Go(NULL); +} + +void BWebWindow::TitleChanged(const BString& title, BWebView* /*view*/) +{ + SetTitle(title.String()); +} + +void BWebWindow::IconReceived(const BBitmap* /*icon*/, BWebView* /*view*/) +{ +} + +void BWebWindow::ResizeRequested(float width, float height, BWebView* /*view*/) +{ + ResizeTo(width, height); +} + +void BWebWindow::SetToolBarsVisible(bool /*flag*/, BWebView* /*view*/) +{ +} + +void BWebWindow::SetStatusBarVisible(bool /*flag*/, BWebView* /*view*/) +{ +} + +void BWebWindow::SetMenuBarVisible(bool /*flag*/, BWebView* /*view*/) +{ +} + +void BWebWindow::SetResizable(bool flag, BWebView* /*view*/) +{ + if (flag) + SetFlags(Flags() & ~B_NOT_RESIZABLE); + else + SetFlags(Flags() | B_NOT_RESIZABLE); +} + +void BWebWindow::StatusChanged(const BString& /*statusText*/, BWebView* /*view*/) +{ +} + +void BWebWindow::NavigationCapabilitiesChanged(bool /*canGoBackward*/, + bool /*canGoForward*/, bool /*canStop*/, BWebView* /*view*/) +{ +} + +void BWebWindow::UpdateGlobalHistory(const BString& /*url*/) +{ +} + +bool BWebWindow::AuthenticationChallenge(BString /*message*/, + BString& /*inOutUser*/, BString& /*inOutPassword*/, + bool& /*inOutRememberCredentials*/, uint32 /*failureCount*/, + BWebView* /*view*/) +{ + return false; +} + +// #pragma mark - private + +void BWebWindow::_FetchIconForURL(const BString& url, const BMessage& message) +{ + BMessage reply(message); + reply.what = ICON_FOR_URL_RECEIVED; + BMessenger target(this); + BWebSettings::SendIconForURL(url, reply, target); +} + +BWebView* BWebWindow::_WebViewForMessage(const BMessage* message) const +{ + // Default to the current BWebView, if there is none in the message. + BWebView* view = fWebView; + message->FindPointer("view", reinterpret_cast(&view)); + return view; +} + diff --git a/Source/WebKitLegacy/haiku/API/WebWindow.h b/Source/WebKitLegacy/haiku/API/WebWindow.h new file mode 100644 index 000000000000..2c0b7abef997 --- /dev/null +++ b/Source/WebKitLegacy/haiku/API/WebWindow.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _WEB_WINDOW_H_ +#define _WEB_WINDOW_H_ + + +#include + +class BWebView; + + +class __attribute__ ((visibility ("default"))) BWebWindow : public BWindow { +public: + BWebWindow(BRect frame, const char* title, + window_look look, window_feel feel, + uint32 flags, + uint32 workspace = B_CURRENT_WORKSPACE); + virtual ~BWebWindow(); + + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + + // You can have as many BWebViews in your derived window as you want, + // but for some situations, the BWebWindow needs to know the current one, + // so always make it known here. + virtual void SetCurrentWebView(BWebView* view); + BWebView* CurrentWebView() const; + + // Derived windows can implement this notification API. + virtual void NavigationRequested(const BString& url, + BWebView* view); + virtual void NewWindowRequested(const BString& url, + bool primaryAction); + virtual void CloseWindowRequested(BWebView* view); + virtual void NewPageCreated(BWebView* view, + BRect windowFrame, bool modalDialog, + bool resizable, bool activate); + virtual void LoadNegotiating(const BString& url, + BWebView* view); + virtual void LoadCommitted(const BString& url, + BWebView* view); + virtual void LoadProgress(float progress, BWebView* view); + virtual void LoadFailed(const BString& url, BWebView* view); + virtual void LoadFinished(const BString& url, + BWebView* view); + virtual void MainDocumentError(const BString& failingURL, + const BString& localizedDescription, + BWebView* view); + virtual void TitleChanged(const BString& title, + BWebView* view); + virtual void IconReceived(const BBitmap* icon, + BWebView* view); + virtual void ResizeRequested(float width, float height, + BWebView* view); + virtual void SetToolBarsVisible(bool flag, BWebView* view); + virtual void SetStatusBarVisible(bool flag, BWebView* view); + virtual void SetMenuBarVisible(bool flag, BWebView* view); + virtual void SetResizable(bool flag, BWebView* view); + virtual void StatusChanged(const BString& status, + BWebView* view); + virtual void NavigationCapabilitiesChanged( + bool canGoBackward, bool canGoForward, + bool canStop, BWebView* view); + virtual void UpdateGlobalHistory(const BString& url); + virtual bool AuthenticationChallenge(BString message, + BString& inOutUser, BString& inOutPassword, + bool& inOutRememberCredentials, + uint32 failureCount, BWebView* view); + +private: + void _FetchIconForURL(const BString& url, + const BMessage& message); + BWebView* _WebViewForMessage( + const BMessage* message) const; + +private: + BWebView* fWebView; +}; + +#endif // _WEB_WINDOW_H_ + diff --git a/Source/WebKitLegacy/haiku/ChangeLog b/Source/WebKitLegacy/haiku/ChangeLog new file mode 100644 index 000000000000..2d2acbe5b360 --- /dev/null +++ b/Source/WebKitLegacy/haiku/ChangeLog @@ -0,0 +1,259 @@ +2010-04-11 Sheriff Bot + + Unreviewed, rolling out r57468. + http://trac.webkit.org/changeset/57468 + https://bugs.webkit.org/show_bug.cgi?id=37433 + + Broke the world... Must have applied the patch wrong + (Requested by abarth on #webkit). + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::committedLoad): + +2010-04-11 Adam Barth + + Reviewed by Eric Seidel. + + Factor DocumentWriter out of FrameLoader + https://bugs.webkit.org/show_bug.cgi?id=37175 + + Update these callsites because the method moved to DocumentWriter. + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::committedLoad): + +2010-04-07 Andrey Kosyakov + + Reviewed by Yury Semikhatsky. + + Removed redundant FrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest() + https://bugs.webkit.org/show_bug.cgi?id=36949 + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + * WebCoreSupport/FrameLoaderClientHaiku.h: + +2010-03-31 Marcus Bulach + + Reviewed by Jeremy Orlow. + + Adds Geolocation param for cancelGeolocationPermissionRequestForFrame. + https://bugs.webkit.org/show_bug.cgi?id=35031 + + * WebCoreSupport/ChromeClientHaiku.h: + (WebCore::ChromeClientHaiku::cancelGeolocationPermissionRequestForFrame): + +2010-03-28 Alexey Proskuryakov + + Build fix. Include WindowsKeyboardCodes.h instead of KeyboardCodes.h. + + * WebCoreSupport/EditorClientHaiku.cpp: + +2010-03-24 Kent Tamura + + Reviewed by Darin Adler. + + Make Icon::createIconForFiles() optional. + https://bugs.webkit.org/show_bug.cgi?id=35072 + + - Rename iconForFiles() to chooseIconForFiles(). + - Call Icon::createIconForFiles() from chooseIconForFiles(). + + * WebCoreSupport/ChromeClientHaiku.cpp: + (WebCore::ChromeClientHaiku::chooseIconForFiles): + * WebCoreSupport/ChromeClientHaiku.h: + +2010-03-16 Yury Semikhatsky + + Reviewed by Pavel Feldman. + + Introduce InspectorFrontendClient that provides InspectorFrontend with an interface to the embedder. InspectorClient now serves as a delegate for InspectorController and does not contain methods for managing inspector frontend window. That allows to create remote InspectorFrontendHost. + + Introduce InspectorFrontendClient that would provide InspectorFrontend with an interface to the embedder + https://bugs.webkit.org/show_bug.cgi?id=35036 + + * WebCoreSupport/InspectorClientHaiku.cpp: + (WebCore::InspectorClientHaiku::openInspectorFrontend): + * WebCoreSupport/InspectorClientHaiku.h: + +2010-03-11 Anders Carlsson + + Reviewed by David Hyatt. + + Remove invalidateContents, it isn't used and it never makes sense to only invalidate the contents. + + * WebCoreSupport/ChromeClientHaiku.cpp: + * WebCoreSupport/ChromeClientHaiku.h: + +2010-03-02 Adam Treat + + Reviewed by Dave Hyatt. + + Adapt the haiku port to the refactoring of repaint methods. + + https://bugs.webkit.org/show_bug.cgi?id=34214 + + * WebCoreSupport/ChromeClientHaiku.cpp: + (WebCore::ChromeClientHaiku::invalidateContents): + (WebCore::ChromeClientHaiku::invalidateWindow): + (WebCore::ChromeClientHaiku::invalidateContentsAndWindow): + (WebCore::ChromeClient::invalidateContentsForSlowScroll): + * WebCoreSupport/ChromeClientHaiku.h: + +2010-02-23 Steve Block + + Reviewed by Darin Adler. + + Adds ChromeClient::cancelGeolocationPermissionRequestForFrame + https://bugs.webkit.org/show_bug.cgi?id=34962 + + This method is required so that a Geolocation object can cancel an + asynchronous permission request. This allows the chrome client to cancel + any UI it is showing for the permission request. + + * WebCoreSupport/ChromeClientHaiku.h: + (WebCore::ChromeClientHaiku::cancelGeolocationPermissionRequestForFrame): + +2010-02-17 Dmitry Titov + + Reviewed by David Levin, Darin Fisher, Simon Hausmann. + + When a live iframe element is moved between pages, it still depends on the old page. + https://bugs.webkit.org/show_bug.cgi?id=34382 + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::didTransferChildFrameToNewDocument): + Added empty implementation of a new virtual method. + + * WebCoreSupport/FrameLoaderClientHaiku.h: + +2010-02-17 Kent Tamura + + Reviewed by Eric Seidel. + + Introduces new Icon loading interface in order to support + asynchronous loading. + https://bugs.webkit.org/show_bug.cgi?id=32054 + + Add an empty implementation of ChromeClient::iconForFiles(). + + * WebCoreSupport/ChromeClientHaiku.cpp: + (WebCore::ChromeClientHaiku::iconForFiles): + * WebCoreSupport/ChromeClientHaiku.h: + +2009-12-06 Maxime Simon + + Reviewed by Adam Barth. + + Build fix. Add in FrameLoaderClientHaiku the declaration of three functions introduced in r51644. + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::dispatchDidPushStateWithinPage): + (WebCore::FrameLoaderClientHaiku::dispatchDidReplaceStateWithinPage): + (WebCore::FrameLoaderClientHaiku::dispatchDidPopStateWithinPage): + * WebCoreSupport/FrameLoaderClientHaiku.h: + +2009-12-03 Pavel Feldman + + Reviewed by Timothy Hatcher. + + Web Inspector: Simplify the settings support in inspector controller. + + https://bugs.webkit.org/show_bug.cgi?id=32076 + + * WebCoreSupport/InspectorClientHaiku.cpp: + (WebCore::InspectorClientHaiku::populateSetting): + (WebCore::InspectorClientHaiku::storeSetting): + * WebCoreSupport/InspectorClientHaiku.h: + +2009-12-03 Ben Murdoch + + Reviewed by Brady Eidson. + + [Android] The FrameLoaderClient is unaware of BackForwardList changes. + https://bugs.webkit.org/show_bug.cgi?id=31914 + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::dispatchDidAddBackForwardItem): Add an empty implementation. Method added to FrameLoaderClient by Android (see bug). + (WebCore::FrameLoaderClientHaiku::dispatchDidRemoveBackForwardItem): ditto. + (WebCore::FrameLoaderClientHaiku::dispatchDidChangeBackForwardIndex): ditto. + * WebCoreSupport/FrameLoaderClientHaiku.h: + +2009-11-13 Adam Roben + + Update for changes to FrameLoaderClient + + Fixes Tell the WebFrameLoadDelegate when + window objects in isolated worlds are cleared + + Reviewed by Dave Hyatt. + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::dispatchDidClearWindowObjectInWorld): + * WebCoreSupport/FrameLoaderClientHaiku.h: + Replaced windowObjectCleared with this function. Does nothing if the + passed-in world is not the mainThreadNormalWorld(). + +2009-10-30 Evan Stade + + Reviewed by David Levin. + + Notify the chrome when the focused node has changed. + https://bugs.webkit.org/show_bug.cgi?id=30832 + + Added stub implementation for new ChromeClient function. + + * WebCoreSupport/ChromeClientHaiku.cpp: + (WebCore::ChromeClientHaiku::focusedNodeChanged): + * WebCoreSupport/ChromeClientHaiku.h: + +2009-10-07 Adam Barth + + Reviewed by Darin Adler. + + Factor PolicyChecker out of FrameLoader + https://bugs.webkit.org/show_bug.cgi?id=30155 + + Move the policy callback to the policy object. + + * WebCoreSupport/FrameLoaderClientHaiku.cpp: + (WebCore::FrameLoaderClientHaiku::dispatchWillSubmitForm): + (WebCore::FrameLoaderClientHaiku::dispatchDecidePolicyForMIMEType): + (WebCore::FrameLoaderClientHaiku::dispatchDecidePolicyForNewWindowAction): + (WebCore::FrameLoaderClientHaiku::dispatchDecidePolicyForNavigationAction): + +2009-09-17 Kenneth Rohde Christiansen + + Reviewed by Simon Hausmann. + + Make PlatformWindow return something else than PlatformWidget + https://bugs.webkit.org/show_bug.cgi?id=29085 + + Reflect the rename of platformWindow and it's return type. + + * WebCoreSupport/ChromeClientHaiku.cpp: + (WebCore::ChromeClientHaiku::platformPageClient): + * WebCoreSupport/ChromeClientHaiku.h: + +2009-08-28 Gustavo Noronha Silva + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=25889 + [GTK] scrollbar policy for main frame is not implementable + + Add empty implementation for new ChromeClient method. + + * WebCoreSupport/ChromeClientHaiku.h: + (ChromeClientHaiku::scrollbarsModeDidChange): + +2009-07-29 Kevin McCullough + + Reviewed by Darin Adler. + + Added foundation work to allow a testing infrastructure for the Web + Inspector. + + * WebCoreSupport/InspectorClientHaiku.cpp: + (WebCore::InspectorClientHaiku::inspectorWindowObjectCleared): + * WebCoreSupport/InspectorClientHaiku.h: + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/AcceleratedCompositingContext.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/AcceleratedCompositingContext.cpp new file mode 100644 index 000000000000..099e69ee11df --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/AcceleratedCompositingContext.cpp @@ -0,0 +1,146 @@ +/* + Copyright (C) 2012 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "AcceleratedCompositingContext.h" +#include "Bitmap.h" +#include "FrameView.h" +#include "Frame.h" +#include "GraphicsContext.h" +#include "GraphicsLayerTextureMapper.h" +#include "NotImplemented.h" +#include "TextureMapperLayer.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebView.h" + +const double compositingFrameRate = 60; + +namespace WebCore { + +AcceleratedCompositingContext::AcceleratedCompositingContext(BWebView* view) + : m_view(view) + , m_rootLayer(nullptr) + , m_syncTimer(*this, &AcceleratedCompositingContext::syncLayers) +{ + ASSERT(m_view); + +#if USE(TEXTURE_MAPPER) + m_textureMapper = TextureMapper::create(); +#endif +} + +AcceleratedCompositingContext::~AcceleratedCompositingContext() +{ + m_syncTimer.stop(); +#if USE(TEXTURE_MAPPER) + m_textureMapper = nullptr; +#endif +} + +void AcceleratedCompositingContext::syncLayers() +{ + flushAndRenderLayers(); +} + +void AcceleratedCompositingContext::flushAndRenderLayers() +{ + // Check that we aren't being deleted... + if (!m_view->LockLooper()) return; + BWebPage* page = m_view->WebPage(); + m_view->UnlockLooper(); + + if (!page) return; + + Frame& frame = *(Frame*)(page->MainFrame()->Frame()); + if (!frame.contentRenderer() || !frame.view()) + return; + frame.view()->updateLayoutAndStyleIfNeededRecursive(); + + if (flushPendingLayerChanges()) + paintToGraphicsContext(); +} + +bool AcceleratedCompositingContext::flushPendingLayerChanges() +{ +#if USE(TEXTURE_MAPPER) + if (m_rootLayer) + m_rootLayer->flushCompositingStateForThisLayerOnly(); +#endif + return m_view->WebPage()->MainFrame()->Frame()->view()->flushCompositingStateIncludingSubframes(); +} + +void AcceleratedCompositingContext::paintToGraphicsContext() +{ + BView* target = m_view->OffscreenView(); + GraphicsContext context(target); + +#if USE(TEXTURE_MAPPER) + m_textureMapper->setGraphicsContext(&context); +#endif + + if(target->LockLooper()) { + compositeLayers(target->Bounds()); + target->Sync(); + target->UnlockLooper(); + } + + if(m_view->LockLooper()) { + m_view->Invalidate(m_updateRect); + m_view->UnlockLooper(); + } +} + +void AcceleratedCompositingContext::compositeLayers(BRect updateRect) +{ +#if USE(TEXTURE_MAPPER) + if (!m_rootLayer || !m_rootLayer->isGraphicsLayerTextureMapper()) + return; + + TextureMapperLayer& currentRootLayer = downcast(m_rootLayer)->layer(); + + m_updateRect = updateRect; + + currentRootLayer.setTextureMapper(m_textureMapper.get()); + + m_textureMapper->beginPainting(); + m_textureMapper->beginClip(TransformationMatrix(), updateRect); + + currentRootLayer.paint(); + m_fpsCounter.updateFPSAndDisplay(*m_textureMapper); + m_textureMapper->endClip(); + m_textureMapper->endPainting(); + + if (currentRootLayer.descendantsOrSelfHaveRunningAnimations() && !m_syncTimer.isActive()) + m_syncTimer.startOneShot(WTF::Seconds(1 / compositingFrameRate)); +#endif +} + +void AcceleratedCompositingContext::setRootGraphicsLayer(GraphicsLayer* rootLayer) +{ +#if USE(TEXTURE_MAPPER) + m_rootLayer = rootLayer; +#endif + + if (!m_syncTimer.isActive()) + m_syncTimer.startOneShot(WTF::Seconds(0)); +} + +} // namespace WebCore diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/AcceleratedCompositingContext.h b/Source/WebKitLegacy/haiku/WebCoreSupport/AcceleratedCompositingContext.h new file mode 100644 index 000000000000..a04b92be81a9 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/AcceleratedCompositingContext.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2012 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef AcceleratedCompositingContext_h +#define AcceleratedCompositingContext_h + +#include +#include "TextureMapperFPSCounter.h" +#include "Timer.h" +#include + +#include + +class BBitmap; +class BView; +class BWebView; + +namespace WebCore { + +class GraphicsLayer; +class HostWindow; +class TextureMapper; +class TextureMapperLayer; + +class AcceleratedCompositingContext { + WTF_MAKE_NONCOPYABLE(AcceleratedCompositingContext); +public: + AcceleratedCompositingContext(BWebView* view); + ~AcceleratedCompositingContext(); + + void setRootGraphicsLayer(GraphicsLayer* rootLayer); + bool isValid() { return m_rootLayer != NULL; } + void flushAndRenderLayers(); + +private: + void paintToGraphicsContext(); + void compositeLayers(BRect updateRect); + + bool flushPendingLayerChanges(); + void syncLayers(); + + BWebView* m_view; + BRect m_updateRect; + + GraphicsLayer* m_rootLayer; + Timer m_syncTimer; + +#if USE(TEXTURE_MAPPER) + std::unique_ptr m_textureMapper; + TextureMapperFPSCounter m_fpsCounter; +#endif +}; + +} // namespace WebCore + +#endif // AcceleratedCompositingContext_h diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/BackForwardList.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/BackForwardList.cpp new file mode 100644 index 000000000000..fb469a098851 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/BackForwardList.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2005, 2006 Apple Inc. All rights reserved. + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "BackForwardList.h" + +#include "Frame.h" +#include "WebCore/FrameLoader.h" +#include "WebCore/FrameLoaderClient.h" +#include + +#include "WebCore/HistoryItem.h" +#include "WebCore/PageCache.h" + +static const unsigned DefaultCapacity = 100; +static const unsigned NoCurrentItemIndex = UINT_MAX; + +using namespace WebCore; + +BackForwardList::BackForwardList() + : m_current(NoCurrentItemIndex) + , m_capacity(DefaultCapacity) + , m_closed(true) + , m_enabled(true) +{ +} + +BackForwardList::~BackForwardList() +{ + ASSERT(m_closed); +} + +void BackForwardList::addItem(Ref&& newItem) +{ + if (!m_capacity || !m_enabled) + return; + + // Toss anything in the forward list + if (m_current != NoCurrentItemIndex) { + unsigned targetSize = m_current + 1; + while (m_entries.size() > targetSize) { + RefPtr item = m_entries.takeLast(); + m_entryHash.remove(item); + PageCache::singleton().remove(*item); + } + } + + // Toss the first item if the list is getting too big, as long as we're not using it + // (or even if we are, if we only want 1 entry). + if (m_entries.size() == m_capacity && (m_current || m_capacity == 1)) { + RefPtr item = WTFMove(m_entries[0]); + m_entries.remove(0); + m_entryHash.remove(item); + PageCache::singleton().remove(*item); + --m_current; + } + + m_entryHash.add(newItem.ptr()); + m_entries.insert(m_current + 1, WTFMove(newItem)); + ++m_current; +} + +void BackForwardList::goToItem(HistoryItem& item) +{ + if (!m_entries.size()) + return; + + unsigned int index = 0; + for (; index < m_entries.size(); ++index) + if (m_entries[index] == &item) + break; + if (index < m_entries.size()) { + m_current = index; + } +} + + +unsigned int BackForwardList::backListCount() const +{ + return m_current == NoCurrentItemIndex ? 0 : m_current; +} + +unsigned int BackForwardList::forwardListCount() const +{ + return m_current == NoCurrentItemIndex ? 0 : m_entries.size() - m_current - 1; +} + +RefPtr BackForwardList::itemAtIndex(int index) +{ + // Do range checks without doing math on index to avoid overflow. + if (index < -static_cast(m_current)) + return nullptr; + + if (index > static_cast(forwardListCount())) + return nullptr; + + return m_entries[index + m_current]; +} + + +void BackForwardList::close() +{ + m_entries.clear(); + m_entryHash.clear(); + m_closed = true; +} + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/BackForwardList.h b/Source/WebKitLegacy/haiku/WebCoreSupport/BackForwardList.h new file mode 100644 index 000000000000..cace5635276b --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/BackForwardList.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (C) 2009 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "WebCore/BackForwardClient.h" +#include +#include + +typedef Vector> HistoryItemVector; +typedef HashSet> HistoryItemHashSet; + +class BackForwardList : public WebCore::BackForwardClient { +public: + static Ref create() { return adoptRef(*new BackForwardList()); } + virtual ~BackForwardList(); + + void addItem(Ref&&) override; + //void goBack() override; + //void goForward() override; + void goToItem(WebCore::HistoryItem&) override; + + //WebCore::HistoryItem& backItem() override; + //WebCore::HistoryItem& currentItem() override; + //WebCore::HistoryItem& forwardItem() override; + RefPtr itemAtIndex(int) override; + + //void backListWithLimit(int, HistoryItemVector&) override; + //void forwardListWithLimit(int, HistoryItemVector&) override; + + //int capacity() override; + //void setCapacity(int) override; + //bool enabled() override; + //void setEnabled(bool) override; + unsigned int backListCount(void) const override; + unsigned int forwardListCount(void) const override; + //bool containsItem(WebCore::HistoryItem*) override; + + void close() override; + //bool closed() override; + + //void removeItem(WebCore::HistoryItem&) override; + //HistoryItemVector& entries() override; + +private: + explicit BackForwardList(); + + HistoryItemVector m_entries; + HistoryItemHashSet m_entryHash; + unsigned m_current; + unsigned m_capacity; + bool m_closed; + bool m_enabled; +}; diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ChromeClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/ChromeClientHaiku.cpp new file mode 100644 index 000000000000..d4dd46751d93 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ChromeClientHaiku.cpp @@ -0,0 +1,537 @@ +/* + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007 Ryan Leavengood All rights reserved. + * Copyright (C) 2009 Maxime Simon All rights reserved. + * Copyright (C) 2010 Stephan Aßmus + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" // WebCore/config.h +#include "ChromeClientHaiku.h" + +#include "ColorChooserHaiku.h" +#include "DateTimeChooserHaiku.h" +#include "FileChooser.h" +#include "FileIconLoader.h" +#include "Frame.h" +#include "FrameLoadRequest.h" +#include "FrameLoader.h" +#include "FrameLoaderClientHaiku.h" +#include "FrameView.h" +#include "HitTestResult.h" +#include "Icon.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PopupMenuHaiku.h" +#include "SearchPopupMenuHaiku.h" +#include "WebFrame.h" +#include "WebView.h" +#include "WebWindow.h" +#include "WindowFeatures.h" + +#include +#include +#include +#include + + +namespace WebCore { + +ChromeClientHaiku::ChromeClientHaiku(BWebPage* webPage, BWebView* webView) + : m_webPage(webPage) + , m_webView(webView) +{ +} + +ChromeClientHaiku::~ChromeClientHaiku() +{ +} + +void ChromeClientHaiku::chromeDestroyed() +{ + delete this; +} + +void ChromeClientHaiku::setWindowRect(const FloatRect& rect) +{ + m_webPage->setWindowBounds(BRect(rect)); +} + +FloatRect ChromeClientHaiku::windowRect() +{ + return FloatRect(m_webPage->windowBounds()); +} + +FloatRect ChromeClientHaiku::pageRect() +{ + IntSize size = m_webPage->MainFrame()->Frame()->view()->contentsSize(); + return FloatRect(0, 0, size.width(), size.height()); +} + +void ChromeClientHaiku::focus() +{ + if (m_webView->LockLooper()) { + m_webView->MakeFocus(true); + m_webView->UnlockLooper(); + } +} + +void ChromeClientHaiku::unfocus() +{ + if (m_webView->LockLooper()) { + m_webView->MakeFocus(false); + m_webView->UnlockLooper(); + } +} + +bool ChromeClientHaiku::canTakeFocus(FocusDirection) +{ + return true; +} + +void ChromeClientHaiku::takeFocus(FocusDirection) +{ +} + +void ChromeClientHaiku::focusedElementChanged(Element* node) +{ + if (node) + focus(); + else + unfocus(); +} + +void ChromeClientHaiku::focusedFrameChanged(Frame*) +{ + notImplemented(); +} + +Page* ChromeClientHaiku::createWindow(Frame& /*frame*/, const FrameLoadRequest& /*request*/, const WindowFeatures& features, const NavigationAction& /*action*/) +{ + // FIXME: I believe the frame is important for cloning session information. + // From looking through the Chromium port code, it is passed to the + // method that creates a new WebView. I didn't find createView() implemented + // anywhere, but only this comment: + // + // // Create a new related WebView. This method must clone its session + // // storage so any subsequent calls to createSessionStorageNamespace + // // conform to the WebStorage specification. + // virtual WebView* createView(WebFrame* creator) { return 0; } + // + // (WebViewClient is probably what browsers or other embedders need to + // implement themselves, so this method is not implemented in the Chromium + // WebKit code.) + + BRect windowFrame; + // If any frame property of the features is set, the windowFrame will be valid and + // starts of as an offseted copy of the window frame where this page is embedded. + if (features.x || features.y || features.width || features.height) + windowFrame = m_webPage->windowFrame().OffsetByCopy(10, 10); + + if (features.x) + windowFrame.OffsetTo(*features.x, windowFrame.top); + if (features.y) + windowFrame.OffsetTo(windowFrame.left, *features.y); + if (features.width) + windowFrame.right = windowFrame.left + *features.width - 1; + if (features.height) + windowFrame.bottom = windowFrame.top + *features.height - 1; + + WebCore::Page* page = m_webPage->createNewPage(windowFrame, features.dialog, features.resizable); + if (!page) + return 0; + + return page; +} + +void ChromeClientHaiku::show() +{ + if (m_webView->LockLooper()) { + if (m_webView->Window()->IsHidden()) + m_webView->Window()->Show(); + m_webView->UnlockLooper(); + } +} + +bool ChromeClientHaiku::canRunModal() +{ + notImplemented(); + return false; +} + +void ChromeClientHaiku::runModal() +{ + notImplemented(); +} + +void ChromeClientHaiku::setToolbarsVisible(bool visible) +{ + m_webPage->setToolbarsVisible(visible); +} + +bool ChromeClientHaiku::toolbarsVisible() +{ + return m_webPage->areToolbarsVisible(); +} + +void ChromeClientHaiku::setStatusbarVisible(bool visible) +{ + m_webPage->setStatusbarVisible(visible); +} + +bool ChromeClientHaiku::statusbarVisible() +{ + return m_webPage->isStatusbarVisible(); +} + +void ChromeClientHaiku::setScrollbarsVisible(bool visible) +{ + m_webPage->MainFrame()->SetAllowsScrolling(visible); +} + +bool ChromeClientHaiku::scrollbarsVisible() +{ + return m_webPage->MainFrame()->AllowsScrolling(); +} + +void ChromeClientHaiku::setMenubarVisible(bool visible) +{ + m_webPage->setMenubarVisible(visible); +} + +bool ChromeClientHaiku::menubarVisible() +{ + return m_webPage->isMenubarVisible(); +} + +void ChromeClientHaiku::setResizable(bool resizable) +{ + m_webPage->setResizable(resizable); +} + +void ChromeClientHaiku::addMessageToConsole(MessageSource, MessageLevel, const String& message, + unsigned int lineNumber, unsigned columnNumber, const String& sourceID) +{ + m_webPage->addMessageToConsole(BString(sourceID), lineNumber, columnNumber, + BString(message)); +} + +bool ChromeClientHaiku::canRunBeforeUnloadConfirmPanel() +{ + return true; +} + +bool ChromeClientHaiku::runBeforeUnloadConfirmPanel(const String& message, Frame& frame) +{ + return runJavaScriptConfirm(frame, message); +} + +void ChromeClientHaiku::closeWindowSoon() +{ + // Make sure this Page can no longer be found by script code. + m_webPage->page()->setGroupName(String()); + + // Make sure all loading has stopped. + m_webPage->MainFrame()->Frame()->loader().stopAllLoaders(); + + m_webPage->closeWindow(); +} + +void ChromeClientHaiku::runJavaScriptAlert(Frame&, const String& msg) +{ + m_webPage->runJavaScriptAlert(BString(msg)); +} + +bool ChromeClientHaiku::runJavaScriptConfirm(Frame&, const String& msg) +{ + return m_webPage->runJavaScriptConfirm(BString(msg)); + BAlert* alert = new BAlert("JavaScript", BString(msg).String(), "Yes", "No"); + return !alert->Go(); +} + +bool ChromeClientHaiku::runJavaScriptPrompt(Frame&, const String& /*message*/, const String& /*defaultValue*/, String& /*result*/) +{ + notImplemented(); + return false; +} + + +std::unique_ptr ChromeClientHaiku::createColorChooser( + ColorChooserClient& client, const Color& color) +{ + return std::make_unique(&client, color); +} + + +void ChromeClientHaiku::setStatusbarText(const String& message) +{ + m_webPage->setStatusMessage(BString(message)); +} + +KeyboardUIMode ChromeClientHaiku::keyboardUIMode() +{ + return KeyboardAccessFull; +} + +void ChromeClientHaiku::invalidateRootView(const IntRect& rect) +{ + // This only invalidates the view, not the backing store. + BMessage message('inva'); + message.AddRect("bounds", BRect(rect)); + m_webView->Looper()->PostMessage(&message, m_webView); +} + +void ChromeClientHaiku::invalidateContentsAndRootView(const IntRect& rect) +{ + m_webPage->draw(BRect(rect)); +} + +void ChromeClientHaiku::invalidateContentsForSlowScroll(const IntRect&) +{ + // We can ignore this, since we implement fast scrolling. +} + +void ChromeClientHaiku::scroll(const IntSize& scrollDelta, + const IntRect& rectToScroll, + const IntRect& clipRect) +{ + if (!m_webView->IsComposited()) { + m_webPage->scroll(scrollDelta.width(), scrollDelta.height(), + rectToScroll, clipRect); + } +} + +#if USE(TILED_BACKING_STORE) +void ChromeClientHaiku::delegatedScrollRequested(const IntPoint& /*scrollPos*/) +{ + // Unused - we let WebKit handle the scrolling. + ASSERT(false); +} +#endif + + +IntPoint ChromeClientHaiku::screenToRootView(const IntPoint& point) const +{ + IntPoint windowPoint(point); + if (m_webView->LockLooperWithTimeout(5000) == B_OK) { + windowPoint = IntPoint(m_webView->ConvertFromScreen(BPoint(point))); + m_webView->UnlockLooper(); + } + return windowPoint; +} + +IntRect ChromeClientHaiku::rootViewToScreen(const IntRect& rect) const +{ + IntRect screenRect(rect); + if (m_webView->LockLooperWithTimeout(5000) == B_OK) { + screenRect = IntRect(m_webView->ConvertToScreen(BRect(rect))); + m_webView->UnlockLooper(); + } + return screenRect; +} + +PlatformPageClient ChromeClientHaiku::platformPageClient() const +{ + return m_webView; +} + +void ChromeClientHaiku::contentsSizeChanged(Frame&, const IntSize&) const +{ +} + +void ChromeClientHaiku::intrinsicContentsSizeChanged(const IntSize&) const +{ +} + +void ChromeClientHaiku::scrollRectIntoView(const IntRect&) const +{ + // NOTE: Used for example to make the view scroll with the mouse when selecting. +} + +void ChromeClientHaiku::mouseDidMoveOverElement(const HitTestResult& result, unsigned /*modifierFlags*/) +{ + TextDirection dir; + if (result.absoluteLinkURL() != lastHoverURL + || result.title(dir) != lastHoverTitle + || result.textContent() != lastHoverContent) { + lastHoverURL = result.absoluteLinkURL(); + lastHoverTitle = result.title(dir); + lastHoverContent = result.textContent(); + m_webPage->linkHovered(lastHoverURL.string(), lastHoverTitle, lastHoverContent); + } +} + +void ChromeClientHaiku::setToolTip(const String& tip, TextDirection) +{ + if (!m_webView->LockLooper()) + return; + + // FIXME: Unless HideToolTip() is called here, changing the tool tip has no + // effect in BView. Remove when BView is fixed. + m_webView->HideToolTip(); + if (!tip.length()) + m_webView->SetToolTip(reinterpret_cast(NULL)); + else + m_webView->SetToolTip(BString(tip).String()); + + m_webView->UnlockLooper(); +} + +void ChromeClientHaiku::print(Frame&) +{ + notImplemented(); +} + +void ChromeClientHaiku::exceededDatabaseQuota(Frame&, const String& /*databaseName*/, DatabaseDetails) +{ + notImplemented(); +} + +void ChromeClientHaiku::reachedMaxAppCacheSize(int64_t /*spaceNeeded*/) +{ + notImplemented(); +} + +void ChromeClientHaiku::reachedApplicationCacheOriginQuota(SecurityOrigin&, int64_t /*totalSpaceNeeded*/) +{ + notImplemented(); +} + +void ChromeClientHaiku::runOpenPanel(Frame&, FileChooser& chooser) +{ + BMessage message(B_REFS_RECEIVED); + message.AddPointer("chooser", &chooser); + BMessenger target(m_webPage); + BFilePanel* panel = new BFilePanel(B_OPEN_PANEL, &target, + &m_filePanelDirectory, 0, chooser.settings().allowsMultipleFiles, + &message, NULL, true, true); + + panel->Show(); +} + +void ChromeClientHaiku::loadIconForFiles(const Vector& filenames, FileIconLoader& loader) +{ + Icon::createIconForFiles(filenames); +} + +RefPtr ChromeClientHaiku::createIconForFiles(const Vector& filenames) +{ + return Icon::createIconForFiles(filenames); +} + +void ChromeClientHaiku::setCursor(const Cursor& cursor) +{ + if (!m_webView->LockLooper()) + return; + + m_webView->SetViewCursor(cursor.platformCursor()); + + m_webView->UnlockLooper(); +} + +#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER) +void ChromeClientHaiku::scheduleAnimation() +{ + ASSERT(false); + notImplemented(); +} +#endif + +bool ChromeClientHaiku::selectItemWritingDirectionIsNatural() +{ + return false; +} + +bool ChromeClientHaiku::selectItemAlignmentFollowsMenuWritingDirection() +{ + return false; +} + +RefPtr ChromeClientHaiku::createPopupMenu(PopupMenuClient& client) const +{ + return adoptRef(new PopupMenuHaiku(&client)); +} + +RefPtr ChromeClientHaiku::createSearchPopupMenu(PopupMenuClient& client) const +{ + return adoptRef(new SearchPopupMenuHaiku(&client)); +} + + +#if ENABLE(POINTER_LOCK) + +bool ChromeClientHaiku::requestPointerLock() { + return m_webView->Looper()->PostMessage('plok', m_webView) == B_OK; +} + +void ChromeClientHaiku::requestPointerUnlock() { + m_webView->Looper()->PostMessage('pulk', m_webView); +} + +bool ChromeClientHaiku::isPointerLocked() { + return m_webView->EventMask() & B_POINTER_EVENTS; +} + +#endif + + +void ChromeClientHaiku::attachRootGraphicsLayer(Frame&, GraphicsLayer* layer) +{ + m_webView->SetRootLayer(layer); +} + +void ChromeClientHaiku::attachViewOverlayGraphicsLayer(GraphicsLayer*) +{ + // FIXME: If we want view-relative page overlays, this would be the place to hook them up. + fprintf(stderr, "!!! Trying to create an overlay layer!\n"); + notImplemented(); +} + +void ChromeClientHaiku::setNeedsOneShotDrawingSynchronization() +{ + notImplemented(); +} + +void ChromeClientHaiku::scheduleCompositingLayerFlush() +{ + // Don't do anything if the view isn't ready yet. + if (!m_webView->LockLooper()) + return; + BRect r = m_webView->Bounds(); + m_webView->UnlockLooper(); + m_webPage->draw(r); +} + +WebCore::IntPoint ChromeClientHaiku::accessibilityScreenToRootView(WebCore::IntPoint const& point) const +{ + return point; +} + +WebCore::IntRect ChromeClientHaiku::rootViewToAccessibilityScreen(WebCore::IntRect const& rect) const +{ + return rect; +} + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ChromeClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/ChromeClientHaiku.h new file mode 100644 index 000000000000..7222ddcc72f5 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ChromeClientHaiku.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2007 Ryan Leavengood All rights reserved. + * Copyright (C) 2009 Maxime Simon All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ChromeClientHaiku_h +#define ChromeClientHaiku_h + +#include "ChromeClient.h" +#include "FloatRect.h" +#include "NotImplemented.h" +#include "wtf/URL.h" + +#include + +#include +#include "WebPage.h" + +namespace WebCore { + + class Page; + class WindowFeatures; + struct FrameLoadRequest; + + class ChromeClientHaiku : public ChromeClient { + public: + ChromeClientHaiku(BWebPage*, BWebView*); + virtual ~ChromeClientHaiku(); + void chromeDestroyed() override; + + void setWindowRect(const FloatRect&) override; + FloatRect windowRect() override; + + FloatRect pageRect() override; + + void focus() override; + void unfocus() override; + + bool canTakeFocus(FocusDirection) override; + void takeFocus(FocusDirection) override; + + void focusedElementChanged(Element*) override; + void focusedFrameChanged(Frame*) override; + + Page* createWindow(Frame&, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&) override; + + void show() override; + + bool canRunModal() override; + void runModal() override; + + void setToolbarsVisible(bool) override; + bool toolbarsVisible() override; + + void setStatusbarVisible(bool) override; + bool statusbarVisible() override; + + void setScrollbarsVisible(bool) override; + bool scrollbarsVisible() override; + + void setMenubarVisible(bool) override; + bool menubarVisible() override; + + void setResizable(bool) override; + + void addMessageToConsole(MessageSource, MessageLevel, + const String& message, unsigned int lineNumber, unsigned columnNumber, const String& sourceID) override; + + bool canRunBeforeUnloadConfirmPanel() override; + bool runBeforeUnloadConfirmPanel(const String& message, Frame& frame) override; + + void closeWindowSoon() override; + + void runJavaScriptAlert(Frame&, const String&) override; + bool runJavaScriptConfirm(Frame&, const String&) override; + bool runJavaScriptPrompt(Frame&, const String& message, const String& defaultValue, String& result) override; + std::unique_ptr createColorChooser(ColorChooserClient&, const Color&) override; + + KeyboardUIMode keyboardUIMode() override; + + void setStatusbarText(const String&) override; + + void invalidateRootView(const IntRect&) override; + void invalidateContentsAndRootView(const IntRect&) override; + + void invalidateContentsForSlowScroll(const IntRect&) override; + void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) override; + + IntPoint screenToRootView(const IntPoint&) const override; + IntRect rootViewToScreen(const IntRect&) const override; + + PlatformPageClient platformPageClient() const override; + void contentsSizeChanged(Frame&, const IntSize&) const override; + void intrinsicContentsSizeChanged(const IntSize&) const override; + void scrollRectIntoView(const IntRect&) const override; + void attachViewOverlayGraphicsLayer(WebCore::GraphicsLayer* layer) override; + + void setCursor(const Cursor&) override ; + void setCursorHiddenUntilMouseMoves(bool) override { } + + void didFinishLoadingImageForElement(HTMLImageElement&) override {} + +#if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER) + void scheduleAnimation() override; +#endif + + void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) override; + + void setToolTip(const String&, TextDirection) override; + + void print(Frame&) override; + + void exceededDatabaseQuota(Frame&, const String& databaseName, DatabaseDetails) override; + void reachedMaxAppCacheSize(int64_t spaceNeeded) override; + void reachedApplicationCacheOriginQuota(SecurityOrigin&, int64_t totalSpaceNeeded) override; + + void attachRootGraphicsLayer(Frame&, GraphicsLayer*) override; + void setNeedsOneShotDrawingSynchronization() override; + void scheduleCompositingLayerFlush() override; + + CompositingTriggerFlags allowedCompositingTriggers() const override + { + return static_cast(0); + } + + void runOpenPanel(Frame&, FileChooser&) override; + void setPanelDirectory(entry_ref dir) { m_filePanelDirectory = dir; } + + // Asynchronous request to load an icon for specified filenames. + void loadIconForFiles(const Vector&, FileIconLoader&) override; + RefPtr createIconForFiles(const Vector& filenames) override; + + bool selectItemWritingDirectionIsNatural() override; + bool selectItemAlignmentFollowsMenuWritingDirection() override; + RefPtr createPopupMenu(PopupMenuClient&) const override; + RefPtr createSearchPopupMenu(PopupMenuClient&) const override; + + void wheelEventHandlersChanged(bool) override { } + +#if ENABLE(POINTER_LOCK) + bool requestPointerLock() override; + void requestPointerUnlock() override; + bool isPointerLocked() override; +#endif + +#if USE(TILED_BACKING_STORE) + void delegatedScrollRequested(const WebCore::IntPoint& pos) override; +#endif + WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) const override; + WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) const override; + private: + BWebPage* m_webPage; + BWebView* m_webView; + + URL lastHoverURL; + String lastHoverTitle; + String lastHoverContent; + + entry_ref m_filePanelDirectory; + }; + +} // namespace WebCore + +#endif + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ColorChooserHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/ColorChooserHaiku.h new file mode 100644 index 000000000000..e9f0f8d8434e --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ColorChooserHaiku.h @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2014 Haiku, Inc. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" +#include "ColorChooser.h" + +#include "ColorChooserClient.h" + +#include +#include +#include +#include +#include +#include + +namespace WebCore { + +class ColorSwatch: public BButton { +public: + ColorSwatch(Color color) + : BButton("swatch", "", NULL) { + SetHighColor(color); + SetExplicitSize(BSize(16, 16)); + + BMessage* message = new BMessage('pick'); + rgb_color c(color); + message->AddData("RGBColor", B_RGB_COLOR_TYPE, &c, sizeof(c)); + SetMessage(message); + } + + void Draw(BRect updateRect) { + FillRect(updateRect); + // TODO should we add a border? + } +}; + +class ColorChooserWindow: public BWindow +{ +public: + ColorChooserWindow(ColorChooserClient& client) + : BWindow(client.elementRectRelativeToRootView(), "Color Picker", + B_FLOATING_WINDOW, B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_NOT_ZOOMABLE + | B_AUTO_UPDATE_SIZE_LIMITS) + , m_client(client) + { + SetLayout(new BGroupLayout(B_VERTICAL)); + BGroupView* group = new BGroupView(B_VERTICAL); + group->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + if (client.shouldShowSuggestions()) { + Vector colors = client.suggestedColors(); + + if (colors.size() > 0) { + BGroupView* swatches = new BGroupView(B_HORIZONTAL); + + for(Color c: colors) { + BButton* v = new ColorSwatch(c); + swatches->AddChild(v); + } + + group->AddChild(swatches); + } + } + + control = new BColorControl(B_ORIGIN, B_CELLS_32x8, 8, "picker", + new BMessage('chng')); + control->SetValue(m_client.currentColor()); + + BButton* ok = new BButton("ok", "Done", new BMessage('done')); + BButton* cancel = new BButton("cancel", "Cancel", new BMessage('canc')); + + m_preview = new ColorSwatch(m_client.currentColor()); + + BGroupLayoutBuilder(group) + .SetInsets(5, 5, 5, 5) + .Add(control) + .AddGroup(B_HORIZONTAL) + .Add(m_preview) + .AddGlue() + .Add(cancel) + .Add(ok) + .End() + .End(); + AddChild(group); + } + + void Hide() override { + m_client.didEndChooser(); + BWindow::Hide(); + } + + void MessageReceived(BMessage* message) { + switch(message->what) { + case 'pick': + { + rgb_color* c; + message->FindData("RGBColor", B_RGB_COLOR_TYPE, (const void**)&c, NULL); + control->SetValue(*c); + // fallthrough + } + case 'chng': + { + m_preview->SetHighColor(control->ValueAsColor()); + m_preview->Invalidate(); + return; + } + case 'done': + m_client.didChooseColor(control->ValueAsColor()); + // fallthrough + case 'canc': + Hide(); + return; + } + + BWindow::MessageReceived(message); + } + +private: + ColorChooserClient& m_client; + BColorControl* control; + ColorSwatch* m_preview; +}; + + +class ColorChooserHaiku: public ColorChooser +{ +public: + ColorChooserHaiku(ColorChooserClient* client, const Color& color) + : m_window(new ColorChooserWindow(*client)) + , m_client(*client) + { + reattachColorChooser(color); + } + + ~ColorChooserHaiku() + { + m_window->PostMessage(B_QUIT_REQUESTED); + } + + + void reattachColorChooser(const Color& color) override + { + setSelectedColor(color); + m_window->Show(); + } + + void setSelectedColor(const Color& color) override + { + m_client.didChooseColor(color); + } + + void endChooser() override { + m_window->Hide(); + } + +private: + BWindow* m_window; + ColorChooserClient& m_client; +}; + +} diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ContextMenuClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/ContextMenuClientHaiku.cpp new file mode 100644 index 000000000000..1dd2c58edaeb --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ContextMenuClientHaiku.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2010 Stephan Aßmus + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" +#include "ContextMenuClientHaiku.h" + +#include "ContextMenu.h" +#include "Document.h" +#include "Editor.h" +#include "Event.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameLoadRequest.h" +#include "HitTestResult.h" +#include "NotImplemented.h" +#include "Page.h" +#include "ResourceRequest.h" +#include "wtf/URL.h" +#include "WebPage.h" + + +namespace WebCore { + +ContextMenuClientHaiku::ContextMenuClientHaiku(BWebPage* webPage) + : m_webPage(webPage) +{ +} + +void ContextMenuClientHaiku::contextMenuDestroyed() +{ + delete this; +} + +void ContextMenuClientHaiku::downloadURL(const URL& url) +{ + ResourceRequest request(url); + m_webPage->requestDownload(request); +} + +void ContextMenuClientHaiku::searchWithGoogle(const Frame* frame) +{ + String searchString = frame->editor().selectedText(); + searchString.stripWhiteSpace(); + String encoded = encodeWithURLEscapeSequences(searchString); + encoded.replace("%20", "+"); + + String url("http://www.google.com/search?q="); + url.append(encoded); + + if (Page* page = frame->page()) { + UserGestureIndicator indicator(ProcessingUserGesture); + page->mainFrame().loader().urlSelected(URL({ }, url), + String("_blank"), 0, LockHistory::No, LockBackForwardList::No, + MaybeSendReferrer, frame->document()->shouldOpenExternalURLsPolicyToPropagate()); + } +} + +void ContextMenuClientHaiku::lookUpInDictionary(Frame*) +{ + notImplemented(); +} + +void ContextMenuClientHaiku::speak(const String&) +{ + notImplemented(); +} + +bool ContextMenuClientHaiku::isSpeaking() +{ + notImplemented(); + return false; +} + +void ContextMenuClientHaiku::stopSpeaking() +{ + notImplemented(); +} + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ContextMenuClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/ContextMenuClientHaiku.h new file mode 100644 index 000000000000..79666ef1b1cd --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ContextMenuClientHaiku.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2010 Stephan Aßmus + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ContextMenuClientHaiku_h +#define ContextMenuClientHaiku_h + +#include "ContextMenuClient.h" + +class BWebPage; + +namespace WebCore { + +class ContextMenu; + +class ContextMenuClientHaiku : public ContextMenuClient { +public: + ContextMenuClientHaiku(BWebPage*); + + void contextMenuDestroyed() override; + + void downloadURL(const URL& url) override; + void lookUpInDictionary(Frame*) override; + void speak(const String&) override; + bool isSpeaking() override; + void stopSpeaking() override; + void searchWithGoogle(const Frame*) override; + +private: + BWebPage* m_webPage; +}; + +} // namespace WebCore + +#endif // ContextMenuClientHaiku_h + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/DateTimeChooserHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/DateTimeChooserHaiku.h new file mode 100644 index 000000000000..8c68f5040f5a --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/DateTimeChooserHaiku.h @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2014 Haiku, Inc. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WebCore { + +class DateTimeChooserWindow: public BWindow +{ +public: + DateTimeChooserWindow(DateTimeChooserClient* client, + const DateTimeChooserParameters& params) + : BWindow(params.anchorRectInRootView, "Date Picker", B_FLOATING_WINDOW, + B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS) + , m_calendar(nullptr) + , m_client(client) + { + BGroupLayout* root = new BGroupLayout(B_VERTICAL); + root->SetSpacing(0); + SetLayout(root); + BGroupView* group = new BGroupView(B_HORIZONTAL); + group->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + group->GroupLayout()->SetInsets(5, 5, 5, 5); + AddChild(group); + + m_okButton = new BButton("ok", "Done", new BMessage('done')); + BButton* cancel = new BButton("cancel", "Cancel", new BMessage('canc')); + + BGroupView* bottomGroup = new BGroupView(B_HORIZONTAL); + bottomGroup->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + BGroupLayoutBuilder(bottomGroup) + .SetInsets(5, 5, 5, 5) + .AddGlue() + .Add(cancel) + .Add(m_okButton); + AddChild(bottomGroup); + + // TODO handle params.type to decide what to include in the window + // (may be only a month, or so - but should we use a popup menu in that + // case?) + + // FIXME we need to parse params.currentValue using other formats + // depending on the type: + // time: HH:mm + // datetime: yyyy-MM-dd-THH:mmZ + + // TODO we should also handle the list of suggestions from the params + // (probably as a BMenuField), and the min, max, and step values. + + if (params.type == InputTypeNames::datetime() + || params.type == InputTypeNames::datetimelocal() + || params.type == InputTypeNames::date() + || params.type == InputTypeNames::week() + || params.type == InputTypeNames::month()) { + BDateFormat format; + + m_yearControl = new BTextControl("year", NULL, NULL, + new BMessage('yech')); + m_yearControl->SetModificationMessage(new BMessage('yech')); + m_yearControl->TextView()->SetMaxBytes(6); + // TODO add filter on isdigit() only + + // Setup month menu + BMenu* monthMenu = new BMenu("month"); + monthMenu->SetLabelFromMarked(true); + + for (int i = 1; i <= 12; i++) { + BString out; + format.GetMonthName(i, out); + BMessage* message = new BMessage('moch'); + message->AddInt32("month", i); + monthMenu->AddItem(new BMenuItem(out, message)); + } + + // Build window + BGroupLayoutBuilder(group) + .AddGroup(B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .Add(new BMenuField(NULL, monthMenu)) + .Add(m_yearControl) + .End() + .Add(m_calendar = new BPrivate::BCalendarView("Date")) + .End() + .End(); + + // Parse initial date + BDate initialDate; + + if (params.type == InputTypeNames::date()) + format.SetDateFormat(B_LONG_DATE_FORMAT, "yyyy'-'MM'-'dd"); + else if (params.type == InputTypeNames::month()) { + format.SetDateFormat(B_LONG_DATE_FORMAT, "yyyy'-'MM"); + } else if (params.type == InputTypeNames::week()) + format.SetDateFormat(B_LONG_DATE_FORMAT, "yyyy'-W'ww"); + format.Parse(params.currentValue, B_LONG_DATE_FORMAT, initialDate); + + m_calendar->SetDate(initialDate); + + BString out; + format.SetDateFormat(B_SHORT_DATE_FORMAT, "yyyy"); + format.Format(out, initialDate, B_SHORT_DATE_FORMAT); + m_yearControl->SetText(out.String()); + + monthMenu->ItemAt(initialDate.Month() - 1)->SetMarked(true); + + } + + if (params.type == InputTypeNames::datetime() + || params.type == InputTypeNames::datetimelocal()) + group->AddChild(new BSeparatorView(B_VERTICAL)); + + if (params.type == InputTypeNames::datetime() + || params.type == InputTypeNames::datetimelocal() + || params.type == InputTypeNames::time()) { + m_hourMenu = new BMenu("hour"); + m_hourMenu->SetLabelFromMarked(true); + m_minuteMenu = new BMenu("minute"); + m_minuteMenu->SetLabelFromMarked(true); + + // Parse the initial time + BTimeFormat format; + BTime initialTime; + format.SetTimeFormat(B_SHORT_TIME_FORMAT, "HH':'mm"); + format.Parse(params.currentValue, B_SHORT_TIME_FORMAT, initialTime); + + for (int i = 0; i <= 24; i++) { + BString label; + label << i; // TODO we could be more locale safe here (AM/PM) + m_hourMenu->AddItem(new BMenuItem(label, NULL)); + } + + m_hourMenu->ItemAt(initialTime.Hour())->SetMarked(true); + + for (int i = 0; i <= 60; i++) { + BString label; + label << i; // TODO we could be more locale safe here + m_minuteMenu->AddItem(new BMenuItem(label, NULL)); + } + + m_minuteMenu->ItemAt(initialTime.Minute())->SetMarked(true); + + BGroupLayoutBuilder(group) + .AddGroup(B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .Add(new BMenuField(NULL, m_hourMenu)) + .Add(new BMenuField(NULL, m_minuteMenu)) + .AddGlue(); + } + + // Now show only the relevant parts of the window depending on the type + // and configure the output format + if (params.type == InputTypeNames::month()) { + m_format = "yyyy'-'MM"; + m_calendar->Hide(); + } else if (params.type == InputTypeNames::week()) { + m_format = "YYYY'-W'ww"; + } else if (params.type == InputTypeNames::date()) { + m_format = "yyyy'-'MM'-'dd"; + } else if (params.type == InputTypeNames::time()) { + m_format = "HH':'mm"; + } else { + // TODO datetime, datetime-local + } + + } + + void Hide() override { + m_client->didEndChooser(); + BWindow::Hide(); + } + + void MessageReceived(BMessage* message) { + switch(message->what) { + case 'done': + { + BString str; + // We must use the en_US format here because this is what WebKit + // expects. + BLanguage language("en"); + BFormattingConventions conventions("en_US"); + if (m_calendar) { + // TODO handle datetime format + conventions.SetExplicitDateFormat(B_LONG_DATE_FORMAT, m_format); + BDateFormat formatter(language, conventions); + formatter.Format(str, m_calendar->Date(), B_LONG_DATE_FORMAT); + } else { + // time-only format + str << m_hourMenu->Superitem()->Label(); + if (str.Length() < 2) str.Prepend("0"); + str << ':'; + str << m_minuteMenu->Superitem()->Label(); + } + m_client->didChooseValue(str); + // fallthrough + } + case 'canc': + Hide(); + return; + + case 'moch': + { + m_calendar->SetMonth(message->FindInt32("month")); + return; + } + + case 'yech': + { + char* p; + errno = 0; + int year = strtol(m_yearControl->Text(), &p, 10); + if (errno == ERANGE || year > 275759 || year <= 0 + || p == m_yearControl->Text() || *p != '\0') { + m_yearControl->MarkAsInvalid(true); + m_okButton->SetEnabled(false); // TODO not if other fields are invalid? + } else { + m_yearControl->MarkAsInvalid(false); + m_okButton->SetEnabled(true); + m_calendar->SetYear(year); + } + return; + } + } + + BWindow::MessageReceived(message); + } + +private: + BPrivate::BCalendarView* m_calendar; + BTextControl* m_yearControl; + BButton* m_okButton; + BMenu* m_hourMenu; + BMenu* m_minuteMenu; + BString m_format; + + DateTimeChooserClient* m_client; +}; + +class DateTimeChooserHaiku: public DateTimeChooser +{ +public: + DateTimeChooserHaiku(DateTimeChooserClient* client, + const DateTimeChooserParameters& params) + : m_window(new DateTimeChooserWindow(client, params)) + { + m_window->Show(); + } + + ~DateTimeChooserHaiku() + { + m_window->PostMessage(B_QUIT_REQUESTED); + } + + void endChooser() override + { + m_window->Hide(); + } + +private: + BWindow* m_window; +}; + +} + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/DragClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/DragClientHaiku.cpp new file mode 100644 index 000000000000..c9f2b2e9af1a --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/DragClientHaiku.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007 Ryan Leavengood + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DragClientHaiku.h" + +#include "NotImplemented.h" +#include "WebView.h" + + +namespace WebCore { + +DragClientHaiku::DragClientHaiku(BWebView* webView) + : m_webView(webView) +{} + +void DragClientHaiku::willPerformDragDestinationAction(DragDestinationAction, const DragData&) +{ + notImplemented(); +} + +void DragClientHaiku::dragControllerDestroyed() +{ + delete this; +} + +DragSourceAction DragClientHaiku::dragSourceActionMaskForPoint(const IntPoint&) +{ + notImplemented(); + return DragSourceActionAny; +} + +void DragClientHaiku::willPerformDragSourceAction(DragSourceAction, const IntPoint&, DataTransfer&) +{ + notImplemented(); +} + +void DragClientHaiku::startDrag(DragItem, DataTransfer&, Frame&) +{ + notImplemented(); +} + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/DragClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/DragClientHaiku.h new file mode 100644 index 000000000000..41d84468c79d --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/DragClientHaiku.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007 Ryan Leavengood + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "DragClient.h" + +class BWebView; + +namespace WebCore { + + class DragClientHaiku : public DragClient { + public: + DragClientHaiku(BWebView*); + virtual void willPerformDragDestinationAction(DragDestinationAction, const DragData&) override; + virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, DataTransfer&) override; + + virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint&) override; + + virtual void startDrag(DragItem, DataTransfer&, Frame&) override; + + virtual void dragControllerDestroyed() override; + private: + BWebView* m_webView; + }; + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/DumpRenderTreeSupportHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/DumpRenderTreeSupportHaiku.cpp new file mode 100644 index 000000000000..7a237594953c --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/DumpRenderTreeSupportHaiku.cpp @@ -0,0 +1,195 @@ +/* + Copyright (C) 2013 Haiku, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" +#include "DumpRenderTreeClient.h" +#include "FrameLoaderClientHaiku.h" + +#include "WebFrame.h" +#include "WebFramePrivate.h" +#include "WebPage.h" +#include "WebView.h" + +#include "DOMWrapperWorld.h" +#include +#include "WebCore/DocumentLoader.h" +#include "Document.h" +#include "DOMWindow.h" +#include "FocusController.h" +#include "Frame.h" +#include "WebCore/FrameLoader.h" +#include "FrameView.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PageGroup.h" +#include +#include +#include "UserContentTypes.h" + +#include "WebCore/Editor.h" + +namespace WebCore { + +bool DumpRenderTreeClient::s_drtRun = false; + +void DumpRenderTreeClient::setDumpRenderTreeModeEnabled(bool enabled) +{ + s_drtRun = enabled; +} + +bool DumpRenderTreeClient::dumpRenderTreeModeEnabled() +{ + return s_drtRun; +} + +void DumpRenderTreeClient::Register(BWebPage* page) +{ + page->fDumpRenderTree = this; +} + +void DumpRenderTreeClient::addUserScript(const BWebView* view, + const String& sourceCode, bool runAtStart, bool allFrames) +{ + // FIXME this was moved to viewGroup and this method should be public + // and part of the WebView API to match mac/ios/win. +#if 0 + view->WebPage()->page()->group().addUserScriptToWorld( + WebCore::mainThreadNormalWorld(), sourceCode, WebCore::URL(), + Vector(), Vector(), + runAtStart ? WebCore::InjectAtDocumentStart : WebCore::InjectAtDocumentEnd, + allFrames ? WebCore::InjectInAllFrames : WebCore::InjectInTopFrameOnly); +#endif +} + +void DumpRenderTreeClient::clearUserScripts(const BWebView* view) +{ +#if 0 + view->WebPage()->page()->group().removeUserScriptsFromWorld( + WebCore::mainThreadNormalWorld()); +#endif +} + + +void DumpRenderTreeClient::executeCoreCommandByName(const BWebView* view, + const BString name, const BString value) +{ + view->WebPage()->page()->focusController().focusedOrMainFrame().editor().command(name).execute(value); +} + + +void +DumpRenderTreeClient::setShouldTrackVisitedLinks(bool) +{ + notImplemented(); +} + + +unsigned DumpRenderTreeClient::pendingUnloadEventCount(const BWebFrame* frame) +{ + return frame->Frame()->document()->domWindow()->pendingUnloadEventListeners(); +} + + +String DumpRenderTreeClient::responseMimeType(const BWebFrame* frame) +{ + WebCore::DocumentLoader *documentLoader = frame->Frame()->loader().documentLoader(); + + if (!documentLoader) + return String(); + + return documentLoader->responseMIMEType(); +} + +// Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm +String DumpRenderTreeClient::suitableDRTFrameName(const BWebFrame* frame) +{ + const String frameName(frame->Frame()->tree().uniqueName()); + + if (frame->Frame() == &frame->fData->page->mainFrame()) { + if (!frameName.isEmpty()) + return String("main frame \"") + frameName + String("\""); + + return String("main frame"); + } + + if (!frameName.isEmpty()) + return String("frame \"") + frameName + String("\""); + + return String("frame (anonymous)"); +} + +BBitmap* DumpRenderTreeClient::getOffscreen(BWebView* view) +{ + view->OffscreenView()->LockLooper(); + view->OffscreenView()->Sync(); + view->OffscreenView()->UnlockLooper(); + return view->OffscreenBitmap(); +} + +BList DumpRenderTreeClient::frameChildren(BWebFrame* webFrame) +{ + WebCore::Frame* frame = webFrame->Frame(); + + BList childFrames; + + for (unsigned index = 0; index < frame->tree().childCount(); index++) { + WebCore::Frame *childFrame = frame->tree().child(index); + WebCore::FrameLoaderClientHaiku& client = static_cast(childFrame->loader().client()); + + childFrames.AddItem(client.webFrame()); + } + + return childFrames; +} + +void +DumpRenderTreeClient::setValueForUser(OpaqueJSContext const*, OpaqueJSValue const*, WTF::String const&) +{ + notImplemented(); +} + +void +DumpRenderTreeClient::setDomainRelaxationForbiddenForURLScheme(bool, WTF::String const&) +{ + notImplemented(); +} + +void +DumpRenderTreeClient::setSerializeHTTPLoads(bool) +{ + notImplemented(); +} + +JSGlobalContextRef DumpRenderTreeClient::globalContextRefForFrame(const BWebFrame* frame) +{ + return toGlobalRef(frame->Frame()->script().globalObject(WebCore::mainThreadNormalWorld())->globalExec()); +} + +void +DumpRenderTreeClient::setMockScrollbarsEnabled(bool enable) +{ + //WebCore::Settings::setMockScrollbarsEnabled(enable); +} + +} diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/EditCommandHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/EditCommandHaiku.h new file mode 100644 index 000000000000..5bac3d45e3de --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/EditCommandHaiku.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008 Kevin Ollivier + * Copyright (C) 2009 Maxime Simon + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EditCommandHaiku_h +#define EditCommandHaiku_h + +#include "EditCommand.h" + +#include +#include + +class EditCommandHaiku { +public: + EditCommandHaiku(WTF::PassRefPtr command) + { + m_editCommand = command; + } + + EditCommandHaiku() { } + WTF::PassRefPtr editCommand() { return m_editCommand; } + +private: + WTF::RefPtr m_editCommand; +}; + +#endif // EditCommandHaiku_h diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/EditorClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/EditorClientHaiku.cpp new file mode 100644 index 000000000000..ab98b6dc5f30 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/EditorClientHaiku.cpp @@ -0,0 +1,698 @@ +/* + * Copyright (C) 2006 Nikolas Zimmermann + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2007 Andrea Anzani + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "EditorClientHaiku.h" + +#include "Document.h" +#include "Editor.h" +#include "FocusController.h" +#include "Frame.h" +#include "FrameSelection.h" +#include "KeyboardEvent.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PlatformKeyboardEvent.h" +#include "Settings.h" +#include "WebFrame.h" +#include "WebViewConstants.h" +#include "WebPage.h" +#include "WindowsKeyboardCodes.h" + +namespace WebCore { + +EditorClientHaiku::EditorClientHaiku(BWebPage* page) + : m_page(page) + , m_isInRedo(false) +{ +} + +bool EditorClientHaiku::shouldDeleteRange(Range* range) +{ + BMessage message(EDITOR_DELETE_RANGE); + message.AddPointer("range", range); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::smartInsertDeleteEnabled() +{ + notImplemented(); + return false; +} + +bool EditorClientHaiku::isContinuousSpellCheckingEnabled() +{ + notImplemented(); + return false; +} + +void EditorClientHaiku::toggleContinuousSpellChecking() +{ + notImplemented(); +} + +bool EditorClientHaiku::isGrammarCheckingEnabled() +{ + notImplemented(); + return false; +} + +void EditorClientHaiku::toggleGrammarChecking() +{ + notImplemented(); +} + +int EditorClientHaiku::spellCheckerDocumentTag() +{ + notImplemented(); + return 0; +} + +bool EditorClientHaiku::shouldBeginEditing(WebCore::Range* range) +{ + BMessage message(EDITOR_BEGIN_EDITING); + message.AddPointer("range", range); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::shouldEndEditing(WebCore::Range* range) +{ + BMessage message(EDITOR_END_EDITING); + message.AddPointer("range", range); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::shouldInsertNode(Node* node, Range* range, EditorInsertAction action) +{ + BMessage message(EDITOR_INSERT_NODE); + message.AddPointer("node", node); + message.AddPointer("range", range); + message.AddInt32("action", (int32)action); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::shouldInsertText(const String& text, Range* range, EditorInsertAction action) +{ + BMessage message(EDITOR_INSERT_TEXT); + message.AddString("text", text); + message.AddPointer("range", range); + message.AddInt32("action", (int32)action); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::shouldChangeSelectedRange(Range* fromRange, Range* toRange, + EAffinity affinity, bool stillSelecting) +{ + BMessage message(EDITOR_CHANGE_SELECTED_RANGE); + message.AddPointer("from", fromRange); + message.AddPointer("to", toRange); + message.AddInt32("affinity", affinity); + message.AddInt32("stillEditing", stillSelecting); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::shouldApplyStyle(WebCore::StyleProperties* style, + WebCore::Range* range) +{ + BMessage message(EDITOR_APPLY_STYLE); + message.AddPointer("style", style); + message.AddPointer("range", range); + dispatchMessage(message); + return true; +} + +bool EditorClientHaiku::shouldMoveRangeAfterDelete(Range*, Range*) +{ + notImplemented(); + return true; +} + +void EditorClientHaiku::didBeginEditing() +{ + BMessage message(EDITOR_EDITING_BEGAN); + dispatchMessage(message); +} + +void EditorClientHaiku::respondToChangedContents() +{ + BMessage message(EDITOR_CONTENTS_CHANGED); + dispatchMessage(message); +} + +void EditorClientHaiku::respondToChangedSelection(Frame* frame) +{ + if (!frame) + return; + + BMessage message(EDITOR_SELECTION_CHANGED); + dispatchMessage(message); +} + +void EditorClientHaiku::didEndEditing() +{ + BMessage message(EDITOR_EDITING_ENDED); + dispatchMessage(message); +} + +void EditorClientHaiku::didWriteSelectionToPasteboard() +{ + notImplemented(); +} + +bool EditorClientHaiku::isSelectTrailingWhitespaceEnabled() const +{ + notImplemented(); + return false; +} + +void EditorClientHaiku::willWriteSelectionToPasteboard(WebCore::Range*) +{ +} + +void EditorClientHaiku::getClientPasteboardDataForRange(WebCore::Range*, Vector&, Vector >&) +{ +} + +void EditorClientHaiku::discardedComposition(Frame*) +{ +} + +void EditorClientHaiku::canceledComposition() +{ +} + +void EditorClientHaiku::registerUndoStep(WebCore::UndoStep& step) +{ + if (!m_isInRedo) + m_redoStack.clear(); + m_undoStack.append(&step); +} + +void EditorClientHaiku::registerRedoStep(WebCore::UndoStep& step) +{ + m_redoStack.append(&step); +} + +void EditorClientHaiku::clearUndoRedoOperations() +{ + m_undoStack.clear(); + m_redoStack.clear(); +} + +bool EditorClientHaiku::canCopyCut(WebCore::Frame*, bool defaultValue) const +{ + return defaultValue; +} + +bool EditorClientHaiku::canPaste(WebCore::Frame*, bool defaultValue) const +{ + return defaultValue; +} + +bool EditorClientHaiku::canUndo() const +{ + return !m_undoStack.isEmpty(); +} + +bool EditorClientHaiku::canRedo() const +{ + return !m_redoStack.isEmpty(); +} + +void EditorClientHaiku::undo() +{ + if (canUndo()) { + RefPtr step(m_undoStack.takeLast()); + // unapply will call us back to push this step onto the redo stack. + step->unapply(); + } +} + +void EditorClientHaiku::redo() +{ + if (canRedo()) { + RefPtr step(m_redoStack.takeLast()); + + ASSERT(!m_isInRedo); + m_isInRedo = true; + // reapply will call us back to push this step onto the undo stack. + step->reapply(); + m_isInRedo = false; + } +} + +#if 0 +static const unsigned CtrlKey = 1 << 0; +static const unsigned AltKey = 1 << 1; +static const unsigned ShiftKey = 1 << 2; + +struct KeyDownEntry { + unsigned virtualKey; + unsigned modifiers; + const char* name; +}; + +struct KeyPressEntry { + unsigned charCode; + unsigned modifiers; + const char* name; +}; + +static const KeyDownEntry keyDownEntries[] = { + { VK_LEFT, 0, "MoveLeft" }, + { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" }, + { VK_LEFT, CtrlKey, "MoveWordLeft" }, + { VK_LEFT, CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection" }, + { VK_RIGHT, 0, "MoveRight" }, + { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" }, + { VK_RIGHT, CtrlKey, "MoveWordRight" }, + { VK_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" }, + { VK_UP, 0, "MoveUp" }, + { VK_UP, ShiftKey, "MoveUpAndModifySelection" }, + { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" }, + { VK_DOWN, 0, "MoveDown" }, + { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" }, + { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" }, + { VK_PRIOR, 0, "MovePageUp" }, + { VK_NEXT, 0, "MovePageDown" }, + { VK_HOME, 0, "MoveToBeginningOfLine" }, + { VK_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" }, + { VK_HOME, CtrlKey, "MoveToBeginningOfDocument" }, + { VK_HOME, CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" }, + + { VK_END, 0, "MoveToEndOfLine" }, + { VK_END, ShiftKey, "MoveToEndOfLineAndModifySelection" }, + { VK_END, CtrlKey, "MoveToEndOfDocument" }, + { VK_END, CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection" }, + + { VK_BACK, 0, "DeleteBackward" }, + { VK_BACK, ShiftKey, "DeleteBackward" }, + { VK_DELETE, 0, "DeleteForward" }, + { VK_BACK, CtrlKey, "DeleteWordBackward" }, + { VK_DELETE, CtrlKey, "DeleteWordForward" }, + + { 'B', CtrlKey, "ToggleBold" }, + { 'I', CtrlKey, "ToggleItalic" }, + + { VK_ESCAPE, 0, "Cancel" }, + { VK_OEM_PERIOD, CtrlKey, "Cancel" }, + { VK_TAB, 0, "InsertTab" }, + { VK_TAB, ShiftKey, "InsertBacktab" }, + { VK_RETURN, 0, "InsertNewline" }, + { VK_RETURN, ShiftKey, "InsertLineBreak" }, + { VK_RETURN, CtrlKey, "InsertNewline" }, + { VK_RETURN, AltKey, "InsertNewline" }, + { VK_RETURN, AltKey | ShiftKey, "InsertNewline" }, +}; + +static const KeyPressEntry keyPressEntries[] = { + { '\t', 0, "InsertTab" }, + { '\t', ShiftKey, "InsertBacktab" }, + { '\r', 0, "InsertNewline" }, + { '\r', ShiftKey, "InsertLineBreak" }, + { '\r', CtrlKey, "InsertNewline" }, + { '\r', AltKey, "InsertNewline" }, + { '\r', AltKey | ShiftKey, "InsertNewline" }, +}; + +static const char* interpretEditorCommandKeyEvent(const KeyboardEvent* evt) +{ + ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent); + + static HashMap* keyDownCommandsMap = 0; + static HashMap* keyPressCommandsMap = 0; + + if (!keyDownCommandsMap) { + keyDownCommandsMap = new HashMap; + keyPressCommandsMap = new HashMap; + + for (unsigned i = 0; i < sizeof(keyDownEntries) / sizeof(KeyDownEntry); i++) + keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); + + for (unsigned i = 0; i < sizeof(keyPressEntries) / sizeof(KeyPressEntry); i++) + keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name); + } + + unsigned modifiers = 0; + if (evt->shiftKey()) + modifiers |= ShiftKey; + if (evt->altKey()) + modifiers |= AltKey; + if (evt->controlKey()) + modifiers |= CtrlKey; + + if (evt->type() == eventNames().keydownEvent) { + int mapKey = modifiers << 16 | evt->keyCode(); + return mapKey ? keyDownCommandsMap->get(mapKey) : 0; + } + + int mapKey = modifiers << 16 | evt->charCode(); + return mapKey ? keyPressCommandsMap->get(mapKey) : 0; +} +#endif + +void EditorClientHaiku::handleKeyboardEvent(KeyboardEvent& event) +{ + const PlatformKeyboardEvent* platformEvent = event.underlyingPlatformEvent(); + if (!platformEvent || platformEvent->type() == PlatformKeyboardEvent::KeyUp) + return; + + if (handleEditingKeyboardEvent(&event, platformEvent)) { + event.setDefaultHandled(); + } +} + +void EditorClientHaiku::handleInputMethodKeydown(KeyboardEvent&) +{ + notImplemented(); +} + +void EditorClientHaiku::textFieldDidBeginEditing(Element*) +{ +} + +void EditorClientHaiku::textFieldDidEndEditing(Element*) +{ +} + +void EditorClientHaiku::textDidChangeInTextField(Element*) +{ +} + +bool EditorClientHaiku::doTextFieldCommandFromEvent(Element*, KeyboardEvent*) +{ + return false; +} + +void EditorClientHaiku::textWillBeDeletedInTextField(Element*) +{ + notImplemented(); +} + +void EditorClientHaiku::textDidChangeInTextArea(Element*) +{ + notImplemented(); +} + +void EditorClientHaiku::overflowScrollPositionChanged() +{ + notImplemented(); +} + +bool EditorClientHaiku::shouldEraseMarkersAfterChangeSelection(TextCheckingType) const +{ + return true; +} + +void EditorClientHaiku::ignoreWordInSpellDocument(const String&) +{ + notImplemented(); +} + +void EditorClientHaiku::learnWord(const String&) +{ + notImplemented(); +} + +void EditorClientHaiku::checkSpellingOfString(StringView, int*, int*) +{ + notImplemented(); +} + +String EditorClientHaiku::getAutoCorrectSuggestionForMisspelledWord(const String& /*misspelledWord*/) +{ + notImplemented(); + return String(); +} + +void EditorClientHaiku::checkGrammarOfString(StringView, Vector&, int*, int*) +{ + notImplemented(); +} + +void EditorClientHaiku::getGuessesForWord(const String&, const String&, const WebCore::VisibleSelection&, Vector&) +{ + notImplemented(); +} + +void EditorClientHaiku::requestCheckingOfString(TextCheckingRequest&, const WebCore::VisibleSelection&) +{ + notImplemented(); +} + +void EditorClientHaiku::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) +{ + notImplemented(); +} + +void EditorClientHaiku::updateSpellingUIWithMisspelledWord(const String&) +{ + notImplemented(); +} + +void EditorClientHaiku::showSpellingUI(bool) +{ + notImplemented(); +} + +bool EditorClientHaiku::spellingUIIsShowing() +{ + notImplemented(); + return false; +} + +void EditorClientHaiku::willSetInputMethodState() +{ + notImplemented(); +} + +void EditorClientHaiku::setInputMethodState(bool /*enabled*/) +{ + notImplemented(); +} + +bool EditorClientHaiku::performTwoStepDrop(DocumentFragment&, Range& destination, bool isMove) +{ + notImplemented(); + return false; +} + +// #pragma mark - + +bool EditorClientHaiku::handleEditingKeyboardEvent(KeyboardEvent* event, + const PlatformKeyboardEvent* platformEvent) +{ + Frame& frame = m_page->page()->focusController().focusedOrMainFrame(); + if (!frame.document()) + return false; + + // TODO be more specific when filtering events here. Some of the keys are + // relevant only when there is a range-selection (shift+arrows to edit it), + // but others are only relevant when there is an edition going on + // (backspace, delete). We should check these different cases depending on + // the key, and decide to swallow the event (return true) or not, in which + // case the BWebFrame code can handle it for scrolling or other keyboard + // shortcuts. + if (!frame.selection().isRange() && !frame.editor().canEdit()) + return false; + + switch (platformEvent->windowsVirtualKeyCode()) { + case VK_BACK: + frame.editor().deleteWithDirection(DirectionBackward, + platformEvent->controlKey() ? WordGranularity : CharacterGranularity, + false, true); + break; + case VK_DELETE: + frame.editor().deleteWithDirection(DirectionForward, + platformEvent->controlKey() ? WordGranularity : CharacterGranularity, + false, true); + break; + case VK_LEFT: + frame.selection().modify(platformEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove, + DirectionLeft, + platformEvent->controlKey() ? WordGranularity : CharacterGranularity, + UserTriggered); + break; + case VK_RIGHT: + frame.selection().modify(platformEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove, + DirectionRight, + platformEvent->controlKey() ? WordGranularity : CharacterGranularity, + UserTriggered); + break; + case VK_UP: + frame.selection().modify(platformEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove, + DirectionBackward, + platformEvent->controlKey() ? ParagraphGranularity : LineGranularity, + UserTriggered); + break; + case VK_DOWN: + frame.selection().modify(platformEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove, + DirectionForward, + platformEvent->controlKey() ? ParagraphGranularity : LineGranularity, + UserTriggered); + break; + case VK_HOME: + if (platformEvent->shiftKey() && platformEvent->controlKey()) + frame.editor().command("MoveToBeginningOfDocumentAndModifySelection").execute(); + else if (platformEvent->shiftKey()) + frame.editor().command("MoveToBeginningOfLineAndModifySelection").execute(); + else if (platformEvent->controlKey()) + frame.editor().command("MoveToBeginningOfDocument").execute(); + else + frame.editor().command("MoveToBeginningOfLine").execute(); + break; + case VK_END: + if (platformEvent->shiftKey() && platformEvent->controlKey()) + frame.editor().command("MoveToEndOfDocumentAndModifySelection").execute(); + else if (platformEvent->shiftKey()) + frame.editor().command("MoveToEndOfLineAndModifySelection").execute(); + else if (platformEvent->controlKey()) + frame.editor().command("MoveToEndOfDocument").execute(); + else + frame.editor().command("MoveToEndOfLine").execute(); + break; + case VK_PRIOR: // PageUp + if (platformEvent->shiftKey()) + frame.editor().command("MovePageUpAndModifySelection").execute(); + else + frame.editor().command("MovePageUp").execute(); + break; + case VK_NEXT: // PageDown + if (platformEvent->shiftKey()) + frame.editor().command("MovePageDownAndModifySelection").execute(); + else + frame.editor().command("MovePageDown").execute(); + break; + case VK_RETURN: + if (platformEvent->shiftKey()) + frame.editor().command("InsertLineBreak").execute(); + else + frame.editor().command("InsertNewline").execute(); + break; + case VK_TAB: + return false; + default: + if (!platformEvent->controlKey() && !platformEvent->altKey() && !platformEvent->text().isEmpty()) { + if (platformEvent->text().length() == 1) { + UChar ch = platformEvent->text()[0]; + // Don't insert null or control characters as they can result in unexpected behaviour + if (ch < ' ') + break; + } + frame.editor().insertText(platformEvent->text(), event); + } else if (platformEvent->controlKey()) { + switch (platformEvent->windowsVirtualKeyCode()) { + case VK_B: + frame.editor().command("ToggleBold").execute(); + break; + case VK_I: + frame.editor().command("ToggleItalic").execute(); + break; + case VK_V: + frame.editor().command("Paste").execute(); + break; + case VK_X: + frame.editor().command("Cut").execute(); + break; + case VK_Y: + case VK_Z: + if (platformEvent->shiftKey()) + frame.editor().command("Redo").execute(); + else + frame.editor().command("Undo").execute(); + break; + case VK_A: + frame.editor().command("SelectAll").execute(); + break; + case VK_C: + frame.editor().command("Copy").execute(); + break; + default: + return false; + } + } else + return false; + } + + return true; +} + +void EditorClientHaiku::setPendingComposition(const char* newComposition) +{ + m_pendingComposition = newComposition; +} + +void EditorClientHaiku::setPendingPreedit(const char* newPreedit) +{ + m_pendingPreedit = newPreedit; +} + +void EditorClientHaiku::clearPendingIMData() +{ + setPendingComposition(0); + setPendingPreedit(0); +} + +void EditorClientHaiku::imContextCommitted(const char* str, EditorClient* /*client*/) +{ + // This signal will fire during a keydown event. We want the contents of the + // field to change right before the keyup event, so we wait until then to actually + // commit this composition. + setPendingComposition(str); +} + +void EditorClientHaiku::imContextPreeditChanged(EditorClient* /*client*/) +{ + const char* newPreedit = 0; + // FIXME: get pre edit + setPendingPreedit(newPreedit); +} + + +void EditorClientHaiku::dispatchMessage(BMessage& message) +{ + BHandler* handler = m_page->fListener.Target(NULL); + if (!handler) + return; + handler->MessageReceived(&message); + // We need the message to be delivered synchronously, otherwise the + // pointers passed through it would not be valid anymore. +} + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/EditorClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/EditorClientHaiku.h new file mode 100644 index 000000000000..1b5cd27a8a03 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/EditorClientHaiku.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2006 Nikolas Zimmermann + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EditorClientHaiku_h +#define EditorClientHaiku_h + +#include "EditorClient.h" +#include "Page.h" +#include "TextCheckerClient.h" +#include +#include +#include +#include "wtf/text/StringView.h" +#include + +class BMessage; +class BWebPage; + +namespace WebCore { +class PlatformKeyboardEvent; + +class EditorClientHaiku : public EditorClient, public TextCheckerClient { +public: + EditorClientHaiku(BWebPage* page); + + bool shouldDeleteRange(Range*) override; + bool smartInsertDeleteEnabled() override; + bool isContinuousSpellCheckingEnabled() override; + void toggleContinuousSpellChecking() override; + bool isGrammarCheckingEnabled() override; + void toggleGrammarChecking() override; + int spellCheckerDocumentTag() override; + + bool shouldBeginEditing(Range*) override; + bool shouldEndEditing(Range*) override; + bool shouldInsertNode(Node*, Range*, EditorInsertAction) override; + bool shouldInsertText(const String&, Range*, EditorInsertAction) override; + bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, + EAffinity, bool stillSelecting) override; + + bool shouldApplyStyle(StyleProperties*, Range*) override; + bool shouldMoveRangeAfterDelete(Range*, Range*) override; + + void didBeginEditing() override; + void didEndEditing() override; + void didApplyStyle() override {}; + + bool isSelectTrailingWhitespaceEnabled() const override; + void willWriteSelectionToPasteboard(WebCore::Range*) override; + void didWriteSelectionToPasteboard() override; + void getClientPasteboardDataForRange(WebCore::Range*, Vector& pasteboardTypes, Vector >& pasteboardData) override; + + void respondToChangedContents() override; + void respondToChangedSelection(Frame*) override; + void discardedComposition(Frame*) override; + void canceledComposition() override; + + void registerUndoStep(UndoStep&) override; + void registerRedoStep(UndoStep&) override; + void clearUndoRedoOperations() override; + + bool canCopyCut(Frame*, bool defaultValue) const override; + bool canPaste(Frame*, bool defaultValue) const override; + bool canUndo() const override; + bool canRedo() const override; + + void undo() override; + void redo() override; + + void handleKeyboardEvent(KeyboardEvent&) override; + void handleInputMethodKeydown(KeyboardEvent&) override; + + void textFieldDidBeginEditing(Element*) override; + void textFieldDidEndEditing(Element*) override; + void textDidChangeInTextField(Element*) override; + bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*) override; + void textWillBeDeletedInTextField(Element*) override; + void textDidChangeInTextArea(Element*) override; + void overflowScrollPositionChanged() override; + void updateEditorStateAfterLayoutIfEditabilityChanged() override {}; + void didEndUserTriggeredSelectionChanges() override {}; + void didUpdateComposition() override {}; + + TextCheckerClient* textChecker() override { return this; } + + void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) override; + void updateSpellingUIWithMisspelledWord(const String&) override; + void showSpellingUI(bool show) override; + bool spellingUIIsShowing() override; + void willSetInputMethodState() override; + void setInputMethodState(bool enabled) override; + + bool performTwoStepDrop(DocumentFragment&, Range& destination, bool isMove) override; + // TextCheckerClient + + bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const override; + void ignoreWordInSpellDocument(const String&) override; + void learnWord(const String&) override; + void checkSpellingOfString(StringView, int* misspellingLocation, + int* misspellingLength) override; + String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) override; + void checkGrammarOfString(StringView, Vector&, + int* badGrammarLocation, int* badGrammarLength) override; + + void getGuessesForWord(const String& word, const String& context, const WebCore::VisibleSelection&, Vector& guesses) override; + void requestCheckingOfString(TextCheckingRequest&, const VisibleSelection& currentSelection) override; + + WebCore::DOMPasteAccessResponse requestDOMPasteAccess(const String&) final { return WebCore::DOMPasteAccessResponse::DeniedForGesture;} + +private: + bool handleEditingKeyboardEvent(KeyboardEvent* event, + const PlatformKeyboardEvent* platformEvent); + void setPendingComposition(const char* newComposition); + void setPendingPreedit(const char* newPreedit); + void clearPendingIMData(); + void imContextCommitted(const char* str, EditorClient* client); + void imContextPreeditChanged(EditorClient* client); + + void dispatchMessage(BMessage& message); + + BWebPage* m_page; + + typedef Deque> UndoManagerStack; + UndoManagerStack m_undoStack; + UndoManagerStack m_redoStack; + + bool m_isInRedo; + + BString m_pendingComposition; + BString m_pendingPreedit; +}; + +} // namespace WebCore + +#endif // EditorClientHaiku_h + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/FrameLoaderClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameLoaderClientHaiku.cpp new file mode 100644 index 000000000000..c81b815174cc --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameLoaderClientHaiku.cpp @@ -0,0 +1,1076 @@ +/* + * Copyright (C) 2006 Don Gibson + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007 Trolltech ASA + * Copyright (C) 2007 Ryan Leavengood All rights reserved. + * Copyright (C) 2009 Maxime Simon All rights reserved. + * Copyright (C) 2010 Stephan Aßmus + * Copyright (C) 2010 Michael Lotz + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FrameLoaderClientHaiku.h" + +#include "AuthenticationChallenge.h" +#include "BackForwardController.h" +#include "Credential.h" +#include "CachedFrame.h" +#include "DocumentLoader.h" +#include "DumpRenderTreeClient.h" +#include "FormState.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "FrameNetworkingContextHaiku.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "HTMLFormElement.h" +#include "HTMLFrameOwnerElement.h" +#include "HTTPParsers.h" +#include "IconDatabase.h" +#include "MouseEvent.h" +#include "MIMETypeRegistry.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PluginData.h" +#include "ProgressTracker.h" +#include "RenderFrame.h" +#include "ResourceRequest.h" +#include "SchemeRegistry.h" +#include "ScriptController.h" +#include "Settings.h" +#include "WebFrame.h" +#include "WebFramePrivate.h" +#include "WebKitInfo.h" +#include "WebPage.h" +#include "WebView.h" +#include "WebViewConstants.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define TRACE_FRAME_LOADER_CLIENT +#ifdef TRACE_FRAME_LOADER_CLIENT +# define CLASS_NAME "FLC" +# include "FunctionTracer.h" +#else +# define CALLED(x...) +# define TRACE(x...) +#endif + +namespace WebCore { + +FrameLoaderClientHaiku::FrameLoaderClientHaiku(BWebPage* webPage) + : m_webPage(webPage) + , m_webFrame(nullptr) + , m_messenger() + , m_loadingErrorPage(false) + , m_uidna_context(nullptr) +{ + CALLED("BWebPage: %p", webPage); + ASSERT(m_webPage); +} + +void FrameLoaderClientHaiku::setDispatchTarget(const BMessenger& messenger) +{ + m_messenger = messenger; +} + +BWebPage* FrameLoaderClientHaiku::page() const +{ + return m_webPage; +} + +void FrameLoaderClientHaiku::frameLoaderDestroyed() +{ + CALLED(); + + uidna_close(m_uidna_context); + delete m_webFrame; + // The frame takes care of deleting us. When that call returns, the + // frame loader object is gone! +} + +WTF::Optional FrameLoaderClientHaiku::pageID() const +{ + return {}; +} + +WTF::Optional FrameLoaderClientHaiku::frameID() const +{ + return {}; +} + +PAL::SessionID FrameLoaderClientHaiku::sessionID() const +{ + RELEASE_ASSERT_NOT_REACHED(); + return PAL::SessionID::defaultSessionID(); +} + +bool FrameLoaderClientHaiku::hasWebView() const +{ + return m_webPage->WebView(); +} + +void FrameLoaderClientHaiku::makeRepresentation(DocumentLoader*) +{ +} + +void FrameLoaderClientHaiku::forceLayoutForNonHTML() +{ +} + +void FrameLoaderClientHaiku::setCopiesOnScroll() +{ + // Other ports mention "apparently mac specific", but I believe it may have to + // do with achieving that WebCore does not repaint the parts that we can scroll + // by blitting. +} + +void FrameLoaderClientHaiku::detachedFromParent2() +{ +} + +void FrameLoaderClientHaiku::detachedFromParent3() +{ +} + +bool FrameLoaderClientHaiku::dispatchDidLoadResourceFromMemoryCache(DocumentLoader* /*loader*/, + const ResourceRequest& /*request*/, + const ResourceResponse& /*response*/, + int /*length*/) +{ + notImplemented(); + return false; +} + +void FrameLoaderClientHaiku::assignIdentifierToInitialRequest(unsigned long /*identifier*/, + DocumentLoader* /*loader*/, + const ResourceRequest& /*request*/) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchWillSendRequest(DocumentLoader* /*loader*/, unsigned long /*identifier*/, + ResourceRequest& /*request*/, + const ResourceResponse& /*redirectResponse*/) +{ + notImplemented(); +} + +bool FrameLoaderClientHaiku::shouldUseCredentialStorage(DocumentLoader*, unsigned long) +{ + notImplemented(); + return false; +} + +void FrameLoaderClientHaiku::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge) +{ + const ProtectionSpace& space = challenge.protectionSpace(); + String text = "Host \"" + space.host() + "\" requests authentication for realm \"" + space.realm() + "\"\n"; + text.append("Authentication Scheme: "); + switch (space.authenticationScheme()) { + case ProtectionSpaceAuthenticationSchemeHTTPBasic: + text.append("Basic (data will be sent as plain text)"); + break; + case ProtectionSpaceAuthenticationSchemeHTTPDigest: + text.append("Digest (data will not be sent plain text)"); + break; + default: + text.append("Unknown (possibly plaintext)"); + break; + } + + BMessage challengeMessage(AUTHENTICATION_CHALLENGE); + challengeMessage.AddString("text", text); + challengeMessage.AddString("user", challenge.proposedCredential().user()); + challengeMessage.AddString("password", challenge.proposedCredential().password()); + challengeMessage.AddUInt32("failureCount", challenge.previousFailureCount()); + challengeMessage.AddPointer("view", m_webPage->WebView()); + + BMessage authenticationReply; + m_messenger.SendMessage(&challengeMessage, &authenticationReply); + + BString user; + BString password; + if (authenticationReply.FindString("user", &user) != B_OK + || authenticationReply.FindString("password", &password) != B_OK) { + challenge.authenticationClient()->receivedCancellation(challenge); + } else { + if (!user.Length() && !password.Length()) + challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); + else { + bool rememberCredentials = false; + CredentialPersistence persistence = CredentialPersistenceForSession; + if (authenticationReply.FindBool("rememberCredentials", + &rememberCredentials) == B_OK && rememberCredentials) { + persistence = CredentialPersistencePermanent; + } + + Credential credential(user.String(), password.String(), persistence); + challenge.authenticationClient()->receivedCredential(challenge, credential); + } + } +} + + +bool FrameLoaderClientHaiku::dispatchDidReceiveInvalidCertificate(DocumentLoader* loader, + const CertificateInfo& certificate, const char* message) +{ + String text = "The SSL certificate received from " + + loader->url().string() + " could not be " + "authenticated for the following reason: " + message + ".\n\n" + "The secure connection to the website may be compromised, make sure " + "to not send any sensitive information."; + + BMessage warningMessage(SSL_CERT_ERROR); + warningMessage.AddString("text", text.utf8().data()); + warningMessage.AddPointer("certificate info", &certificate); + + BMessage reply; + m_messenger.SendMessage(&warningMessage, &reply); + + bool continueAnyway = reply.FindBool("continue"); + + return continueAnyway; +} + + +void FrameLoaderClientHaiku::dispatchDidReceiveResponse(DocumentLoader* loader, + unsigned long identifier, + const ResourceResponse& coreResponse) +{ + loader->writer().setEncoding(coreResponse.textEncodingName(), false); + + BMessage message(RESPONSE_RECEIVED); + message.AddInt32("status", coreResponse.httpStatusCode()); + message.AddInt32("identifier", identifier); + message.AddString("url", coreResponse.url().string()); + message.AddString("mimeType", coreResponse.mimeType()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidReceiveContentLength(DocumentLoader* /*loader*/, + unsigned long /*id*/, int /*length*/) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidFinishLoading(DocumentLoader* /*loader*/, unsigned long /*identifier*/) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidFailLoading(DocumentLoader* loader, unsigned long, const ResourceError& error) +{ + if (error.isCancellation()) + return; + BMessage message(LOAD_FAILED); + message.AddString("url", loader->url().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidDispatchOnloadEvents() +{ + CALLED(); + BMessage message(LOAD_ONLOAD_HANDLE); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidReceiveServerRedirectForProvisionalLoad() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidCancelClientRedirect() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchWillPerformClientRedirect(const URL&, double /*interval*/, WallTime /*fireDate*/, LockBackForwardList) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidChangeLocationWithinPage() +{ + BMessage message(LOAD_DOC_COMPLETED); + message.AddPointer("frame", m_webFrame); + message.AddString("url", m_webFrame->Frame()->document()->url().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidPushStateWithinPage() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidReplaceStateWithinPage() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidPopStateWithinPage() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchWillClose() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDidReceiveIcon() +{ + if (m_loadingErrorPage) + return; + + BMessage message(ICON_RECEIVED); + message.AddString("url", m_webFrame->Frame()->document()->url().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidStartProvisionalLoad() +{ + CALLED(); + if (m_loadingErrorPage) { + TRACE("m_loadingErrorPage\n"); + m_loadingErrorPage = false; + } + + BMessage message(LOAD_NEGOTIATING); + message.AddString("url", + m_webFrame->Frame()->loader().provisionalDocumentLoader()->request().url().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidReceiveTitle(const StringWithDirection& title) +{ + CALLED(); + if (m_loadingErrorPage) { + TRACE("m_loadingErrorPage\n"); + return; + } + + m_webFrame->SetTitle(title.string); + + BMessage message(TITLE_CHANGED); + message.AddString("title", title.string); + message.AddBool("ltr", isLeftToRightDirection(title.direction)); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidCommitLoad(WTF::Optional) +{ + CALLED(); + if (m_loadingErrorPage) { + TRACE("m_loadingErrorPage\n"); + return; + } + + BMessage message(LOAD_COMMITTED); + URL url = m_webFrame->Frame()->loader().documentLoader()->request().url(); + BUrl decoded(url); + + // In WebKit URL, the host may be IDN-encoded. Decode it for displaying. + char dest[2048]; + UErrorCode error = U_ZERO_ERROR; + if (!m_uidna_context) + m_uidna_context = uidna_openUTS46(UIDNA_DEFAULT, &error); + UIDNAInfo info = UIDNA_INFO_INITIALIZER; + + uidna_nameToUnicodeUTF8(m_uidna_context, url.host().utf8().data(), + -1 /* NULL-terminated */, dest, sizeof(dest), &info, &error); + + if (U_SUCCESS(error) && info.errors == 0) + decoded.SetHost(dest); + + message.AddString("url", decoded); + dispatchMessage(message); + + // We should assume first the frame has no title. If it has, then the above + // dispatchDidReceiveTitle() will be called very soon with the correct title. + // This properly resets the title when we navigate to a URI without a title. + BMessage titleMessage(TITLE_CHANGED); + titleMessage.AddString("title", ""); + dispatchMessage(titleMessage); +} + +void FrameLoaderClientHaiku::dispatchDidFailProvisionalLoad(const ResourceError& error, WillContinueLoading) +{ + dispatchDidFailLoad(error); +} + +void FrameLoaderClientHaiku::dispatchDidFailLoad(const ResourceError& error) +{ + CALLED(); + if (m_loadingErrorPage) { + TRACE("m_loadingErrorPage\n"); + return; + } + if (!shouldFallBack(error)) { + TRACE("should not fall back\n"); + return; + } + + m_loadingErrorPage = true; + + // NOTE: This could be used to display the error right in the page. However, I find + // the error alert somehow better to manage. For example, on a partial load error, + // at least some content stays readable if we don't overwrite it with the error text... :-) +// BString content(""); +// content << error.localizedDescription().utf8().data(); +// content << ""; +// +// m_webFrame->SetFrameSource(content); +} + +void FrameLoaderClientHaiku::dispatchDidFinishDocumentLoad() +{ + BMessage message(LOAD_DOC_COMPLETED); + message.AddPointer("frame", m_webFrame); + message.AddString("url", m_webFrame->Frame()->document()->url().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchDidFinishLoad() +{ + CALLED(); + if (m_loadingErrorPage) { + m_loadingErrorPage = false; + TRACE("m_loadingErrorPage\n"); + return; + } + + BMessage message(LOAD_FINISHED); + message.AddPointer("frame", m_webFrame); + message.AddString("url", m_webFrame->Frame()->document()->url().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::dispatchWillSubmitForm(FormState&, WTF::CompletionHandler&& function) +{ + CALLED(); + notImplemented(); + // It seems we can access the form content here, and maybe store it for auto-complete and the like. + function(); +} + +Frame* FrameLoaderClientHaiku::dispatchCreatePage(const NavigationAction& /*action*/) +{ + CALLED(); + WebCore::Page* page = m_webPage->createNewPage(); + if (page) + return &page->mainFrame(); + + return 0; +} + +void FrameLoaderClientHaiku::dispatchShow() +{ + CALLED(); + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchDecidePolicyForResponse( + const WebCore::ResourceResponse& response, + const WebCore::ResourceRequest& request, PolicyCheckIdentifier identifier, + const WTF::String&, FramePolicyFunction&& function) +{ + if (request.isNull()) { + function(PolicyAction::Ignore, identifier); + return; + } + // we need to call directly here + if (!response.isAttachment() && canShowMIMEType(response.mimeType())) { + function(PolicyAction::Use, identifier); + } else if (!request.url().isLocalFile() && response.mimeType() != "application/x-shockwave-flash") { + function(PolicyAction::Download, identifier); + } else { + function(PolicyAction::Ignore, identifier); + } +} + +void FrameLoaderClientHaiku::dispatchDecidePolicyForNewWindowAction( + const NavigationAction& action, const ResourceRequest& request, + FormState* /*formState*/, const String& /*targetName*/, + PolicyCheckIdentifier identifier, + FramePolicyFunction&& function) +{ + ASSERT(function); + if (!function) + return; + + if (request.isNull()) { + function(PolicyAction::Ignore, identifier); + return; + } + + if (!m_messenger.IsValid() || !isTertiaryMouseButton(action)) { + dispatchNavigationRequested(request); + function(PolicyAction::Use, identifier); + return; + } + + // Clicks with the tertiary mouse button shall open a new window, + // (or tab respectively depending on browser) - *ignore* the request for this page + // then, since we create it ourself. + BMessage message(NEW_WINDOW_REQUESTED); + message.AddString("url", request.url().string()); + + bool switchTab = false; + + // Switch to the new tab, when shift is pressed. + if (action.mouseEventData().hasValue()) { + switchTab = action.mouseEventData()->shiftKey; + } + + message.AddBool("primary", switchTab); + dispatchMessage(message, true); + + if (action.type() == NavigationType::FormSubmitted || action.type() == NavigationType::FormResubmitted) + m_webFrame->Frame()->loader().resetMultipleFormSubmissionProtection(); + + if (action.type() == NavigationType::LinkClicked) { + ResourceRequest emptyRequest; + m_webFrame->Frame()->loader().activeDocumentLoader()->setLastCheckedRequest(WTFMove(emptyRequest)); + } + + function(PolicyAction::Ignore, identifier); +} + +void FrameLoaderClientHaiku::dispatchDecidePolicyForNavigationAction( + const NavigationAction& action, const ResourceRequest& request, + const WebCore::ResourceResponse& response, FormState* formState, + PolicyDecisionMode, PolicyCheckIdentifier identifier, + FramePolicyFunction&& function) +{ + // Potentially we want to open a new window, when the user clicked with the + // tertiary mouse button. That's why we can reuse the other method. + dispatchDecidePolicyForNewWindowAction(action, request, formState, String(), + identifier, std::move(function)); +} + +void FrameLoaderClientHaiku::cancelPolicyCheck() +{ + CALLED(); + notImplemented(); +} + +void FrameLoaderClientHaiku::dispatchUnableToImplementPolicy(const ResourceError&) +{ + CALLED(); + notImplemented(); +} + +void FrameLoaderClientHaiku::revertToProvisionalState(DocumentLoader*) +{ + CALLED(); + notImplemented(); +} + +void FrameLoaderClientHaiku::setMainDocumentError(WebCore::DocumentLoader* /*loader*/, const WebCore::ResourceError& error) +{ + CALLED(); + + if (error.isCancellation()) + return; + + BMessage message(MAIN_DOCUMENT_ERROR); + message.AddString("url", error.failingURL().string().utf8().data()); + message.AddString("error", error.localizedDescription()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::setMainFrameDocumentReady(bool) +{ + // this is only interesting once we provide an external API for the DOM +} + +void FrameLoaderClientHaiku::startDownload(const ResourceRequest& request, const String& /*suggestedName*/) +{ + m_webPage->requestDownload(request); +} + +void FrameLoaderClientHaiku::willChangeTitle(DocumentLoader*) +{ + // We act in didChangeTitle +} + +void FrameLoaderClientHaiku::didChangeTitle(DocumentLoader* docLoader) +{ + setTitle(docLoader->title(), docLoader->url()); +} + +void FrameLoaderClientHaiku::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length) +{ + CALLED(); + + ASSERT(loader->frame()); + loader->commitData(data, length); + +#if 0 + Frame* coreFrame = loader->frame(); + if (coreFrame && coreFrame->document()->isMediaDocument()) + loader->cancelMainResourceLoad(coreFrame->loader().client().pluginWillHandleLoadError(loader->response())); +#endif +} + +void FrameLoaderClientHaiku::finishedLoading(DocumentLoader* /*documentLoader*/) +{ + CALLED(); +} + +void FrameLoaderClientHaiku::updateGlobalHistory() +{ + WebCore::Frame* frame = m_webFrame->Frame(); + if (!frame) + return; + + BMessage message(UPDATE_HISTORY); + message.AddString("url", frame->loader().documentLoader()->urlForHistory().string()); + dispatchMessage(message); +} + +void FrameLoaderClientHaiku::updateGlobalHistoryRedirectLinks() +{ + updateGlobalHistory(); +} + +bool FrameLoaderClientHaiku::shouldGoToHistoryItem(WebCore::HistoryItem&) const +{ + // FIXME: Should probably be refuse to go to the item when it contains + // form data that has already been sent or something. + return true; +} + +void FrameLoaderClientHaiku::didDisplayInsecureContent() +{ +} + +void FrameLoaderClientHaiku::didRunInsecureContent(WebCore::SecurityOrigin&, const WTF::URL&) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::didDetectXSS(const URL&, bool) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::convertMainResourceLoadToDownload(DocumentLoader*, + PAL::SessionID, const ResourceRequest& request, const ResourceResponse&) +{ + startDownload(request); +} + +WebCore::ResourceError FrameLoaderClientHaiku::cancelledError(const WebCore::ResourceRequest& request) +{ + ResourceError error = ResourceError(String(), WebKitErrorCannotShowURL, + request.url(), "Load request cancelled", ResourceError::Type::Cancellation); + return error; +} + +WebCore::ResourceError FrameLoaderClientHaiku::blockedError(const ResourceRequest& request) +{ + return ResourceError(String(), WebKitErrorCannotUseRestrictedPort, + request.url(), "Not allowed to use restricted network port"); +} + +WebCore::ResourceError FrameLoaderClientHaiku::blockedByContentBlockerError(const ResourceRequest& request) +{ + return ResourceError(String(), WebKitErrorCannotShowURL, + request.url(), "Blocked by content blocker"); +} + +WebCore::ResourceError FrameLoaderClientHaiku::cannotShowURLError(const WebCore::ResourceRequest& request) +{ + return ResourceError(String(), WebKitErrorCannotShowURL, + request.url(), "URL cannot be shown"); +} + +WebCore::ResourceError FrameLoaderClientHaiku::interruptedForPolicyChangeError(const WebCore::ResourceRequest& request) +{ + ResourceError error = ResourceError(String(), WebKitErrorFrameLoadInterruptedByPolicyChange, + request.url(), "Frame load was interrupted", ResourceError::Type::Cancellation); + return error; +} + +WebCore::ResourceError FrameLoaderClientHaiku::cannotShowMIMETypeError(const WebCore::ResourceResponse& response) +{ + // FIXME: This can probably be used to automatically close pages that have no content, + // but only triggered a download. Since BWebPage is used for initiating a BWebDownload, + // it could remember doing so and then we could ask here if we are the main frame, + // have no content, but did download something -- then we could asked to be closed. + return ResourceError(String(), WebKitErrorCannotShowMIMEType, + response.url(), "Content with the specified MIME type cannot be shown"); +} + +WebCore::ResourceError FrameLoaderClientHaiku::fileDoesNotExistError(const WebCore::ResourceResponse& response) +{ + return ResourceError(String(), WebKitErrorCannotShowURL, + response.url(), "File does not exist"); +} + +ResourceError FrameLoaderClientHaiku::pluginWillHandleLoadError(const ResourceResponse& response) +{ + return ResourceError(String(), WebKitErrorPlugInWillHandleLoad, + response.url(), "Plugin will handle load"); +} + +bool FrameLoaderClientHaiku::shouldFallBack(const WebCore::ResourceError& error) +{ + return !(error.isCancellation() + || error.errorCode() == WebKitErrorFrameLoadInterruptedByPolicyChange + || error.errorCode() == WebKitErrorPlugInWillHandleLoad); +} + +bool FrameLoaderClientHaiku::canHandleRequest(const WebCore::ResourceRequest&) const +{ + // notImplemented(); + return true; +} + +bool FrameLoaderClientHaiku::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const +{ + notImplemented(); + return false; +} + +bool FrameLoaderClientHaiku::canShowMIMEType(const String& mimeType) const +{ + CALLED("%s", mimeType.utf8().data()); + // FIXME: Usually, the mime type will have been detexted. This is supposed to work around + // downloading some empty files, that can be observed. + if (!mimeType.length()) + return true; + + if (MIMETypeRegistry::canShowMIMEType(mimeType)) + return true; + +#if 0 + Frame* frame = m_webFrame->Frame(); + if (frame && frame->settings() && frame->settings()->arePluginsEnabled() + && PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType)) + return true; +#endif + + return false; +} + +bool FrameLoaderClientHaiku::representationExistsForURLScheme(const String& /*URLScheme*/) const +{ + return false; +} + +String FrameLoaderClientHaiku::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const +{ + notImplemented(); + return String(); +} + +void FrameLoaderClientHaiku::frameLoadCompleted() +{ +} + +void FrameLoaderClientHaiku::saveViewStateToItem(HistoryItem&) +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::restoreViewState() +{ + // This seems unimportant, the Qt port mentions this for it's corresponding signal: + // "This signal is emitted when the load of \a frame is finished and the application + // may now update its state accordingly." + // Could be this is important for ports which use actual platform widgets. + notImplemented(); +} + +void FrameLoaderClientHaiku::provisionalLoadStarted() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::didFinishLoad() +{ + notImplemented(); +} + +void FrameLoaderClientHaiku::prepareForDataSourceReplacement() +{ + // notImplemented(); // Nor does any port except Apple one. +} + +WTF::Ref FrameLoaderClientHaiku::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) +{ + CALLED("request: %s", request.url().string().utf8().data()); + return DocumentLoader::create(request, substituteData); +} + +void FrameLoaderClientHaiku::setTitle(const StringWithDirection&, const URL&) +{ + // no need for, dispatchDidReceiveTitle is the right callback +} + +void FrameLoaderClientHaiku::savePlatformDataToCachedFrame(CachedFrame* /*cachedPage*/) +{ + CALLED(); + // Nothing to be done here for the moment. We don't associate any platform data +} + +void FrameLoaderClientHaiku::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame) +{ + CALLED(); + ASSERT(cachedFrame->view()); + + // FIXME: I guess we would have to restore platform data from the cachedFrame here, + // data associated in savePlatformDataToCachedFrame(). + + cachedFrame->view()->setTopLevelPlatformWidget(m_webPage->WebView()); +} + +void FrameLoaderClientHaiku::transitionToCommittedForNewPage() +{ + CALLED(); + ASSERT(m_webFrame); + + Frame* frame = m_webFrame->Frame(); + + assert(frame); + + BRect bounds = m_webPage->viewBounds(); + IntSize size = IntSize(bounds.IntegerWidth() + 1, bounds.IntegerHeight() + 1); + + Optional backgroundColor; + if (m_webFrame->IsTransparent()) + backgroundColor = Color(Color::transparent); + frame->createView(size, backgroundColor, {}, {}); + + frame->view()->setTopLevelPlatformWidget(m_webPage->WebView()); +} + +String FrameLoaderClientHaiku::userAgent(const URL&) +{ + BLanguage language; + BLocale::Default()->GetLanguage(&language); + BString languageTag(language.Code()); + if (language.CountryCode() != NULL) + languageTag << "-" << language.CountryCode(); + + // FIXME: Get the app name from the app. Hardcoded WebPositive for now. + // We have to look as close to Safari as possible for some sites like gmail.com + BString userAgent("Mozilla/5.0 (Macintosh; Intel Haiku R1 x86) AppleWebKit/%webkit% (KHTML, like Gecko) WebPositive/1.2 Version/11.1 Safari/%webkit%"); + userAgent.ReplaceAll("%webkit%", WebKitInfo::WebKitVersion().String()); + return userAgent; +} + +bool FrameLoaderClientHaiku::canCachePage() const +{ + return true; +} + +RefPtr FrameLoaderClientHaiku::createFrame(const URL& url, + const String& name, HTMLFrameOwnerElement& ownerElement, + const String& referrer) +{ + ASSERT(m_webFrame); + ASSERT(m_webPage); + + BWebFrame* subFrame = m_webFrame->AddChild(m_webPage, name, &ownerElement); + if (!subFrame) + return nullptr; + + RefPtr coreSubFrame = subFrame->Frame(); + ASSERT(coreSubFrame); + + subFrame->SetListener(m_messenger); + m_webFrame->Frame()->loader().loadURLIntoChildFrame(url, referrer, coreSubFrame.get()); + + // The frame's onload handler may have removed it from the document. + // See fast/dom/null-page-show-modal-dialog-crash.html for an example. + if (!coreSubFrame->tree().parent()) { + // The subframe will be deleted when coreSubFrame is dereferenced. + return nullptr; + } + + return coreSubFrame; +} + +ObjectContentType FrameLoaderClientHaiku::objectContentType(const URL& url, const String& originalMimeType) +{ + CALLED(); + if (url.isEmpty() && !originalMimeType.length()) + return ObjectContentType::None; + + String mimeType = originalMimeType; + if (!mimeType.length()) { + entry_ref ref; + if (get_ref_for_path(url.path().utf8().data(), &ref) == B_OK) { + BMimeType type; + if (BMimeType::GuessMimeType(&ref, &type) == B_OK) + mimeType = type.Type(); + } else { + // For non-file URLs, try guessing from the extension (this happens + // before the request so our content sniffing is of no use) + mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1)); + } + } + + if (!mimeType.length()) + return ObjectContentType::Frame; + + if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) + return ObjectContentType::Image; + +#if 0 + if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType)) + return ObjectContentNetscapePlugin; +#endif + + if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) + return ObjectContentType::Frame; + + if (url.protocol() == "about") + return ObjectContentType::Frame; + + return ObjectContentType::None; +} + +RefPtr FrameLoaderClientHaiku::createPlugin(const IntSize&, HTMLPlugInElement&, const URL&, const Vector&, + const Vector&, const String&, bool /*loadManually*/) +{ + CALLED(); + notImplemented(); + return nullptr; +} + +void FrameLoaderClientHaiku::redirectDataToPlugin(Widget& pluginWidge) +{ + CALLED(); + debugger("plugins are not implemented on Haiku!"); +} + +RefPtr FrameLoaderClientHaiku::createJavaAppletWidget(const IntSize&, HTMLAppletElement&, const URL& /*baseURL*/, + const Vector& /*paramNames*/, const Vector& /*paramValues*/) +{ + notImplemented(); + return 0; +} + +String FrameLoaderClientHaiku::overrideMediaType() const +{ + // This will do, until we support printing. + return "screen"; +} + +void FrameLoaderClientHaiku::didSaveToPageCache() +{ +} + +void FrameLoaderClientHaiku::didRestoreFromPageCache() +{ +} + +void FrameLoaderClientHaiku::dispatchDidBecomeFrameset(bool) +{ +} + +void FrameLoaderClientHaiku::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world) +{ + if (&world != &mainThreadNormalWorld()) + return; + + if (m_webFrame) { + BMessage message(JAVASCRIPT_WINDOW_OBJECT_CLEARED); + dispatchMessage(message); + + } + + if (m_webPage->fDumpRenderTree) + { + // DumpRenderTree registers the TestRunner JavaScript object using this + // callback. This can't be done using the asynchronous BMessage above: + // by the time the message is processed by the target, the JS test will + // already have run! + JSGlobalContextRef context = toGlobalRef(m_webFrame->Frame()->script().globalObject(mainThreadNormalWorld())->globalExec()); + JSObjectRef windowObject = toRef(m_webFrame->Frame()->script().globalObject(mainThreadNormalWorld())); + m_webPage->fDumpRenderTree->didClearWindowObjectInWorld(world, context, windowObject); + } + +} + +Ref FrameLoaderClientHaiku::createNetworkingContext() +{ + return FrameNetworkingContextHaiku::create(m_webFrame->Frame(), m_webPage->GetContext()); +} + +// #pragma mark - private + +bool FrameLoaderClientHaiku::isTertiaryMouseButton(const NavigationAction& action) const +{ + if (action.mouseEventData().hasValue()) { + return (action.mouseEventData()->button == 1); + } + return false; +} + +status_t FrameLoaderClientHaiku::dispatchNavigationRequested(const ResourceRequest& request) const +{ + BMessage message(NAVIGATION_REQUESTED); + message.AddString("url", request.url().string()); + return dispatchMessage(message); +} + +status_t FrameLoaderClientHaiku::dispatchMessage(BMessage& message, bool allowChildFrame) const +{ + message.AddPointer("view", m_webPage->WebView()); + message.AddPointer("frame", m_webFrame); + + // Most messages are only relevant when they come from the main frame + // (setting the title, favicon, url, loading progress, etc). We intercept + // the ones coming from child frames here. + // Currently, the only exception is the message for navigation policy. This + // allows opening a new tab by middle-clicking a link that's in a frame. + if (allowChildFrame || m_webFrame == m_webPage->MainFrame()) + return m_messenger.SendMessage(&message); + else + return B_NOT_ALLOWED; +} + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/FrameLoaderClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameLoaderClientHaiku.h new file mode 100644 index 000000000000..4072e41c11b6 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameLoaderClientHaiku.h @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2006 Zack Rusin + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2007 Ryan Leavengood All rights reserved. + * Copyright (C) 2009 Maxime Simon All rights reserved. + * Copyright (C) 2010 Stephan Aßmus + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FrameLoaderClientHaiku_h +#define FrameLoaderClientHaiku_h + +#include "FrameLoader.h" +#include "FrameLoaderClient.h" +#include "wtf/URL.h" +#include "ResourceResponse.h" +#include +#include +#include + +class BWebFrame; +class BWebPage; + +namespace WebCore { + +class AuthenticationChallenge; +class DocumentLoader; +class Element; +class FormState; +class FrameView; +class HistoryItem; +class NavigationAction; +class ResourceLoader; + +struct LoadErrorResetToken; + +class FrameLoaderClientHaiku : public FrameLoaderClient { + public: + explicit FrameLoaderClientHaiku(BWebPage*); + void frameLoaderDestroyed() override; + + void setFrame(BWebFrame* frame) {m_webFrame = frame;} + BWebFrame* webFrame() { return m_webFrame; } + void setDispatchTarget(const BMessenger& messenger); + BWebPage* page() const; + + WTF::Optional pageID() const final; + WTF::Optional frameID() const final; + PAL::SessionID sessionID() const final; + + bool hasWebView() const override; + + void makeRepresentation(DocumentLoader*) override; + void forceLayoutForNonHTML() override; + + void setCopiesOnScroll() override; + + void detachedFromParent2() override; + void detachedFromParent3() override; + + void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&) override; + + void dispatchWillSendRequest(DocumentLoader*, unsigned long, ResourceRequest&, + const ResourceResponse&) override; + bool shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier) override; + void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, + unsigned long identifier, + const AuthenticationChallenge&) override; + + bool dispatchDidReceiveInvalidCertificate(DocumentLoader*, + const CertificateInfo& certificate, const char* message) override; + + void dispatchDidCommitLoad(WTF::Optional) override; + void dispatchDidReceiveResponse(DocumentLoader*, unsigned long, + const ResourceResponse&) override; + void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long, int) override; + void dispatchDidFinishLoading(DocumentLoader*, unsigned long) override; + void dispatchDidFailLoading(DocumentLoader*, unsigned long, + const ResourceError&) override; + + void dispatchDidDispatchOnloadEvents() override; + void dispatchDidReceiveServerRedirectForProvisionalLoad() override; + void dispatchDidCancelClientRedirect() override; + void dispatchWillPerformClientRedirect(const URL&, double interval, WallTime fireDate, LockBackForwardList) override; + void dispatchDidChangeLocationWithinPage() override; + void dispatchDidPushStateWithinPage() override; + void dispatchDidReplaceStateWithinPage() override; + void dispatchDidPopStateWithinPage() override; + void dispatchWillClose() override; + void dispatchDidReceiveIcon() override; + void dispatchDidStartProvisionalLoad() override; + void dispatchDidReceiveTitle(const StringWithDirection&) override; + void dispatchDidFailProvisionalLoad(const ResourceError&, WillContinueLoading) override; + void dispatchDidFailLoad(const ResourceError&) override; + void dispatchDidFinishDocumentLoad() override; + void dispatchDidFinishLoad() override; + + Frame* dispatchCreatePage(const NavigationAction&) override; + void dispatchShow() override; + + void dispatchDecidePolicyForResponse(const ResourceResponse&, + const ResourceRequest&, PolicyCheckIdentifier, + const String& downloadAttribute, FramePolicyFunction&&) override; + void dispatchDecidePolicyForNewWindowAction(const NavigationAction&, + const ResourceRequest&, FormState*, const String& formName, + PolicyCheckIdentifier, FramePolicyFunction&&) override; + void dispatchDecidePolicyForNavigationAction(const NavigationAction&, + const ResourceRequest&, const WebCore::ResourceResponse&, FormState*, + PolicyDecisionMode, PolicyCheckIdentifier, FramePolicyFunction&&) override; + void cancelPolicyCheck() override; + + void dispatchUnableToImplementPolicy(const ResourceError&) override; + + void dispatchWillSendSubmitEvent(WTF::Ref&&) override { } + void dispatchWillSubmitForm(FormState&, WTF::CompletionHandler&&) override; + + void revertToProvisionalState(DocumentLoader*) override; + void setMainDocumentError(DocumentLoader*, const ResourceError&) override; + bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, + const ResourceRequest&, + const ResourceResponse&, int) override; + + void setMainFrameDocumentReady(bool) override; + + void startDownload(const ResourceRequest&, const String& suggestedName = String()) override; + + void willChangeTitle(DocumentLoader*) override; + void didChangeTitle(DocumentLoader*) override; + + virtual void willReplaceMultipartContent() override { } + virtual void didReplaceMultipartContent() override { } + + void committedLoad(DocumentLoader*, const char*, int) override; + void finishedLoading(DocumentLoader*) override; + void updateGlobalHistory() override; + void updateGlobalHistoryRedirectLinks() override; + + bool shouldGoToHistoryItem(HistoryItem&) const override; + + bool canCachePage() const override; + void convertMainResourceLoadToDownload(DocumentLoader*, PAL::SessionID, + const ResourceRequest&, const ResourceResponse&) override; + + void didDisplayInsecureContent() override; + + void didRunInsecureContent(SecurityOrigin&, const URL&) override; + void didDetectXSS(const URL&, bool didBlockEntirePage) override; + + ResourceError cancelledError(const ResourceRequest&) override; + ResourceError blockedError(const ResourceRequest&) override; + ResourceError blockedByContentBlockerError(const ResourceRequest&) override; + ResourceError cannotShowURLError(const ResourceRequest&) override; + ResourceError interruptedForPolicyChangeError(const ResourceRequest&) override; + + + ResourceError cannotShowMIMETypeError(const ResourceResponse&) override; + ResourceError fileDoesNotExistError(const ResourceResponse&) override; + ResourceError pluginWillHandleLoadError(const ResourceResponse&) override; + + bool shouldFallBack(const ResourceError&) override; + + String userAgent(const URL&) override; + + void savePlatformDataToCachedFrame(CachedFrame*) override; + void transitionToCommittedFromCachedFrame(CachedFrame*) override; + void transitionToCommittedForNewPage() override; + + bool canHandleRequest(const ResourceRequest&) const override; + bool canShowMIMEType(const String& MIMEType) const override; + bool canShowMIMETypeAsHTML(const String& MIMEType) const override; + bool representationExistsForURLScheme(const String& URLScheme) const override; + String generatedMIMETypeForURLScheme(const String& URLScheme) const override; + + void frameLoadCompleted() override; + void saveViewStateToItem(HistoryItem&) override; + void restoreViewState() override; + void provisionalLoadStarted() override; + void didFinishLoad() override; + void prepareForDataSourceReplacement() override; + Ref createDocumentLoader(const ResourceRequest&, const SubstituteData&) override; + + void setTitle(const StringWithDirection&, const URL&) override; + + RefPtr createFrame(const URL& url, const String& name, HTMLFrameOwnerElement&, + const String& referrer) override; + RefPtr createPlugin(const IntSize&, HTMLPlugInElement&, const URL&, const Vector&, + const Vector&, const String&, bool) override; + void redirectDataToPlugin(Widget& pluginWidget) override; + + RefPtr createJavaAppletWidget(const IntSize&, HTMLAppletElement&, const URL& baseURL, + const Vector& paramNames, const Vector& paramValues) override; + + ObjectContentType objectContentType(const URL&, const String& mimeType) override; + + String overrideMediaType() const override; + + void didSaveToPageCache() override; + void didRestoreFromPageCache() override; + + void dispatchDidBecomeFrameset(bool) override; + + void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld&) override; + + Ref createNetworkingContext() override; + void updateCachedDocumentLoader(WebCore::DocumentLoader&) override { } + + void prefetchDNS(const String&) override { } + private: + bool isTertiaryMouseButton(const NavigationAction& action) const; + + status_t dispatchNavigationRequested(const ResourceRequest& request) const; + status_t dispatchMessage(BMessage& message, bool allowChildFrame = false) const; + +private: + BWebPage* m_webPage; + BWebFrame* m_webFrame; + BMessenger m_messenger; + + bool m_loadingErrorPage; + + // IDNA domain encoding and decoding. + UIDNA* m_uidna_context; +}; + +} + +#endif // FrameLoaderClientHaiku_h + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/FrameNetworkingContextHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameNetworkingContextHaiku.cpp new file mode 100644 index 000000000000..3b5f647cbf77 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameNetworkingContextHaiku.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010 Samsung Electronics + * Copyright (C) 2012 ProFUSION embedded systems + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FrameNetworkingContextHaiku.h" + +#include "NetworkStorageSessionMap.h" +#include "NetworkStorageSession.h" +#include "NotImplemented.h" +#include "Page.h" +#include "ResourceHandle.h" + +#include +#include + +namespace WebCore { + +static std::unique_ptr& privateSession() +{ + static NeverDestroyed> session; + return session; +} + +Ref FrameNetworkingContextHaiku::create(Frame* frame, BUrlContext* context) +{ + return adoptRef(*new FrameNetworkingContextHaiku(frame, context)); +} + +FrameNetworkingContextHaiku::FrameNetworkingContextHaiku(Frame* frame, BUrlContext* context) + : FrameNetworkingContext(frame) +{ + storageSession()->setPlatformSession(context); +} + +FrameNetworkingContextHaiku::~FrameNetworkingContextHaiku() +{ +} + +BUrlContext* FrameNetworkingContextHaiku::context() +{ + return &storageSession()->platformSession(); +} + +uint64_t FrameNetworkingContextHaiku::initiatingPageID() const +{ + notImplemented(); + return 0; +} + + +NetworkStorageSession* FrameNetworkingContextHaiku::storageSession() const +{ + ASSERT(isMainThread()); + + if (frame() && frame()->page()->usesEphemeralSession()) + return NetworkStorageSessionMap::storageSession(PAL::SessionID::legacyPrivateSessionID()); + + return &NetworkStorageSessionMap::defaultStorageSession(); +} + +} diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/FrameNetworkingContextHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameNetworkingContextHaiku.h new file mode 100644 index 000000000000..0384eda1e09a --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/FrameNetworkingContextHaiku.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FrameNetworkingContextHaiku_h +#define FrameNetworkingContextHaiku_h + +#include "FrameNetworkingContext.h" + +#include +#include +#include + +namespace WebCore { + +class FrameNetworkingContextHaiku : public WebCore::FrameNetworkingContext { +public: + static Ref create(Frame*, BUrlContext* context); + virtual ~FrameNetworkingContextHaiku(); + + WebCore::Frame* coreFrame() const { return frame(); } + virtual uint64_t initiatingPageID() const; + + BUrlContext* context(); + +private: + FrameNetworkingContextHaiku(Frame*, BUrlContext* context); + WebCore::NetworkStorageSession* storageSession() const override; +}; + +} + +#endif diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/FunctionTracer.h b/Source/WebKitLegacy/haiku/WebCoreSupport/FunctionTracer.h new file mode 100644 index 000000000000..9a93fccc08d4 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/FunctionTracer.h @@ -0,0 +1,83 @@ +/* + * Copyright 2008-2010 Stephan Aßmus + * All rights reserved. Distributed under the terms of the MIT/X11 license. + */ +#ifndef FunctionTracer_h +#define FunctionTracer_h + +#include + +class FunctionTracer; + +static FunctionTracer* sPreviousFunctionTracer; + +#ifndef CLASS_NAME +#define CLASS_NAME "CLASS_NAME" +#endif + +class FunctionTracer { +public: + FunctionTracer(const void* ptr, const char* functionName, int& depth) + : m_previousTracer(sPreviousFunctionTracer) + , m_blockWasNeeded(false) + , m_functionDepth(depth) + , m_thisPointer(ptr) + , m_functionName(functionName) + { + m_functionDepth++; + if (m_previousTracer) + m_previousTracer->blockNeeded(); + sPreviousFunctionTracer = this; + } + + ~FunctionTracer() + { + if (m_blockWasNeeded) + printf("%*s}\n", m_functionDepth * 2, ""); + else + printf("\n"); + m_functionDepth--; + sPreviousFunctionTracer = m_previousTracer; + } + + void init(const char* format = "", ...) + { + char buffer[1024]; + va_list list; + va_start(list, format); + vsnprintf(buffer, sizeof(buffer), format, list); + va_end(list); + printf("%*s%p->%s::%s(%s)", m_functionDepth * 2, "", m_thisPointer, + CLASS_NAME, m_functionName, buffer); + } + + void blockNeeded() + { + if (!m_blockWasNeeded) { + printf(" {\n"); + m_blockWasNeeded = true; + } + } + +private: + FunctionTracer* m_previousTracer; + bool m_blockWasNeeded; + int& m_functionDepth; + const void* m_thisPointer; + const char* m_functionName; +}; + +static int sFunctionDepth = -1; + +#define CALLED(x...) FunctionTracer _ft(this, __FUNCTION__, sFunctionDepth); \ + _ft.init(x) + +#define TRACE(x...) { \ + if (sPreviousFunctionTracer) \ + sPreviousFunctionTracer->blockNeeded(); \ + printf("%*s", (sFunctionDepth + 1) * 2, ""); \ + printf(x); \ + } + + +#endif // FunctionTracer_h diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/IconDatabase.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/IconDatabase.cpp new file mode 100644 index 000000000000..bee918363d01 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/IconDatabase.cpp @@ -0,0 +1,1976 @@ +/* + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. + * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "IconDatabase.h" + +#include "pal/ExportMacros.h" +#include "Logging.h" +#include "BitmapImage.h" +#include +#include "Image.h" +#include +#include +#include "SharedBuffer.h" +#include +#include +#include +#include +#include + +// For methods that are meant to support API from the main thread - should not be called internally +#define ASSERT_NOT_SYNC_THREAD() ASSERT(!m_syncThreadRunning || !IS_ICON_SYNC_THREAD()) + +// For methods that are meant to support the sync thread ONLY +#define IS_ICON_SYNC_THREAD() (m_syncThread == &Thread::current()) +#define ASSERT_ICON_SYNC_THREAD() ASSERT(IS_ICON_SYNC_THREAD()) + +using namespace WebCore; + +namespace WebKit { + +static int databaseCleanupCounter = 0; + +// This version number is in the DB and marks the current generation of the schema +// Currently, a mismatched schema causes the DB to be wiped and reset. This isn't +// so bad during development but in the future, we would need to write a conversion +// function to advance older released schemas to "current" +static const int currentDatabaseVersion = 6; + +// Icons expire once every 4 days +static const int iconExpirationTime = 60*60*24*4; + +static const Seconds updateTimerDelay { 5_s }; + +static bool checkIntegrityOnOpen = false; + +// We are not interested in icons that have been unused for more than +// 30 days, delete them even if they have not been explicitly released. +static const Seconds notUsedIconExpirationTime { 60*60*24*30 }; + +#if !LOG_DISABLED || !ERROR_DISABLED +static String urlForLogging(const String& url) +{ + static const unsigned urlTruncationLength = 120; + + if (url.length() < urlTruncationLength) + return url; + return url.substring(0, urlTruncationLength) + "..."; +} +#endif + +class DefaultIconDatabaseClient final : public IconDatabaseClient { + WTF_MAKE_FAST_ALLOCATED; +public: + void didImportIconURLForPageURL(const String&) override { } + void didImportIconDataForPageURL(const String&) override { } + void didChangeIconForPageURL(const String&) override { } + void didFinishURLImport() override { } +}; + +static IconDatabaseClient* defaultClient() +{ + static IconDatabaseClient* defaultClient = new DefaultIconDatabaseClient; + return defaultClient; +} + +IconDatabase::IconRecord::IconRecord(const String& url) + : m_iconURL(url) +{ +} + +IconDatabase::IconRecord::~IconRecord() +{ + LOG(IconDatabase, "Destroying IconRecord for icon url %s", m_iconURL.ascii().data()); +} + +NativeImagePtr IconDatabase::IconRecord::image(const IntSize&) +{ + // FIXME rdar://4680377 - For size right now, we are returning our one and only image and the Bridge + // is resizing it in place. We need to actually store all the original representations here and return a native + // one, or resize the best one to the requested size and cache that result. + return m_image; +} + +void IconDatabase::IconRecord::setImageData(RefPtr&& data) +{ + m_dataSet = true; + m_imageData = WTFMove(data); + m_image = nullptr; + + if (!m_imageData || !m_imageData->size()) { + m_imageData = nullptr; + return; + } + + auto image = BitmapImage::create(); + if (image->setData(RefPtr { m_imageData }, true) < EncodedDataStatus::SizeAvailable) { + LOG(IconDatabase, "Manual image data for iconURL '%s' FAILED - it was probably invalid image data", m_iconURL.ascii().data()); + m_imageData = nullptr; + return; + } + + m_image = image->nativeImageForCurrentFrame(); + if (!m_image) { + LOG(IconDatabase, "Manual image data for iconURL '%s' FAILED - it was probably invalid image data", m_iconURL.ascii().data()); + m_imageData = nullptr; + } +} + +IconDatabase::IconRecord::ImageDataStatus IconDatabase::IconRecord::imageDataStatus() +{ + if (!m_dataSet) + return ImageDataStatus::Unknown; + if (!m_image) + return ImageDataStatus::Missing; + return ImageDataStatus::Present; +} + +IconDatabase::IconSnapshot IconDatabase::IconRecord::snapshot(bool forDeletion) const +{ + if (forDeletion) + return IconSnapshot(m_iconURL, 0, nullptr); + + return IconSnapshot(m_iconURL, m_stamp, m_imageData ? m_imageData.get() : nullptr); +} + +IconDatabase::PageURLRecord::PageURLRecord(const String& pageURL) + : m_pageURL(pageURL) +{ +} + +IconDatabase::PageURLRecord::~PageURLRecord() +{ + if (m_iconRecord) + m_iconRecord->retainingPageURLs().remove(m_pageURL); +} + +void IconDatabase::PageURLRecord::setIconRecord(RefPtr&& icon) +{ + if (m_iconRecord) + m_iconRecord->retainingPageURLs().remove(m_pageURL); + + m_iconRecord = WTFMove(icon); + + if (m_iconRecord) + m_iconRecord->retainingPageURLs().add(m_pageURL); +} + +IconDatabase::PageURLSnapshot IconDatabase::PageURLRecord::snapshot(bool forDeletion) const +{ + return { m_pageURL, (m_iconRecord && !forDeletion) ? m_iconRecord->iconURL() : String() }; +} + +// ************************ +// *** Main Thread Only *** +// ************************ + +void IconDatabase::setClient(std::unique_ptr&& client) +{ + // Don't allow a client change after the thread has already began + // (setting the client should occur before the database is opened) + ASSERT(!m_syncThreadRunning); + if (!client || m_syncThreadRunning) + return; + + m_client = WTFMove(client); +} + +bool IconDatabase::open(const String& directory, const String& filename) +{ + ASSERT_NOT_SYNC_THREAD(); + + if (!m_isEnabled) + return false; + + if (isOpen()) { + LOG_ERROR("Attempt to reopen the IconDatabase which is already open. Must close it first."); + return false; + } + + m_mainThreadNotifier.setActive(true); + + m_databaseDirectory = directory.isolatedCopy(); + + // Formulate the full path for the database file + m_completeDatabasePath = FileSystem::pathByAppendingComponent(m_databaseDirectory, filename); + + // Lock here as well as first thing in the thread so the thread doesn't actually commence until the createThread() call + // completes and m_syncThreadRunning is properly set + m_syncLock.lock(); + m_syncThread = Thread::create("WebCore: IconDatabase", [this] { + iconDatabaseSyncThread(); + }); + m_syncThreadRunning = true; + m_syncLock.unlock(); + return true; +} + +void IconDatabase::close() +{ + ASSERT_NOT_SYNC_THREAD(); + + m_mainThreadNotifier.stop(); + + if (m_syncThreadRunning) { + // Set the flag to tell the sync thread to wrap it up + m_threadTerminationRequested = true; + + // Wake up the sync thread if it's waiting + wakeSyncThread(); + + // Wait for the sync thread to terminate + m_syncThread->waitForCompletion(); + } + + m_syncThreadRunning = false; + m_threadTerminationRequested = false; + m_removeIconsRequested = false; + + m_syncDB.close(); + + m_client = nullptr; +} + +void IconDatabase::removeAllIcons() +{ + ASSERT_NOT_SYNC_THREAD(); + + if (!isOpen()) + return; + + LOG(IconDatabase, "Requesting background thread to remove all icons"); + + // Clear the in-memory record of every IconRecord, anything waiting to be read from disk, and anything waiting to be written to disk + { + LockHolder locker(m_urlAndIconLock); + + // Clear the IconRecords for every page URL - RefCounting will cause the IconRecords themselves to be deleted + // We don't delete the actual PageRecords because we have the "retain icon for url" count to keep track of + for (auto& pageURL : m_pageURLToRecordMap.values()) + pageURL->setIconRecord(nullptr); + + // Clear the iconURL -> IconRecord map + m_iconURLToRecordMap.clear(); + + // Clear all in-memory records of things that need to be synced out to disk + { + LockHolder locker(m_pendingSyncLock); + m_pageURLsPendingSync.clear(); + m_iconsPendingSync.clear(); + } + + // Clear all in-memory records of things that need to be read in from disk + { + LockHolder locker(m_pendingReadingLock); + m_pageURLsPendingImport.clear(); + m_pageURLsInterestedInIcons.clear(); + m_iconsPendingReading.clear(); + } + } + + m_removeIconsRequested = true; + wakeSyncThread(); +} + +static bool documentCanHaveIcon(const String& documentURL) +{ + return !documentURL.isEmpty() && !protocolIs(documentURL, "about"); +} + +std::pair IconDatabase::synchronousIconForPageURL(const String& pageURLOriginal, const IntSize& size) +{ + ASSERT_NOT_SYNC_THREAD(); + + // pageURLOriginal cannot be stored without being deep copied first. + // We should go our of our way to only copy it if we have to store it + + if (!isOpen() || !documentCanHaveIcon(pageURLOriginal)) + return { nullptr, IsKnownIcon::No }; + + LockHolder locker(m_urlAndIconLock); + + performPendingRetainAndReleaseOperations(); + + String pageURLCopy; // Creates a null string for easy testing + + PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal); + if (!pageRecord) { + pageURLCopy = pageURLOriginal.isolatedCopy(); + pageRecord = getOrCreatePageURLRecord(pageURLCopy); + } + + // If pageRecord is nullptr, one of two things is true - + // 1 - The initial url import is incomplete and this pageURL was marked to be notified once it is complete if an iconURL exists + // 2 - The initial url import IS complete and this pageURL has no icon + if (!pageRecord) { + LockHolder locker(m_pendingReadingLock); + + // Import is ongoing, there might be an icon. In this case, register to be notified when the icon comes in + // If we ever reach this condition, we know we've already made the pageURL copy + if (!m_iconURLImportComplete) + m_pageURLsInterestedInIcons.add(pageURLCopy); + + return { nullptr, IsKnownIcon::No }; + } + + IconRecord* iconRecord = pageRecord->iconRecord(); + + // If the initial URL import isn't complete, it's possible to have a PageURL record without an associated icon + // In this case, the pageURL is already in the set to alert the client when the iconURL mapping is complete so + // we can just bail now + if (!m_iconURLImportComplete && !iconRecord) + return { nullptr, IsKnownIcon::No }; + + // Assuming we're done initializing and cleanup is allowed, + // the only way we should *not* have an icon record is if this pageURL is retained but has no icon yet. + ASSERT(iconRecord || databaseCleanupCounter || m_retainedPageURLs.contains(pageURLOriginal)); + + if (!iconRecord) + return { nullptr, IsKnownIcon::No }; + + // If it's a new IconRecord object that doesn't have its imageData set yet, + // mark it to be read by the background thread + if (iconRecord->imageDataStatus() == IconRecord::ImageDataStatus::Unknown) { + if (pageURLCopy.isNull()) + pageURLCopy = pageURLOriginal.isolatedCopy(); + + LockHolder locker(m_pendingReadingLock); + m_pageURLsInterestedInIcons.add(pageURLCopy); + m_iconsPendingReading.add(iconRecord); + wakeSyncThread(); + return { nullptr, IsKnownIcon::No }; + } + + // If the size parameter was (0, 0) that means the caller of this method just wanted the read from disk to be kicked off + // and isn't actually interested in the image return value + if (size == IntSize(0, 0)) + return { nullptr, IsKnownIcon::Yes }; + + return { iconRecord->image(size), IsKnownIcon::Yes }; +} + +String IconDatabase::synchronousIconURLForPageURL(const String& pageURLOriginal) +{ + ASSERT_NOT_SYNC_THREAD(); + + // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first + // Also, in the case we have a real answer for the caller, we must deep copy that as well + + if (!isOpen() || !documentCanHaveIcon(pageURLOriginal)) + return String(); + + LockHolder locker(m_urlAndIconLock); + + PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal); + if (!pageRecord) + pageRecord = getOrCreatePageURLRecord(pageURLOriginal.isolatedCopy()); + + // If pageRecord is nullptr, one of two things is true - + // 1 - The initial url import is incomplete and this pageURL has already been marked to be notified once it is complete if an iconURL exists + // 2 - The initial url import IS complete and this pageURL has no icon + if (!pageRecord) + return String(); + + // Possible the pageRecord is around because it's a retained pageURL with no iconURL, so we have to check + return pageRecord->iconRecord() ? pageRecord->iconRecord()->iconURL().isolatedCopy() : String(); +} + +void IconDatabase::retainIconForPageURL(const String& pageURL) +{ + ASSERT_NOT_SYNC_THREAD(); + + if (!isEnabled() || !documentCanHaveIcon(pageURL)) + return; + + { + LockHolder locker(m_urlsToRetainOrReleaseLock); + m_urlsToRetain.add(pageURL.isolatedCopy()); + m_retainOrReleaseIconRequested = true; + } + + scheduleOrDeferSyncTimer(); +} + +void IconDatabase::performRetainIconForPageURL(const String& pageURLOriginal, int retainCount) +{ + PageURLRecord* record = m_pageURLToRecordMap.get(pageURLOriginal); + + String pageURL; + + if (!record) { + pageURL = pageURLOriginal.isolatedCopy(); + + record = new PageURLRecord(pageURL); + m_pageURLToRecordMap.set(pageURL, record); + } + + if (!record->retain(retainCount)) { + if (pageURL.isNull()) + pageURL = pageURLOriginal.isolatedCopy(); + + // This page just had its retain count bumped from 0 to 1 - Record that fact + m_retainedPageURLs.add(pageURL); + + // If we read the iconURLs yet, we want to avoid any pageURL->iconURL lookups and the pageURLsPendingDeletion is moot, + // so we bail here and skip those steps + if (!m_iconURLImportComplete) + return; + + LockHolder locker(m_pendingSyncLock); + // If this pageURL waiting to be sync'ed, update the sync record + // This saves us in the case where a page was ready to be deleted from the database but was just retained - so theres no need to delete it! + if (!m_privateBrowsingEnabled && m_pageURLsPendingSync.contains(pageURL)) { + LOG(IconDatabase, "Bringing %s back from the brink", pageURL.ascii().data()); + m_pageURLsPendingSync.set(pageURL, record->snapshot()); + } + } +} + +void IconDatabase::releaseIconForPageURL(const String& pageURL) +{ + ASSERT_NOT_SYNC_THREAD(); + + // Cannot do anything with pageURLOriginal that would end up storing it without deep copying first + + if (!isEnabled() || !documentCanHaveIcon(pageURL)) + return; + + { + LockHolder locker(m_urlsToRetainOrReleaseLock); + m_urlsToRelease.add(pageURL.isolatedCopy()); + m_retainOrReleaseIconRequested = true; + } + scheduleOrDeferSyncTimer(); +} + +void IconDatabase::performReleaseIconForPageURL(const String& pageURLOriginal, int releaseCount) +{ + // Check if this pageURL is actually retained + if (!m_retainedPageURLs.contains(pageURLOriginal)) { + LOG_ERROR("Attempting to release icon for URL %s which is not retained", urlForLogging(pageURLOriginal).ascii().data()); + return; + } + + // Get its retain count - if it's retained, we'd better have a PageURLRecord for it + PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal); + ASSERT(pageRecord); + LOG(IconDatabase, "Releasing pageURL %s to a retain count of %i", urlForLogging(pageURLOriginal).ascii().data(), pageRecord->retainCount() - 1); + ASSERT(pageRecord->retainCount() > 0); + + // If it still has a positive retain count, store the new count and bail + if (pageRecord->release(releaseCount)) + return; + + // This pageRecord has now been fully released. Do the appropriate cleanup + LOG(IconDatabase, "No more retainers for PageURL %s", urlForLogging(pageURLOriginal).ascii().data()); + m_pageURLToRecordMap.remove(pageURLOriginal); + m_retainedPageURLs.remove(pageURLOriginal); + + // Grab the iconRecord for later use (and do a sanity check on it for kicks) + IconRecord* iconRecord = pageRecord->iconRecord(); + + ASSERT(!iconRecord || (iconRecord && m_iconURLToRecordMap.get(iconRecord->iconURL()) == iconRecord)); + + { + LockHolder locker(m_pendingReadingLock); + + // Since this pageURL is going away, there's no reason anyone would ever be interested in its read results + if (!m_iconURLImportComplete) + m_pageURLsPendingImport.remove(pageURLOriginal); + m_pageURLsInterestedInIcons.remove(pageURLOriginal); + + // If this icon is down to it's last retainer, we don't care about reading it in from disk anymore + if (iconRecord && iconRecord->hasOneRef()) { + m_iconURLToRecordMap.remove(iconRecord->iconURL()); + m_iconsPendingReading.remove(iconRecord); + } + } + + // Mark stuff for deletion from the database only if we're not in private browsing + if (!m_privateBrowsingEnabled) { + LockHolder locker(m_pendingSyncLock); + m_pageURLsPendingSync.set(pageURLOriginal.isolatedCopy(), pageRecord->snapshot(true)); + + // If this page is the last page to refer to a particular IconRecord, that IconRecord needs to + // be marked for deletion + if (iconRecord && iconRecord->hasOneRef()) + m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true)); + } + + delete pageRecord; +} + +void IconDatabase::setIconDataForIconURL(RefPtr&& data, const String& iconURLOriginal) +{ + ASSERT_NOT_SYNC_THREAD(); + + // Cannot do anything with iconURLOriginal that would end up storing them without deep copying first + + if (!isOpen() || iconURLOriginal.isEmpty()) + return; + + String iconURL = iconURLOriginal.isolatedCopy(); + Vector pageURLs; + { + LockHolder locker(m_urlAndIconLock); + + // If this icon was pending a read, remove it from that set because this new data should override what is on disk + RefPtr icon = m_iconURLToRecordMap.get(iconURL); + if (icon) { + LockHolder locker(m_pendingReadingLock); + m_iconsPendingReading.remove(icon.get()); + } else + icon = getOrCreateIconRecord(iconURL); + + // Update the data and set the time stamp + icon->setImageData(WTFMove(data)); + icon->setTimestamp((int)WallTime::now().secondsSinceEpoch().seconds()); + + // Copy the current retaining pageURLs - if any - to notify them of the change + pageURLs.appendRange(icon->retainingPageURLs().begin(), icon->retainingPageURLs().end()); + + // Mark the IconRecord as requiring an update to the database only if private browsing is disabled + if (!m_privateBrowsingEnabled) { + LockHolder locker(m_pendingSyncLock); + m_iconsPendingSync.set(iconURL, icon->snapshot()); + } + + if (icon->hasOneRef()) { + ASSERT(icon->retainingPageURLs().isEmpty()); + LOG(IconDatabase, "Icon for icon url %s is about to be destroyed - removing mapping for it", urlForLogging(icon->iconURL()).ascii().data()); + m_iconURLToRecordMap.remove(icon->iconURL()); + } + } + + // Send notification out regarding all PageURLs that retain this icon + // Start the timer to commit this change - or further delay the timer if it was already started + scheduleOrDeferSyncTimer(); + + for (auto& pageURL : pageURLs) { + LOG(IconDatabase, "Dispatching notification that retaining pageURL %s has a new icon", urlForLogging(pageURL).ascii().data()); + if (m_client) + m_client->didChangeIconForPageURL(pageURL); + } +} + +void IconDatabase::setIconURLForPageURL(const String& iconURLOriginal, const String& pageURLOriginal) +{ + ASSERT_NOT_SYNC_THREAD(); + + // Cannot do anything with iconURLOriginal or pageURLOriginal that would end up storing them without deep copying first + + ASSERT(!iconURLOriginal.isEmpty()); + + if (!isOpen() || !documentCanHaveIcon(pageURLOriginal)) + return; + + String iconURL, pageURL; + { + LockHolder locker(m_urlAndIconLock); + + PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURLOriginal); + + // If the urls already map to each other, bail. + // This happens surprisingly often, and seems to cream iBench performance + if (pageRecord && pageRecord->iconRecord() && pageRecord->iconRecord()->iconURL() == iconURLOriginal) + return; + + pageURL = pageURLOriginal.isolatedCopy(); + iconURL = iconURLOriginal.isolatedCopy(); + + if (!pageRecord) { + pageRecord = new PageURLRecord(pageURL); + m_pageURLToRecordMap.set(pageURL, pageRecord); + } + + RefPtr iconRecord = pageRecord->iconRecord(); + + // Otherwise, set the new icon record for this page + pageRecord->setIconRecord(getOrCreateIconRecord(iconURL)); + + // If the current icon has only a single ref left, it is about to get wiped out. + // Remove it from the in-memory records and don't bother reading it in from disk anymore + if (iconRecord && iconRecord->hasOneRef()) { + ASSERT(!iconRecord->retainingPageURLs().size()); + LOG(IconDatabase, "Icon for icon url %s is about to be destroyed - removing mapping for it", urlForLogging(iconRecord->iconURL()).ascii().data()); + m_iconURLToRecordMap.remove(iconRecord->iconURL()); + LockHolder locker(m_pendingReadingLock); + m_iconsPendingReading.remove(iconRecord.get()); + } + + // And mark this mapping to be added to the database + if (!m_privateBrowsingEnabled) { + LockHolder locker(m_pendingSyncLock); + m_pageURLsPendingSync.set(pageURL, pageRecord->snapshot()); + + // If the icon is on its last ref, mark it for deletion + if (iconRecord && iconRecord->hasOneRef()) + m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true)); + } + } + + // Since this mapping is new, send the notification out - but not if we're on the sync thread because that implies this mapping + // comes from the initial import which we don't want notifications for + if (!IS_ICON_SYNC_THREAD()) { + // Start the timer to commit this change - or further delay the timer if it was already started + scheduleOrDeferSyncTimer(); + + LOG(IconDatabase, "Dispatching notification that we changed an icon mapping for url %s", urlForLogging(pageURL).ascii().data()); + if (m_client) + m_client->didChangeIconForPageURL(pageURL); + } +} + +IconDatabase::IconLoadDecision IconDatabase::synchronousLoadDecisionForIconURL(const String& iconURL) +{ + ASSERT_NOT_SYNC_THREAD(); + + if (!isOpen() || iconURL.isEmpty()) + return IconLoadDecision::No; + + // If we have a IconRecord, it should also have its timeStamp marked because there is only two times when we create the IconRecord: + // 1 - When we read the icon urls from disk, getting the timeStamp at the same time + // 2 - When we get a new icon from the loader, in which case the timestamp is set at that time + { + LockHolder locker(m_urlAndIconLock); + if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL)) { + LOG(IconDatabase, "Found expiration time on a present icon based on existing IconRecord"); + return static_cast(WallTime::now().secondsSinceEpoch().seconds()) - static_cast(icon->getTimestamp()) > iconExpirationTime ? IconLoadDecision::Yes : IconLoadDecision::No; + } + } + + // If we don't have a record for it, but we *have* imported all iconURLs from disk, then we should load it now + LockHolder readingLocker(m_pendingReadingLock); + if (m_iconURLImportComplete) + return IconLoadDecision::Yes; + + // Otherwise - since we refuse to perform I/O on the main thread to find out for sure - we return the answer that says + // "You might be asked to load this later, so flag that" + return IconLoadDecision::Unknown; +} + +bool IconDatabase::synchronousIconDataKnownForIconURL(const String& iconURL) +{ + ASSERT_NOT_SYNC_THREAD(); + + LockHolder locker(m_urlAndIconLock); + if (IconRecord* icon = m_iconURLToRecordMap.get(iconURL)) + return icon->imageDataStatus() != IconRecord::ImageDataStatus::Unknown; + + return false; +} + +void IconDatabase::setEnabled(bool enabled) +{ + ASSERT_NOT_SYNC_THREAD(); + + if (!enabled && isOpen()) + close(); + m_isEnabled = enabled; +} + +bool IconDatabase::isEnabled() const +{ + ASSERT_NOT_SYNC_THREAD(); + + return m_isEnabled; +} + +void IconDatabase::setPrivateBrowsingEnabled(bool flag) +{ + m_privateBrowsingEnabled = flag; +} + +bool IconDatabase::isPrivateBrowsingEnabled() const +{ + return m_privateBrowsingEnabled; +} + +void IconDatabase::delayDatabaseCleanup() +{ + ++databaseCleanupCounter; + if (databaseCleanupCounter == 1) + LOG(IconDatabase, "Database cleanup is now DISABLED"); +} + +void IconDatabase::allowDatabaseCleanup() +{ + if (--databaseCleanupCounter < 0) + databaseCleanupCounter = 0; + if (!databaseCleanupCounter) + LOG(IconDatabase, "Database cleanup is now ENABLED"); +} + +void IconDatabase::checkIntegrityBeforeOpening() +{ + checkIntegrityOnOpen = true; +} + +IconDatabase::IconDatabase() + : m_syncTimer(RunLoop::main(), this, &IconDatabase::syncTimerFired) + , m_client(defaultClient()) +{ + LOG(IconDatabase, "Creating IconDatabase %p", this); + ASSERT(isMainThread()); +} + +IconDatabase::~IconDatabase() +{ + ASSERT(!isOpen()); +} + +void IconDatabase::wakeSyncThread() +{ + LockHolder locker(m_syncLock); + + m_syncThreadHasWorkToDo = true; + m_syncCondition.notifyOne(); +} + +void IconDatabase::scheduleOrDeferSyncTimer() +{ + ASSERT_NOT_SYNC_THREAD(); + + if (m_scheduleOrDeferSyncTimerRequested) + return; + + m_scheduleOrDeferSyncTimerRequested = true; + callOnMainThread([this] { + m_syncTimer.startOneShot(updateTimerDelay); + m_scheduleOrDeferSyncTimerRequested = false; + }); +} + +void IconDatabase::syncTimerFired() +{ + ASSERT_NOT_SYNC_THREAD(); + wakeSyncThread(); +} + +// ****************** +// *** Any Thread *** +// ****************** + +bool IconDatabase::isOpen() const +{ + LockHolder locker(m_syncLock); + return m_syncThreadRunning || m_syncDB.isOpen(); +} + +String IconDatabase::databasePath() const +{ + LockHolder locker(m_syncLock); + return m_completeDatabasePath.isolatedCopy(); +} + +String IconDatabase::defaultDatabaseFilename() +{ + static NeverDestroyed defaultDatabaseFilename(MAKE_STATIC_STRING_IMPL("WebpageIcons.db")); + return defaultDatabaseFilename.get().isolatedCopy(); +} + +// Unlike getOrCreatePageURLRecord(), getOrCreateIconRecord() does not mark the icon as "interested in import" +Ref IconDatabase::getOrCreateIconRecord(const String& iconURL) +{ + // Clients of getOrCreateIconRecord() are required to acquire the m_urlAndIconLock before calling this method + ASSERT(!m_urlAndIconLock.tryLock()); + + if (auto* icon = m_iconURLToRecordMap.get(iconURL)) + return *icon; + + auto newIcon = IconRecord::create(iconURL); + m_iconURLToRecordMap.set(iconURL, newIcon.ptr()); + return newIcon; +} + +// This method retrieves the existing PageURLRecord, or creates a new one and marks it as "interested in the import" for later notification +IconDatabase::PageURLRecord* IconDatabase::getOrCreatePageURLRecord(const String& pageURL) +{ + // Clients of getOrCreatePageURLRecord() are required to acquire the m_urlAndIconLock before calling this method + ASSERT(!m_urlAndIconLock.tryLock()); + + if (!documentCanHaveIcon(pageURL)) + return nullptr; + + PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL); + + LockHolder locker(m_pendingReadingLock); + if (!m_iconURLImportComplete) { + // If the initial import of all URLs hasn't completed and we have no page record, we assume we *might* know about this later and create a record for it + if (!pageRecord) { + LOG(IconDatabase, "Creating new PageURLRecord for pageURL %s", urlForLogging(pageURL).ascii().data()); + pageRecord = new PageURLRecord(pageURL); + m_pageURLToRecordMap.set(pageURL, pageRecord); + } + + // If the pageRecord for this page does not have an iconRecord attached to it, then it is a new pageRecord still awaiting the initial import + // Mark the URL as "interested in the result of the import" then bail + if (!pageRecord->iconRecord()) { + m_pageURLsPendingImport.add(pageURL); + return nullptr; + } + } + + // We've done the initial import of all URLs known in the database. If this record doesn't exist now, it never will + return pageRecord; +} + + +// ************************ +// *** Sync Thread Only *** +// ************************ + +bool IconDatabase::shouldStopThreadActivity() const +{ + ASSERT_ICON_SYNC_THREAD(); + + return m_threadTerminationRequested || m_removeIconsRequested; +} + +void IconDatabase::iconDatabaseSyncThread() +{ + // The call to create this thread might not complete before the thread actually starts, so we might fail this ASSERT_ICON_SYNC_THREAD() because the pointer + // to our thread structure hasn't been filled in yet. + // To fix this, the main thread acquires this lock before creating us, then releases the lock after creation is complete. A quick lock/unlock cycle here will + // prevent us from running before that call completes + m_syncLock.lock(); + m_syncLock.unlock(); + + ASSERT_ICON_SYNC_THREAD(); + + LOG(IconDatabase, "(THREAD) IconDatabase sync thread started"); + +#if !LOG_DISABLED + MonotonicTime startTime = MonotonicTime::now(); +#endif + + // Need to create the database path if it doesn't already exist + FileSystem::makeAllDirectories(m_databaseDirectory); + + // Existence of a journal file is evidence of a previous crash/force quit and automatically qualifies + // us to do an integrity check + String journalFilename = m_completeDatabasePath + "-journal"; + if (!checkIntegrityOnOpen) + checkIntegrityOnOpen = FileSystem::fileExists(journalFilename); + + { + LockHolder locker(m_syncLock); + if (!m_syncDB.open(m_completeDatabasePath)) { + LOG_ERROR("Unable to open icon database at path %s - %s", m_completeDatabasePath.ascii().data(), m_syncDB.lastErrorMsg()); + return; + } + } + + if (shouldStopThreadActivity()) { + syncThreadMainLoop(); + return; + } + +#if !LOG_DISABLED + MonotonicTime timeStamp = MonotonicTime::now(); + Seconds delta = timeStamp - startTime; + LOG(IconDatabase, "(THREAD) Open took %.4f seconds", delta.value()); +#endif + + performOpenInitialization(); + if (shouldStopThreadActivity()) { + syncThreadMainLoop(); + return; + } + +#if !LOG_DISABLED + MonotonicTime newStamp = MonotonicTime::now(); + Seconds totalDelta = newStamp - startTime; + delta = newStamp - timeStamp; + LOG(IconDatabase, "(THREAD) performOpenInitialization() took %.4f seconds, now %.4f seconds from thread start", delta.value(), totalDelta.value()); + timeStamp = newStamp; +#endif + + // Uncomment the following line to simulate a long lasting URL import (*HUGE* icon databases, or network home directories) + // while (MonotonicTime::now() - timeStamp < 10_s); + + // Read in URL mappings from the database + LOG(IconDatabase, "(THREAD) Starting iconURL import"); + performURLImport(); + + if (shouldStopThreadActivity()) { + syncThreadMainLoop(); + return; + } + +#if !LOG_DISABLED + newStamp = MonotonicTime::now(); + totalDelta = newStamp - startTime; + delta = newStamp - timeStamp; + LOG(IconDatabase, "(THREAD) performURLImport() took %.4f seconds. Entering main loop %.4f seconds from thread start", delta.value(), totalDelta.value()); +#endif + + LOG(IconDatabase, "(THREAD) Beginning sync"); + syncThreadMainLoop(); +} + +static int databaseVersionNumber(SQLiteDatabase& db) +{ + return SQLiteStatement(db, "SELECT value FROM IconDatabaseInfo WHERE key = 'Version';").getColumnInt(0); +} + +static bool isValidDatabase(SQLiteDatabase& db) +{ + // These four tables should always exist in a valid db + if (!db.tableExists("IconInfo") || !db.tableExists("IconData") || !db.tableExists("PageURL") || !db.tableExists("IconDatabaseInfo")) + return false; + + if (databaseVersionNumber(db) < currentDatabaseVersion) { + LOG(IconDatabase, "DB version is not found or below expected valid version"); + return false; + } + + return true; +} + +static void createDatabaseTables(SQLiteDatabase& db) +{ + if (!db.executeCommand("CREATE TABLE PageURL (url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,iconID INTEGER NOT NULL ON CONFLICT FAIL);")) { + LOG_ERROR("Could not create PageURL table in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand("CREATE INDEX PageURLIndex ON PageURL (url);")) { + LOG_ERROR("Could not create PageURL index in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand("CREATE TABLE IconInfo (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, url TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, stamp INTEGER);")) { + LOG_ERROR("Could not create IconInfo table in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand("CREATE INDEX IconInfoIndex ON IconInfo (url, iconID);")) { + LOG_ERROR("Could not create PageURL index in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand("CREATE TABLE IconData (iconID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE ON CONFLICT REPLACE, data BLOB);")) { + LOG_ERROR("Could not create IconData table in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand("CREATE INDEX IconDataIndex ON IconData (iconID);")) { + LOG_ERROR("Could not create PageURL index in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand("CREATE TABLE IconDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) { + LOG_ERROR("Could not create IconDatabaseInfo table in database (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } + if (!db.executeCommand(String("INSERT INTO IconDatabaseInfo VALUES ('Version', ") + String::number(currentDatabaseVersion) + ");")) { + LOG_ERROR("Could not insert icon database version into IconDatabaseInfo table (%i) - %s", db.lastError(), db.lastErrorMsg()); + db.close(); + return; + } +} + +void IconDatabase::performOpenInitialization() +{ + ASSERT_ICON_SYNC_THREAD(); + + if (!isOpen()) + return; + + if (checkIntegrityOnOpen) { + checkIntegrityOnOpen = false; + if (!checkIntegrity()) { + LOG(IconDatabase, "Integrity check was bad - dumping IconDatabase"); + + m_syncDB.close(); + + { + LockHolder locker(m_syncLock); + // Should've been consumed by SQLite, delete just to make sure we don't see it again in the future; + FileSystem::deleteFile(m_completeDatabasePath + "-journal"); + FileSystem::deleteFile(m_completeDatabasePath); + } + + // Reopen the write database, creating it from scratch + if (!m_syncDB.open(m_completeDatabasePath)) { + LOG_ERROR("Unable to open icon database at path %s - %s", m_completeDatabasePath.ascii().data(), m_syncDB.lastErrorMsg()); + return; + } + } + } + + int version = databaseVersionNumber(m_syncDB); + + if (version > currentDatabaseVersion) { + LOG(IconDatabase, "Database version number %i is greater than our current version number %i - closing the database to prevent overwriting newer versions", version, currentDatabaseVersion); + m_syncDB.close(); + m_threadTerminationRequested = true; + return; + } + + if (!isValidDatabase(m_syncDB)) { + LOG(IconDatabase, "%s is missing or in an invalid state - reconstructing", m_completeDatabasePath.ascii().data()); + m_syncDB.clearAllTables(); + createDatabaseTables(m_syncDB); + } + + // Reduce sqlite RAM cache size from default 2000 pages (~1.5kB per page). 3MB of cache for icon database is overkill + if (!SQLiteStatement(m_syncDB, "PRAGMA cache_size = 200;").executeCommand()) + LOG_ERROR("SQLite database could not set cache_size"); +} + +bool IconDatabase::checkIntegrity() +{ + ASSERT_ICON_SYNC_THREAD(); + + SQLiteStatement integrity(m_syncDB, "PRAGMA integrity_check;"); + if (integrity.prepare() != SQLITE_OK) { + LOG_ERROR("checkIntegrity failed to execute"); + return false; + } + + int resultCode = integrity.step(); + if (resultCode == SQLITE_OK) + return true; + + if (resultCode != SQLITE_ROW) + return false; + + int columns = integrity.columnCount(); + if (columns != 1) { + LOG_ERROR("Received %i columns performing integrity check, should be 1", columns); + return false; + } + + String resultText = integrity.getColumnText(0); + + // A successful, no-error integrity check will be "ok" - all other strings imply failure + if (resultText == "ok") + return true; + + LOG_ERROR("Icon database integrity check failed - \n%s", resultText.ascii().data()); + return false; +} + +void IconDatabase::performURLImport() +{ + ASSERT_ICON_SYNC_THREAD(); + + // Do not import icons not used in the last 30 days. They will be automatically pruned later if nobody retains them. + // Note that IconInfo.stamp is only set when the icon data is retrieved from the server (and thus is not updated whether + // we use it or not). This code works anyway because the IconDatabase downloads icons again if they are older than 4 days, + // so if the timestamp goes back in time more than those 30 days we can be sure that the icon was not used at all. + String importQuery = makeString("SELECT PageURL.url, IconInfo.url, IconInfo.stamp FROM PageURL INNER JOIN IconInfo ON PageURL.iconID=IconInfo.iconID WHERE IconInfo.stamp > ", floor((WallTime::now() - notUsedIconExpirationTime).secondsSinceEpoch().seconds()), ';'); + + SQLiteStatement query(m_syncDB, importQuery); + + if (query.prepare() != SQLITE_OK) { + LOG_ERROR("Unable to prepare icon url import query"); + return; + } + + int result = query.step(); + while (result == SQLITE_ROW) { + String pageURL = query.getColumnText(0); + String iconURL = query.getColumnText(1); + + { + LockHolder locker(m_urlAndIconLock); + + PageURLRecord* pageRecord = m_pageURLToRecordMap.get(pageURL); + + // If the pageRecord doesn't exist in this map, then no one has retained this pageURL + // If the s_databaseCleanupCounter count is non-zero, then we're not supposed to be pruning the database in any manner, + // so actually create a pageURLRecord for this url even though it's not retained. + // If database cleanup *is* allowed, we don't want to bother pulling in a page url from disk that noone is actually interested + // in - we'll prune it later instead! + if (!pageRecord && databaseCleanupCounter && documentCanHaveIcon(pageURL)) { + pageRecord = new PageURLRecord(pageURL); + m_pageURLToRecordMap.set(pageURL, pageRecord); + } + + if (pageRecord) { + IconRecord* currentIcon = pageRecord->iconRecord(); + + if (!currentIcon || currentIcon->iconURL() != iconURL) { + pageRecord->setIconRecord(getOrCreateIconRecord(iconURL)); + currentIcon = pageRecord->iconRecord(); + } + + // Regardless, the time stamp from disk still takes precedence. Until we read this icon from disk, we didn't think we'd seen it before + // so we marked the timestamp as "now", but it's really much older + currentIcon->setTimestamp(query.getColumnInt(2)); + } + } + + // FIXME: Currently the WebKit API supports 1 type of notification that is sent whenever we get an Icon URL for a Page URL. We might want to re-purpose it to work for + // getting the actually icon itself also (so each pageurl would get this notification twice) or we might want to add a second type of notification - + // one for the URL and one for the Image itself + // Note that WebIconDatabase is not neccessarily API so we might be able to make this change + { + LockHolder locker(m_pendingReadingLock); + if (m_pageURLsPendingImport.contains(pageURL)) { + dispatchDidImportIconURLForPageURLOnMainThread(pageURL); + m_pageURLsPendingImport.remove(pageURL); + } + } + + // Stop the import at any time of the thread has been asked to shutdown + if (shouldStopThreadActivity()) { + LOG(IconDatabase, "IconDatabase asked to terminate during performURLImport()"); + return; + } + + result = query.step(); + } + + if (result != SQLITE_DONE) + LOG(IconDatabase, "Error reading page->icon url mappings from database"); + + // Clear the m_pageURLsPendingImport set - either the page URLs ended up with an iconURL (that we'll notify about) or not, + // but after m_iconURLImportComplete is set to true, we don't care about this set anymore + Vector urls; + { + LockHolder locker(m_pendingReadingLock); + + urls.appendRange(m_pageURLsPendingImport.begin(), m_pageURLsPendingImport.end()); + m_pageURLsPendingImport.clear(); + m_iconURLImportComplete = true; + } + + Vector urlsToNotify; + + // Loop through the urls pending import + // Remove unretained ones if database cleanup is allowed + // Keep a set of ones that are retained and pending notification + { + LockHolder locker(m_urlAndIconLock); + + performPendingRetainAndReleaseOperations(); + + for (auto& url : urls) { + if (!m_retainedPageURLs.contains(url)) { + PageURLRecord* record = m_pageURLToRecordMap.get(url); + if (record && !databaseCleanupCounter) { + m_pageURLToRecordMap.remove(url); + IconRecord* iconRecord = record->iconRecord(); + + // If this page is the only remaining retainer of its icon, mark that icon for deletion and don't bother + // reading anything related to it + if (iconRecord && iconRecord->hasOneRef()) { + m_iconURLToRecordMap.remove(iconRecord->iconURL()); + + { + LockHolder locker(m_pendingReadingLock); + m_pageURLsInterestedInIcons.remove(url); + m_iconsPendingReading.remove(iconRecord); + } + { + LockHolder locker(m_pendingSyncLock); + m_iconsPendingSync.set(iconRecord->iconURL(), iconRecord->snapshot(true)); + } + } + + delete record; + } + } else + urlsToNotify.append(url); + } + } + + LOG(IconDatabase, "Notifying %lu interested page URLs that their icon URL is known due to the import", static_cast(urlsToNotify.size())); + // Now that we don't hold any locks, perform the actual notifications + for (auto& url : urlsToNotify) { + LOG(IconDatabase, "Notifying icon info known for pageURL %s", url.ascii().data()); + dispatchDidImportIconURLForPageURLOnMainThread(url); + if (shouldStopThreadActivity()) + return; + } + + // Notify the client that the URL import is complete in case it's managing its own pending notifications. + dispatchDidFinishURLImportOnMainThread(); +} + +void IconDatabase::syncThreadMainLoop() +{ + ASSERT_ICON_SYNC_THREAD(); + + m_syncLock.lock(); + + // We'll either do any pending work on our first pass through the loop, or we'll terminate + // without doing any work. Either way we're dealing with any currently-pending work. + m_syncThreadHasWorkToDo = false; + + // It's possible thread termination is requested before the main loop even starts - in that case, just skip straight to cleanup + while (!m_threadTerminationRequested) { + m_syncLock.unlock(); + +#if !LOG_DISABLED + MonotonicTime timeStamp = MonotonicTime::now(); +#endif + LOG(IconDatabase, "(THREAD) Main work loop starting"); + + // If we should remove all icons, do it now. This is an uninteruptible procedure that we will always do before quitting if it is requested + if (m_removeIconsRequested) { + removeAllIconsOnThread(); + m_removeIconsRequested = false; + } + + // Then, if the thread should be quitting, quit now! + if (m_threadTerminationRequested) { + cleanupSyncThread(); + return; + } + + { + LockHolder locker(m_urlAndIconLock); + performPendingRetainAndReleaseOperations(); + } + + bool didAnyWork = true; + while (didAnyWork) { + bool didWrite = writeToDatabase(); + if (shouldStopThreadActivity()) + break; + + didAnyWork = readFromDatabase(); + if (shouldStopThreadActivity()) + break; + + // Prune unretained icons after the first time we sync anything out to the database + // This way, pruning won't be the only operation we perform to the database by itself + // We also don't want to bother doing this if the thread should be terminating (the user is quitting) + // or if private browsing is enabled + // We also don't want to prune if the m_databaseCleanupCounter count is non-zero - that means someone + // has asked to delay pruning + static bool prunedUnretainedIcons = false; + if (didWrite && !m_privateBrowsingEnabled && !prunedUnretainedIcons && !databaseCleanupCounter) { +#if !LOG_DISABLED + MonotonicTime time = MonotonicTime::now(); +#endif + LOG(IconDatabase, "(THREAD) Starting pruneUnretainedIcons()"); + + pruneUnretainedIcons(); + +#if !LOG_DISABLED + Seconds delta = MonotonicTime::now() - time; +#endif + LOG(IconDatabase, "(THREAD) pruneUnretainedIcons() took %.4f seconds", delta.value()); + + // If pruneUnretainedIcons() returned early due to requested thread termination, its still okay + // to mark prunedUnretainedIcons true because we're about to terminate anyway + prunedUnretainedIcons = true; + } + + didAnyWork = didAnyWork || didWrite; + if (shouldStopThreadActivity()) + break; + } + +#if !LOG_DISABLED + MonotonicTime newstamp = MonotonicTime::now(); + Seconds delta = newstamp - timeStamp; + LOG(IconDatabase, "(THREAD) Main work loop ran for %.4f seconds, %s requested to terminate", delta.value(), shouldStopThreadActivity() ? "was" : "was not"); +#endif + + m_syncLock.lock(); + + // There is some condition that is asking us to stop what we're doing now and handle a special case + // This is either removing all icons, or shutting down the thread to quit the app + // We handle those at the top of this main loop so continue to jump back up there + if (shouldStopThreadActivity()) + continue; + + while (!m_syncThreadHasWorkToDo) + m_syncCondition.wait(m_syncLock); + + m_syncThreadHasWorkToDo = false; + } + + m_syncLock.unlock(); + + // Thread is terminating at this point + cleanupSyncThread(); +} + +void IconDatabase::performPendingRetainAndReleaseOperations() +{ + // NOTE: The caller is assumed to hold m_urlAndIconLock. + ASSERT(!m_urlAndIconLock.tryLock()); + + HashCountedSet toRetain; + HashCountedSet toRelease; + + { + LockHolder pendingWorkLocker(m_urlsToRetainOrReleaseLock); + if (!m_retainOrReleaseIconRequested) + return; + + // Make a copy of the URLs to retain and/or release so we can release m_urlsToRetainOrReleaseLock ASAP. + // Holding m_urlAndIconLock protects this function from being re-entered. + + toRetain.swap(m_urlsToRetain); + toRelease.swap(m_urlsToRelease); + m_retainOrReleaseIconRequested = false; + } + + for (auto& entry : toRetain) { + ASSERT(!entry.key.impl() || entry.key.impl()->hasOneRef()); + performRetainIconForPageURL(entry.key, entry.value); + } + + for (auto& entry : toRelease) { + ASSERT(!entry.key.impl() || entry.key.impl()->hasOneRef()); + performReleaseIconForPageURL(entry.key, entry.value); + } +} + +bool IconDatabase::readFromDatabase() +{ + ASSERT_ICON_SYNC_THREAD(); + +#if !LOG_DISABLED + MonotonicTime timeStamp = MonotonicTime::now(); +#endif + + bool didAnyWork = false; + + // We'll make a copy of the sets of things that need to be read. Then we'll verify at the time of updating the record that it still wants to be updated + // This way we won't hold the lock for a long period of time + Vector icons; + { + LockHolder locker(m_pendingReadingLock); + icons.appendRange(m_iconsPendingReading.begin(), m_iconsPendingReading.end()); + } + + // Keep track of icons we actually read to notify them of the new icon + HashSet urlsToNotify; + + for (unsigned i = 0; i < icons.size(); ++i) { + didAnyWork = true; + auto imageData = getImageDataForIconURLFromSQLDatabase(icons[i]->iconURL()); + + // Verify this icon still wants to be read from disk + { + LockHolder urlLocker(m_urlAndIconLock); + { + LockHolder readLocker(m_pendingReadingLock); + + if (m_iconsPendingReading.contains(icons[i])) { + // Set the new data + icons[i]->setImageData(WTFMove(imageData)); + + // Remove this icon from the set that needs to be read + m_iconsPendingReading.remove(icons[i]); + + // We have a set of all Page URLs that retain this icon as well as all PageURLs waiting for an icon + // We want to find the intersection of these two sets to notify them + // Check the sizes of these two sets to minimize the number of iterations + const HashSet* outerHash; + const HashSet* innerHash; + + if (icons[i]->retainingPageURLs().size() > m_pageURLsInterestedInIcons.size()) { + outerHash = &m_pageURLsInterestedInIcons; + innerHash = &(icons[i]->retainingPageURLs()); + } else { + innerHash = &m_pageURLsInterestedInIcons; + outerHash = &(icons[i]->retainingPageURLs()); + } + + for (auto& outer : *outerHash) { + if (innerHash->contains(outer)) { + LOG(IconDatabase, "%s is interested in the icon we just read. Adding it to the notification list and removing it from the interested set", urlForLogging(outer).ascii().data()); + urlsToNotify.add(outer); + } + + // If we ever get to the point were we've seen every url interested in this icon, break early + if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size()) + break; + } + + // We don't need to notify a PageURL twice, so all the ones we're about to notify can be removed from the interested set + if (urlsToNotify.size() == m_pageURLsInterestedInIcons.size()) + m_pageURLsInterestedInIcons.clear(); + else { + for (auto& url : urlsToNotify) + m_pageURLsInterestedInIcons.remove(url); + } + } + } + } + + if (shouldStopThreadActivity()) + return didAnyWork; + + // Now that we don't hold any locks, perform the actual notifications + for (HashSet::const_iterator it = urlsToNotify.begin(), end = urlsToNotify.end(); it != end; ++it) { + LOG(IconDatabase, "Notifying icon received for pageURL %s", urlForLogging(*it).ascii().data()); + dispatchDidImportIconDataForPageURLOnMainThread(*it); + if (shouldStopThreadActivity()) + return didAnyWork; + } + + LOG(IconDatabase, "Done notifying %i pageURLs who just received their icons", urlsToNotify.size()); + urlsToNotify.clear(); + + if (shouldStopThreadActivity()) + return didAnyWork; + } + +#if !LOG_DISABLED + Seconds delta = MonotonicTime::now() - timeStamp; + LOG(IconDatabase, "Reading from database took %.4f seconds", delta.value()); +#endif + + return didAnyWork; +} + +bool IconDatabase::writeToDatabase() +{ + ASSERT_ICON_SYNC_THREAD(); + +#if !LOG_DISABLED + MonotonicTime timeStamp = MonotonicTime::now(); +#endif + + bool didAnyWork = false; + + // We can copy the current work queue then clear it out - If any new work comes in while we're writing out, + // we'll pick it up on the next pass. This greatly simplifies the locking strategy for this method and remains cohesive with changes + // asked for by the database on the main thread + { + LockHolder locker(m_urlAndIconLock); + Vector iconSnapshots; + Vector pageSnapshots; + { + LockHolder locker(m_pendingSyncLock); + + iconSnapshots.appendRange(m_iconsPendingSync.begin().values(), m_iconsPendingSync.end().values()); + m_iconsPendingSync.clear(); + + pageSnapshots.appendRange(m_pageURLsPendingSync.begin().values(), m_pageURLsPendingSync.end().values()); + m_pageURLsPendingSync.clear(); + } + + if (iconSnapshots.size() || pageSnapshots.size()) + didAnyWork = true; + + SQLiteTransaction syncTransaction(m_syncDB); + syncTransaction.begin(); + + for (auto& snapshot : iconSnapshots) { + writeIconSnapshotToSQLDatabase(snapshot); + LOG(IconDatabase, "Wrote IconRecord for IconURL %s with timeStamp of %i to the DB", urlForLogging(snapshot.iconURL()).ascii().data(), snapshot.timestamp()); + } + + for (auto& snapshot : pageSnapshots) { + // If the icon URL is empty, this page is meant to be deleted + // ASSERTs are sanity checks to make sure the mappings exist if they should and don't if they shouldn't + if (snapshot.iconURL().isEmpty()) + removePageURLFromSQLDatabase(snapshot.pageURL()); + else + setIconURLForPageURLInSQLDatabase(snapshot.iconURL(), snapshot.pageURL()); + LOG(IconDatabase, "Committed IconURL for PageURL %s to database", urlForLogging(snapshot.pageURL()).ascii().data()); + } + + syncTransaction.commit(); + } + + // Check to make sure there are no dangling PageURLs - If there are, we want to output one log message but not spam the console potentially every few seconds + if (didAnyWork) + checkForDanglingPageURLs(false); + +#if !LOG_DISABLED + Seconds delta = MonotonicTime::now() - timeStamp; + LOG(IconDatabase, "Updating the database took %.4f seconds", delta.value()); +#endif + + return didAnyWork; +} + +void IconDatabase::pruneUnretainedIcons() +{ + ASSERT_ICON_SYNC_THREAD(); + + if (!isOpen()) + return; + + // This method should only be called once per run + ASSERT(!m_initialPruningComplete); + + // This method relies on having read in all page URLs from the database earlier. + ASSERT(m_iconURLImportComplete); + + // Get the known PageURLs from the db, and record the ID of any that are not in the retain count set. + Vector pageIDsToDelete; + + SQLiteStatement pageSQL(m_syncDB, "SELECT rowid, url FROM PageURL;"); + pageSQL.prepare(); + + int result; + while ((result = pageSQL.step()) == SQLITE_ROW) { + LockHolder locker(m_urlAndIconLock); + if (!m_pageURLToRecordMap.contains(pageSQL.getColumnText(1))) + pageIDsToDelete.append(pageSQL.getColumnInt64(0)); + } + + if (result != SQLITE_DONE) + LOG_ERROR("Error reading PageURL table from on-disk DB"); + pageSQL.finalize(); + + // Delete page URLs that were in the table, but not in our retain count set. + size_t numToDelete = pageIDsToDelete.size(); + if (numToDelete) { + SQLiteTransaction pruningTransaction(m_syncDB); + pruningTransaction.begin(); + + SQLiteStatement pageDeleteSQL(m_syncDB, "DELETE FROM PageURL WHERE rowid = (?);"); + pageDeleteSQL.prepare(); + for (size_t i = 0; i < numToDelete; ++i) { + LOG(IconDatabase, "Pruning page with rowid %lli from disk", static_cast(pageIDsToDelete[i])); + pageDeleteSQL.bindInt64(1, pageIDsToDelete[i]); + int result = pageDeleteSQL.step(); + if (result != SQLITE_DONE) + LOG_ERROR("Unabled to delete page with id %lli from disk", static_cast(pageIDsToDelete[i])); + pageDeleteSQL.reset(); + + // If the thread was asked to terminate, we should commit what pruning we've done so far, figuring we can + // finish the rest later (hopefully) + if (shouldStopThreadActivity()) { + pruningTransaction.commit(); + return; + } + } + pruningTransaction.commit(); + pageDeleteSQL.finalize(); + } + + // Deleting unreferenced icons from the Icon tables has to be atomic - + // If the user quits while these are taking place, they might have to wait. Thankfully this will rarely be an issue + // A user on a network home directory with a wildly inconsistent database might see quite a pause... + + SQLiteTransaction pruningTransaction(m_syncDB); + pruningTransaction.begin(); + + // Wipe Icons that aren't retained + if (!m_syncDB.executeCommand("DELETE FROM IconData WHERE iconID NOT IN (SELECT iconID FROM PageURL);")) + LOG_ERROR("Failed to execute SQL to prune unretained icons from the on-disk IconData table"); + if (!m_syncDB.executeCommand("DELETE FROM IconInfo WHERE iconID NOT IN (SELECT iconID FROM PageURL);")) + LOG_ERROR("Failed to execute SQL to prune unretained icons from the on-disk IconInfo table"); + + pruningTransaction.commit(); + + checkForDanglingPageURLs(true); + + m_initialPruningComplete = true; +} + +void IconDatabase::checkForDanglingPageURLs(bool pruneIfFound) +{ + ASSERT_ICON_SYNC_THREAD(); + + // This check can be relatively expensive so we don't do it in a release build unless the caller has asked us to prune any dangling + // entries. We also don't want to keep performing this check and reporting this error if it has already found danglers before so we + // keep track of whether we've found any. We skip the check in the release build pretending to have already found danglers already. +#ifndef NDEBUG + static bool danglersFound = true; +#else + static bool danglersFound = false; +#endif + + if ((pruneIfFound || !danglersFound) && SQLiteStatement(m_syncDB, "SELECT url FROM PageURL WHERE PageURL.iconID NOT IN (SELECT iconID FROM IconInfo) LIMIT 1;").returnsAtLeastOneResult()) { + danglersFound = true; + LOG(IconDatabase, "Dangling PageURL entries found"); + if (pruneIfFound && !m_syncDB.executeCommand("DELETE FROM PageURL WHERE iconID NOT IN (SELECT iconID FROM IconInfo);")) + LOG(IconDatabase, "Unable to prune dangling PageURLs"); + } +} + +void IconDatabase::removeAllIconsOnThread() +{ + ASSERT_ICON_SYNC_THREAD(); + + LOG(IconDatabase, "Removing all icons on the sync thread"); + + // Delete all the prepared statements so they can start over + deleteAllPreparedStatements(); + + // To reset the on-disk database, we'll wipe all its tables then vacuum it + // This is easier and safer than closing it, deleting the file, and recreating from scratch + m_syncDB.clearAllTables(); + m_syncDB.runVacuumCommand(); + createDatabaseTables(m_syncDB); +} + +void IconDatabase::deleteAllPreparedStatements() +{ + ASSERT_ICON_SYNC_THREAD(); + + m_setIconIDForPageURLStatement = nullptr; + m_removePageURLStatement = nullptr; + m_getIconIDForIconURLStatement = nullptr; + m_getImageDataForIconURLStatement = nullptr; + m_addIconToIconInfoStatement = nullptr; + m_addIconToIconDataStatement = nullptr; + m_getImageDataStatement = nullptr; + m_deletePageURLsForIconURLStatement = nullptr; + m_deleteIconFromIconInfoStatement = nullptr; + m_deleteIconFromIconDataStatement = nullptr; + m_updateIconInfoStatement = nullptr; + m_updateIconDataStatement = nullptr; + m_setIconInfoStatement = nullptr; + m_setIconDataStatement = nullptr; +} + +void* IconDatabase::cleanupSyncThread() +{ + ASSERT_ICON_SYNC_THREAD(); + +#if !LOG_DISABLED + MonotonicTime timeStamp = MonotonicTime::now(); +#endif + + // If the removeIcons flag is set, remove all icons from the db. + if (m_removeIconsRequested) + removeAllIconsOnThread(); + + // Sync remaining icons out + LOG(IconDatabase, "(THREAD) Doing final writeout and closure of sync thread"); + writeToDatabase(); + + // Close the database + LockHolder locker(m_syncLock); + + m_databaseDirectory = String(); + m_completeDatabasePath = String(); + deleteAllPreparedStatements(); + m_syncDB.close(); + +#if !LOG_DISABLED + Seconds delta = MonotonicTime::now() - timeStamp; + LOG(IconDatabase, "(THREAD) Final closure took %.4f seconds", delta.value()); +#endif + + m_syncThreadRunning = false; + return nullptr; +} + +// readySQLiteStatement() handles two things +// 1 - If the SQLDatabase& argument is different, the statement must be destroyed and remade. This happens when the user +// switches to and from private browsing +// 2 - Lazy construction of the Statement in the first place, in case we've never made this query before +inline void readySQLiteStatement(std::unique_ptr& statement, SQLiteDatabase& db, const String& str) +{ + if (statement && (&statement->database() != &db || statement->isExpired())) { + if (statement->isExpired()) + LOG(IconDatabase, "SQLiteStatement associated with %s is expired", str.ascii().data()); + statement = nullptr; + } + if (!statement) { + statement = std::make_unique(db, str); + if (statement->prepare() != SQLITE_OK) + LOG_ERROR("Preparing statement %s failed", str.ascii().data()); + } +} + +void IconDatabase::setIconURLForPageURLInSQLDatabase(const String& iconURL, const String& pageURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + int64_t iconID = getIconIDForIconURLFromSQLDatabase(iconURL); + + if (!iconID) + iconID = addIconURLToSQLDatabase(iconURL); + + if (!iconID) { + LOG_ERROR("Failed to establish an ID for iconURL %s", urlForLogging(iconURL).ascii().data()); + ASSERT_NOT_REACHED(); + return; + } + + setIconIDForPageURLInSQLDatabase(iconID, pageURL); +} + +void IconDatabase::setIconIDForPageURLInSQLDatabase(int64_t iconID, const String& pageURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + readySQLiteStatement(m_setIconIDForPageURLStatement, m_syncDB, "INSERT INTO PageURL (url, iconID) VALUES ((?), ?);"); + m_setIconIDForPageURLStatement->bindText(1, pageURL); + m_setIconIDForPageURLStatement->bindInt64(2, iconID); + + int result = m_setIconIDForPageURLStatement->step(); + if (result != SQLITE_DONE) { + ASSERT_NOT_REACHED(); + LOG_ERROR("setIconIDForPageURLQuery failed for url %s", urlForLogging(pageURL).ascii().data()); + } + + m_setIconIDForPageURLStatement->reset(); +} + +void IconDatabase::removePageURLFromSQLDatabase(const String& pageURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + readySQLiteStatement(m_removePageURLStatement, m_syncDB, "DELETE FROM PageURL WHERE url = (?);"); + m_removePageURLStatement->bindText(1, pageURL); + + if (m_removePageURLStatement->step() != SQLITE_DONE) + LOG_ERROR("removePageURLFromSQLDatabase failed for url %s", urlForLogging(pageURL).ascii().data()); + + m_removePageURLStatement->reset(); +} + + +int64_t IconDatabase::getIconIDForIconURLFromSQLDatabase(const String& iconURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + readySQLiteStatement(m_getIconIDForIconURLStatement, m_syncDB, "SELECT IconInfo.iconID FROM IconInfo WHERE IconInfo.url = (?);"); + m_getIconIDForIconURLStatement->bindText(1, iconURL); + + int64_t result = m_getIconIDForIconURLStatement->step(); + if (result == SQLITE_ROW) + result = m_getIconIDForIconURLStatement->getColumnInt64(0); + else { + if (result != SQLITE_DONE) + LOG_ERROR("getIconIDForIconURLFromSQLDatabase failed for url %s", urlForLogging(iconURL).ascii().data()); + result = 0; + } + + m_getIconIDForIconURLStatement->reset(); + return result; +} + +int64_t IconDatabase::addIconURLToSQLDatabase(const String& iconURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + // There would be a transaction here to make sure these two inserts are atomic + // In practice the only caller of this method is always wrapped in a transaction itself so placing another + // here is unnecessary + + readySQLiteStatement(m_addIconToIconInfoStatement, m_syncDB, "INSERT INTO IconInfo (url, stamp) VALUES (?, 0);"); + m_addIconToIconInfoStatement->bindText(1, iconURL); + + int result = m_addIconToIconInfoStatement->step(); + m_addIconToIconInfoStatement->reset(); + if (result != SQLITE_DONE) { + LOG_ERROR("addIconURLToSQLDatabase failed to insert %s into IconInfo", urlForLogging(iconURL).ascii().data()); + return 0; + } + int64_t iconID = m_syncDB.lastInsertRowID(); + + readySQLiteStatement(m_addIconToIconDataStatement, m_syncDB, "INSERT INTO IconData (iconID, data) VALUES (?, ?);"); + m_addIconToIconDataStatement->bindInt64(1, iconID); + + result = m_addIconToIconDataStatement->step(); + m_addIconToIconDataStatement->reset(); + if (result != SQLITE_DONE) { + LOG_ERROR("addIconURLToSQLDatabase failed to insert %s into IconData", urlForLogging(iconURL).ascii().data()); + return 0; + } + + return iconID; +} + +RefPtr IconDatabase::getImageDataForIconURLFromSQLDatabase(const String& iconURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + RefPtr imageData; + + readySQLiteStatement(m_getImageDataForIconURLStatement, m_syncDB, "SELECT IconData.data FROM IconData WHERE IconData.iconID IN (SELECT iconID FROM IconInfo WHERE IconInfo.url = (?));"); + m_getImageDataForIconURLStatement->bindText(1, iconURL); + + int result = m_getImageDataForIconURLStatement->step(); + if (result == SQLITE_ROW) { + Vector data; + m_getImageDataForIconURLStatement->getColumnBlobAsVector(0, data); + imageData = SharedBuffer::create(data.data(), data.size()); + } else if (result != SQLITE_DONE) + LOG_ERROR("getImageDataForIconURLFromSQLDatabase failed for url %s", urlForLogging(iconURL).ascii().data()); + + m_getImageDataForIconURLStatement->reset(); + + return imageData; +} + +void IconDatabase::removeIconFromSQLDatabase(const String& iconURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + if (iconURL.isEmpty()) + return; + + // There would be a transaction here to make sure these removals are atomic + // In practice the only caller of this method is always wrapped in a transaction itself so placing another here is unnecessary + + // It's possible this icon is not in the database because of certain rapid browsing patterns (such as a stress test) where the + // icon is marked to be added then marked for removal before it is ever written to disk. No big deal, early return + int64_t iconID = getIconIDForIconURLFromSQLDatabase(iconURL); + if (!iconID) + return; + + readySQLiteStatement(m_deletePageURLsForIconURLStatement, m_syncDB, "DELETE FROM PageURL WHERE PageURL.iconID = (?);"); + m_deletePageURLsForIconURLStatement->bindInt64(1, iconID); + + if (m_deletePageURLsForIconURLStatement->step() != SQLITE_DONE) + LOG_ERROR("m_deletePageURLsForIconURLStatement failed for url %s", urlForLogging(iconURL).ascii().data()); + + readySQLiteStatement(m_deleteIconFromIconInfoStatement, m_syncDB, "DELETE FROM IconInfo WHERE IconInfo.iconID = (?);"); + m_deleteIconFromIconInfoStatement->bindInt64(1, iconID); + + if (m_deleteIconFromIconInfoStatement->step() != SQLITE_DONE) + LOG_ERROR("m_deleteIconFromIconInfoStatement failed for url %s", urlForLogging(iconURL).ascii().data()); + + readySQLiteStatement(m_deleteIconFromIconDataStatement, m_syncDB, "DELETE FROM IconData WHERE IconData.iconID = (?);"); + m_deleteIconFromIconDataStatement->bindInt64(1, iconID); + + if (m_deleteIconFromIconDataStatement->step() != SQLITE_DONE) + LOG_ERROR("m_deleteIconFromIconDataStatement failed for url %s", urlForLogging(iconURL).ascii().data()); + + m_deletePageURLsForIconURLStatement->reset(); + m_deleteIconFromIconInfoStatement->reset(); + m_deleteIconFromIconDataStatement->reset(); +} + +void IconDatabase::writeIconSnapshotToSQLDatabase(const IconSnapshot& snapshot) +{ + ASSERT_ICON_SYNC_THREAD(); + + if (snapshot.iconURL().isEmpty()) + return; + + // A nulled out timestamp and data means this icon is destined to be deleted - do that instead of writing it out + if (!snapshot.timestamp() && !snapshot.data()) { + LOG(IconDatabase, "Removing %s from on-disk database", urlForLogging(snapshot.iconURL()).ascii().data()); + removeIconFromSQLDatabase(snapshot.iconURL()); + return; + } + + // There would be a transaction here to make sure these removals are atomic + // In practice the only caller of this method is always wrapped in a transaction itself so placing another here is unnecessary + + // Get the iconID for this url + int64_t iconID = getIconIDForIconURLFromSQLDatabase(snapshot.iconURL()); + + // If there is already an iconID in place, update the database. + // Otherwise, insert new records + if (iconID) { + readySQLiteStatement(m_updateIconInfoStatement, m_syncDB, "UPDATE IconInfo SET stamp = ?, url = ? WHERE iconID = ?;"); + m_updateIconInfoStatement->bindInt64(1, snapshot.timestamp()); + m_updateIconInfoStatement->bindText(2, snapshot.iconURL()); + m_updateIconInfoStatement->bindInt64(3, iconID); + + if (m_updateIconInfoStatement->step() != SQLITE_DONE) + LOG_ERROR("Failed to update icon info for url %s", urlForLogging(snapshot.iconURL()).ascii().data()); + + m_updateIconInfoStatement->reset(); + + readySQLiteStatement(m_updateIconDataStatement, m_syncDB, "UPDATE IconData SET data = ? WHERE iconID = ?;"); + m_updateIconDataStatement->bindInt64(2, iconID); + + // If we *have* image data, bind it to this statement - Otherwise bind "null" for the blob data, + // signifying that this icon doesn't have any data + if (snapshot.data() && snapshot.data()->size()) + m_updateIconDataStatement->bindBlob(1, snapshot.data()->data(), snapshot.data()->size()); + else + m_updateIconDataStatement->bindNull(1); + + if (m_updateIconDataStatement->step() != SQLITE_DONE) + LOG_ERROR("Failed to update icon data for url %s", urlForLogging(snapshot.iconURL()).ascii().data()); + + m_updateIconDataStatement->reset(); + } else { + readySQLiteStatement(m_setIconInfoStatement, m_syncDB, "INSERT INTO IconInfo (url,stamp) VALUES (?, ?);"); + m_setIconInfoStatement->bindText(1, snapshot.iconURL()); + m_setIconInfoStatement->bindInt64(2, snapshot.timestamp()); + + if (m_setIconInfoStatement->step() != SQLITE_DONE) + LOG_ERROR("Failed to set icon info for url %s", urlForLogging(snapshot.iconURL()).ascii().data()); + + m_setIconInfoStatement->reset(); + + int64_t iconID = m_syncDB.lastInsertRowID(); + + readySQLiteStatement(m_setIconDataStatement, m_syncDB, "INSERT INTO IconData (iconID, data) VALUES (?, ?);"); + m_setIconDataStatement->bindInt64(1, iconID); + + // If we *have* image data, bind it to this statement - Otherwise bind "null" for the blob data, + // signifying that this icon doesn't have any data + if (snapshot.data() && snapshot.data()->size()) + m_setIconDataStatement->bindBlob(2, snapshot.data()->data(), snapshot.data()->size()); + else + m_setIconDataStatement->bindNull(2); + + if (m_setIconDataStatement->step() != SQLITE_DONE) + LOG_ERROR("Failed to set icon data for url %s", urlForLogging(snapshot.iconURL()).ascii().data()); + + m_setIconDataStatement->reset(); + } +} + +void IconDatabase::dispatchDidImportIconURLForPageURLOnMainThread(const String& pageURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + m_mainThreadNotifier.notify([this, pageURL = pageURL.isolatedCopy()] { + if (m_client) + m_client->didImportIconURLForPageURL(pageURL); + }); +} + +void IconDatabase::dispatchDidImportIconDataForPageURLOnMainThread(const String& pageURL) +{ + ASSERT_ICON_SYNC_THREAD(); + + m_mainThreadNotifier.notify([this, pageURL = pageURL.isolatedCopy()] { + if (m_client) + m_client->didImportIconDataForPageURL(pageURL); + }); +} + +void IconDatabase::dispatchDidFinishURLImportOnMainThread() +{ + ASSERT_ICON_SYNC_THREAD(); + + m_mainThreadNotifier.notify([this] { + if (m_client) + m_client->didFinishURLImport(); + }); +} + +IconDatabase& iconDatabase() +{ + static IconDatabase base; + return base; +} + +} // namespace WebKit diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/IconDatabase.h b/Source/WebKitLegacy/haiku/WebCoreSupport/IconDatabase.h new file mode 100644 index 000000000000..e0cc74290f0b --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/IconDatabase.h @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "NativeImage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace WebCore { +class SharedBuffer; +} + +namespace WebKit { + +class IconDatabaseClient { +public: + virtual ~IconDatabaseClient() = default; + + virtual void didImportIconURLForPageURL(const String&) { } + virtual void didImportIconDataForPageURL(const String&) { } + virtual void didChangeIconForPageURL(const String&) { } + virtual void didFinishURLImport() { } +}; + +class IconDatabase { + WTF_MAKE_FAST_ALLOCATED; + +private: + class IconSnapshot { + public: + IconSnapshot() = default; + + IconSnapshot(const String& iconURL, int timestamp, WebCore::SharedBuffer* data) + : m_iconURL(iconURL) + , m_timestamp(timestamp) + , m_data(data) + { } + + const String& iconURL() const { return m_iconURL; } + int timestamp() const { return m_timestamp; } + WebCore::SharedBuffer* data() const { return m_data.get(); } + + private: + String m_iconURL; + int m_timestamp { 0 }; + RefPtr m_data; + }; + + class IconRecord : public RefCounted { + public: + static Ref create(const String& url) + { + return adoptRef(*new IconRecord(url)); + } + ~IconRecord(); + + time_t getTimestamp() { return m_stamp; } + void setTimestamp(time_t stamp) { m_stamp = stamp; } + + void setImageData(RefPtr&&); + WebCore::NativeImagePtr image(const WebCore::IntSize&); + + String iconURL() { return m_iconURL; } + + enum class ImageDataStatus { Present, Missing, Unknown }; + ImageDataStatus imageDataStatus(); + + HashSet& retainingPageURLs() { return m_retainingPageURLs; } + + IconSnapshot snapshot(bool forDeletion = false) const; + + private: + IconRecord(const String& url); + + String m_iconURL; + time_t m_stamp { 0 }; + RefPtr m_imageData; + WebCore::NativeImagePtr m_image; + + HashSet m_retainingPageURLs; + + // This allows us to cache whether or not a SiteIcon has had its data set yet + // This helps the IconDatabase know if it has to set the data on a new object or not, + // and also to determine if the icon is missing data or if it just hasn't been brought + // in from the DB yet + bool m_dataSet { false }; + }; + + class PageURLSnapshot { + public: + PageURLSnapshot() = default; + + PageURLSnapshot(const String& pageURL, const String& iconURL) + : m_pageURL(pageURL) + , m_iconURL(iconURL) + { } + + const String& pageURL() const { return m_pageURL; } + const String& iconURL() const { return m_iconURL; } + + private: + String m_pageURL; + String m_iconURL; + }; + + class PageURLRecord { + WTF_MAKE_NONCOPYABLE(PageURLRecord); WTF_MAKE_FAST_ALLOCATED; + public: + PageURLRecord(const String& pageURL); + ~PageURLRecord(); + + inline String url() const { return m_pageURL; } + + void setIconRecord(RefPtr&&); + IconRecord* iconRecord() { return m_iconRecord.get(); } + + PageURLSnapshot snapshot(bool forDeletion = false) const; + + // Returns false if the page wasn't retained beforehand, true if the retain count was already 1 or higher. + bool retain(int count) + { + bool wasRetained = m_retainCount > 0; + m_retainCount += count; + return wasRetained; + } + + // Returns true if the page is still retained after the call. False if the retain count just dropped to 0. + bool release(int count) + { + ASSERT(m_retainCount >= count); + m_retainCount -= count; + return m_retainCount > 0; + } + + int retainCount() const { return m_retainCount; } + + private: + String m_pageURL; + RefPtr m_iconRecord; + int m_retainCount { 0 }; + }; + + class MainThreadNotifier { + public: + MainThreadNotifier() + : m_timer(RunLoop::main(), this, &MainThreadNotifier::timerFired) + { + //m_timer.setPriority(RunLoopSourcePriority::MainThreadDispatcherTimer); + } + + void setActive(bool active) + { + m_isActive.store(active); + } + + void notify(Function&& notification) + { + if (!m_isActive.load()) + return; + + { + LockHolder locker(m_notificationQueueLock); + m_notificationQueue.append(WTFMove(notification)); + } + + if (!m_timer.isActive()) + m_timer.startOneShot(0_s); + } + + void stop() + { + setActive(false); + m_timer.stop(); + LockHolder locker(m_notificationQueueLock); + m_notificationQueue.clear(); + } + + private: + void timerFired() + { + Deque> notificationQueue; + { + LockHolder locker(m_notificationQueueLock); + notificationQueue = WTFMove(m_notificationQueue); + } + + if (!m_isActive.load()) + return; + + while (!notificationQueue.isEmpty()) { + auto function = notificationQueue.takeFirst(); + function(); + } + } + + Deque> m_notificationQueue; + Lock m_notificationQueueLock; + Atomic m_isActive; + RunLoop::Timer m_timer; + }; + +// *** Main Thread Only *** +public: + IconDatabase(); + ~IconDatabase(); + + enum class IconLoadDecision { Yes, No, Unknown }; + + void setClient(std::unique_ptr&&); + + bool open(const String& directory, const String& filename); + void close(); + + void removeAllIcons(); + + void retainIconForPageURL(const String&); + void releaseIconForPageURL(const String&); + void setIconDataForIconURL(RefPtr&&, const String& iconURL); + void setIconURLForPageURL(const String& iconURL, const String& pageURL); + + enum class IsKnownIcon { No, Yes }; + std::pair synchronousIconForPageURL(const String&, const WebCore::IntSize&); + String synchronousIconURLForPageURL(const String&); + bool synchronousIconDataKnownForIconURL(const String&); + IconLoadDecision synchronousLoadDecisionForIconURL(const String&); + + void setEnabled(bool); + bool isEnabled() const; + + void setPrivateBrowsingEnabled(bool flag); + bool isPrivateBrowsingEnabled() const; + + static void delayDatabaseCleanup(); + static void allowDatabaseCleanup(); + static void checkIntegrityBeforeOpening(); + +private: + void wakeSyncThread(); + void scheduleOrDeferSyncTimer(); + void syncTimerFired(); + + RunLoop::Timer m_syncTimer; + RefPtr m_syncThread; + bool m_syncThreadRunning { false }; + bool m_scheduleOrDeferSyncTimerRequested { false }; + +// *** Any Thread *** +public: + bool isOpen() const; + String databasePath() const; + static String defaultDatabaseFilename(); + +private: + Ref getOrCreateIconRecord(const String& iconURL); + PageURLRecord* getOrCreatePageURLRecord(const String& pageURL); + + bool m_isEnabled {false }; + bool m_privateBrowsingEnabled { false }; + + mutable Lock m_syncLock; + Condition m_syncCondition; + String m_databaseDirectory; + // Holding m_syncLock is required when accessing m_completeDatabasePath + String m_completeDatabasePath; + + bool m_threadTerminationRequested { false }; + bool m_removeIconsRequested { false }; + bool m_iconURLImportComplete { false }; + bool m_syncThreadHasWorkToDo { false }; + + Lock m_urlAndIconLock; + // Holding m_urlAndIconLock is required when accessing any of the following data structures or the objects they contain + HashMap m_iconURLToRecordMap; + HashMap m_pageURLToRecordMap; + HashSet m_retainedPageURLs; + + Lock m_pendingSyncLock; + // Holding m_pendingSyncLock is required when accessing any of the following data structures + HashMap m_pageURLsPendingSync; + HashMap m_iconsPendingSync; + + Lock m_pendingReadingLock; + // Holding m_pendingSyncLock is required when accessing any of the following data structures - when dealing with IconRecord*s, holding m_urlAndIconLock is also required + HashSet m_pageURLsPendingImport; + HashSet m_pageURLsInterestedInIcons; + HashSet m_iconsPendingReading; + + Lock m_urlsToRetainOrReleaseLock; + // Holding m_urlsToRetainOrReleaseLock is required when accessing any of the following data structures. + HashCountedSet m_urlsToRetain; + HashCountedSet m_urlsToRelease; + bool m_retainOrReleaseIconRequested { false }; + +// *** Sync Thread Only *** +public: + bool shouldStopThreadActivity() const; + +private: + void iconDatabaseSyncThread(); + + // The following block of methods are called exclusively by the sync thread to manage i/o to and from the database + // Each method should periodically monitor m_threadTerminationRequested when it makes sense to return early on shutdown + void performOpenInitialization(); + bool checkIntegrity(); + void performURLImport(); + void syncThreadMainLoop(); + bool readFromDatabase(); + bool writeToDatabase(); + void pruneUnretainedIcons(); + void checkForDanglingPageURLs(bool pruneIfFound); + void removeAllIconsOnThread(); + void deleteAllPreparedStatements(); + void* cleanupSyncThread(); + void performRetainIconForPageURL(const String&, int retainCount); + void performReleaseIconForPageURL(const String&, int releaseCount); + + bool m_initialPruningComplete { false }; + + void setIconURLForPageURLInSQLDatabase(const String&, const String&); + void setIconIDForPageURLInSQLDatabase(int64_t, const String&); + void removePageURLFromSQLDatabase(const String& pageURL); + int64_t getIconIDForIconURLFromSQLDatabase(const String& iconURL); + int64_t addIconURLToSQLDatabase(const String&); + RefPtr getImageDataForIconURLFromSQLDatabase(const String& iconURL); + void removeIconFromSQLDatabase(const String& iconURL); + void writeIconSnapshotToSQLDatabase(const IconSnapshot&); + + void performPendingRetainAndReleaseOperations(); + + // Methods to dispatch client callbacks on the main thread + void dispatchDidImportIconURLForPageURLOnMainThread(const String&); + void dispatchDidImportIconDataForPageURLOnMainThread(const String&); + void dispatchDidFinishURLImportOnMainThread(); + + // The client is set by the main thread before the thread starts, and from then on is only used by the sync thread + std::unique_ptr m_client; + + WebCore::SQLiteDatabase m_syncDB; + + std::unique_ptr m_setIconIDForPageURLStatement; + std::unique_ptr m_removePageURLStatement; + std::unique_ptr m_getIconIDForIconURLStatement; + std::unique_ptr m_getImageDataForIconURLStatement; + std::unique_ptr m_addIconToIconInfoStatement; + std::unique_ptr m_addIconToIconDataStatement; + std::unique_ptr m_getImageDataStatement; + std::unique_ptr m_deletePageURLsForIconURLStatement; + std::unique_ptr m_deleteIconFromIconInfoStatement; + std::unique_ptr m_deleteIconFromIconDataStatement; + std::unique_ptr m_updateIconInfoStatement; + std::unique_ptr m_updateIconDataStatement; + std::unique_ptr m_setIconInfoStatement; + std::unique_ptr m_setIconDataStatement; + + MainThreadNotifier m_mainThreadNotifier; +}; + +IconDatabase& iconDatabase(); + +} // namespace WebKit diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/InspectorClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/InspectorClientHaiku.cpp new file mode 100644 index 000000000000..a723f86fca96 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/InspectorClientHaiku.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007 Ryan Leavengood + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InspectorClientHaiku.h" + +#include "NotImplemented.h" + + +namespace WebCore { + +void InspectorClientHaiku::inspectedPageDestroyed() +{ + delete this; +} + +Inspector::FrontendChannel* InspectorClientHaiku::openLocalFrontend(WebCore::InspectorController*) +{ + notImplemented(); + return NULL; +} + +void InspectorClientHaiku::bringFrontendToFront() +{ + notImplemented(); +} + +void InspectorClientHaiku::highlight() +{ + notImplemented(); +} + +void InspectorClientHaiku::hideHighlight() +{ + notImplemented(); +} + +} // namespace WebCore + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/InspectorClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/InspectorClientHaiku.h new file mode 100644 index 000000000000..a8b118c58dee --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/InspectorClientHaiku.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007 Ryan Leavengood + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef InspectorClientHaiku_h +#define InspectorClientHaiku_h + +#include "InspectorClient.h" + +namespace WebCore { + class Node; + class Page; + + class InspectorClientHaiku : public InspectorClient { + public: + virtual void inspectedPageDestroyed() override; + + virtual Inspector::FrontendChannel* openLocalFrontend(WebCore::InspectorController*) override; + virtual void bringFrontendToFront() override; + + virtual void highlight() override; + virtual void hideHighlight() override; + }; +} // namespace WebCore + +#endif // InspectorClientHaiku_h + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/NotificationClientHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/NotificationClientHaiku.cpp new file mode 100644 index 000000000000..6a0a66dd97e3 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/NotificationClientHaiku.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2017, Adrien Destugues, pulkomandy@pulkomandy.tk + * Distributed under terms of the MIT license. + */ + + +#include "NotificationClientHaiku.h" + +#include "WebPage.h" + +namespace WebCore { + +class NotificationClientHaiku::SynchronousListener + : public BUrlSynchronousRequest +{ + public: + SynchronousListener(BUrlRequest& request) + : BUrlSynchronousRequest(request) + {} + virtual ~SynchronousListener() {}; + void DataReceived(BUrlRequest*, const char* data, off_t position, + ssize_t size) override { + result.WriteAt(position, data, size); + } + + const BUrlResult& Result() const override + { return fWrappedRequest.Result(); } + status_t _ProtocolLoop() override + { return B_ERROR; } + + BMallocIO result; +}; + + +BNotification +NotificationClientHaiku::fromDescriptor(Notification* descriptor) +{ + BNotification notification(B_INFORMATION_NOTIFICATION); + notification.SetGroup("WebPositive"); + // Unfortunately, we don't get a website name or so… + if (descriptor->body().length() > 0) { + notification.SetTitle(descriptor->title()); + notification.SetContent(descriptor->body()); + } else { + notification.SetContent(descriptor->title()); + } + + // TODO we should cache the data, in case the notification is re-sent + // with some changes for an update. + BUrl iconURL(descriptor->icon()); + BUrlRequest* request = BUrlProtocolRoster::MakeRequest(iconURL); + if (request) { + SynchronousListener synchronous(*request); + synchronous.Perform(); + synchronous.WaitUntilCompletion(); + + BBitmap* bitmap = BTranslationUtils::GetBitmap(&synchronous.result); + if (bitmap) { + notification.SetIcon(bitmap); + delete bitmap; + } + + delete request; + } + + notification.SetMessageID(descriptor->tag()); + + return notification; +} + +}; diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/NotificationClientHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/NotificationClientHaiku.h new file mode 100644 index 000000000000..b986fd17e8a1 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/NotificationClientHaiku.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NotificationClientHaiku_h +#define NotificationClientHaiku_h + +#include "NotificationClient.h" +#include "Notification.h" +#include "NotificationPermissionCallback.h" +#include +#include + +#include +#include +#include +#include + +class BWebPage; + +namespace WebCore { + +class NotificationClientHaiku: public NotificationClient { +public: + NotificationClientHaiku(BWebPage*) {} + + bool show(Notification* descriptor) override { + + // FIXME should call dispatch{Click/Close/Error/Show}Event + fromDescriptor(descriptor).Send(); + return true; + } + + void cancel(Notification* descriptor) override { + fromDescriptor(descriptor).Send(0); // 0 timeout = destroy now + } + + void notificationObjectDestroyed(Notification*) override {} + void notificationControllerDestroyed() override {} + + void requestPermission(ScriptExecutionContext*, + RefPtr&& callback) override { + if (callback) + callback->handleEvent(NotificationPermission::Granted); + } + void cancelRequestsForPermission(ScriptExecutionContext*) override {} + bool hasPendingPermissionRequests(WebCore::ScriptExecutionContext*) const override { return false; } + + Permission checkPermission(ScriptExecutionContext*) override { + return NotificationPermission::Granted; + } + +private: + class SynchronousListener; + + BNotification fromDescriptor(Notification* descriptor); +}; + +} + +#endif diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/PlatformStrategiesHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/PlatformStrategiesHaiku.cpp new file mode 100644 index 000000000000..be31d384dc01 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/PlatformStrategiesHaiku.cpp @@ -0,0 +1,84 @@ +/* + Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + Copyright (C) 2008 Trolltech ASA + Copyright (C) 2008 Collabora Ltd. All rights reserved. + Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2011 Samsung Electronics + Copyright (C) 2012 Intel Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "PlatformStrategiesHaiku.h" + +#include "BlobRegistryImpl.h" +#include "NetworkStorageSession.h" +#include "wtf/NeverDestroyed.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PageGroup.h" +#include "WebResourceLoadScheduler.h" + + +using namespace WebCore; + + +void PlatformStrategiesHaiku::initialize() +{ + static NeverDestroyed platformStrategies; + setPlatformStrategies(&platformStrategies.get()); +} + +PlatformStrategiesHaiku::PlatformStrategiesHaiku() +{ +} + +LoaderStrategy* PlatformStrategiesHaiku::createLoaderStrategy() +{ + return new WebResourceLoadScheduler(); +} + +PasteboardStrategy* PlatformStrategiesHaiku::createPasteboardStrategy() +{ + notImplemented(); + return 0; +} + +WebCore::BlobRegistry* PlatformStrategiesHaiku::createBlobRegistry() +{ + return new BlobRegistryImpl(); +} + + +bool PlatformStrategiesHaiku::cookiesEnabled(const NetworkStorageSession& session) +{ + return session.cookiesEnabled(); +} + + +bool PlatformStrategiesHaiku::getRawCookies(const NetworkStorageSession& session, const URL& firstParty, const WebCore::SameSiteInfo& sameSite, const URL& url, + WTF::Optional frameID, WTF::Optional pageID, + Vector& rawCookies) +{ + return session.getRawCookies(firstParty, sameSite, url, frameID, pageID, rawCookies); +} + +void PlatformStrategiesHaiku::deleteCookie(const NetworkStorageSession& session, const URL& url, const String& cookieName) +{ + session.deleteCookie(url, cookieName); +} diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/PlatformStrategiesHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/PlatformStrategiesHaiku.h new file mode 100644 index 000000000000..992069316fb6 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/PlatformStrategiesHaiku.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2012 Intel Corporation + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PlatformStrategiesHaiku_h +#define PlatformStrategiesHaiku_h + +#include "LoaderStrategy.h" +#include "NetworkStorageSession.h" +#include "PasteboardStrategy.h" +#include "PlatformStrategies.h" + +#include + +#include "WebCore/PageIdentifier.h" + +class PlatformStrategiesHaiku : public WebCore::PlatformStrategies { +public: + static void initialize(); + +private: + PlatformStrategiesHaiku(); + + friend class NeverDestroyed; + + // WebCore::PlatformStrategies + WebCore::LoaderStrategy* createLoaderStrategy() override; + WebCore::PasteboardStrategy* createPasteboardStrategy() override; + WebCore::BlobRegistry* createBlobRegistry() override; + + // WebCore::CookiesStrategy + virtual bool cookiesEnabled(const WebCore::NetworkStorageSession&); + virtual bool getRawCookies(const WebCore::NetworkStorageSession&, + const WTF::URL& firstParty, const WebCore::SameSiteInfo&, const WTF::URL&, + WTF::Optional frameID, WTF::Optional pageID, + Vector&); + virtual void deleteCookie(const WebCore::NetworkStorageSession&, const WTF::URL&, const String&); +}; + +#endif // PlatformStrategiesHaiku_h diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ProgressTrackerHaiku.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/ProgressTrackerHaiku.cpp new file mode 100644 index 000000000000..9e0471cdb24c --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ProgressTrackerHaiku.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ProgressTrackerHaiku.h" + +#include "BackForwardController.h" +#include "Document.h" +#include "Frame.h" +#include "FrameLoader.h" +#include "NotImplemented.h" +#include "Page.h" +#include "ProgressTracker.h" +#include "WebPage.h" +#include "WebViewConstants.h" + + +namespace WebCore { + +ProgressTrackerClientHaiku::ProgressTrackerClientHaiku(BWebPage* view) + : m_view(view) +{ + ASSERT(m_view); +} + +void ProgressTrackerClientHaiku::progressTrackerDestroyed() +{ + delete this; +} + +void ProgressTrackerClientHaiku::progressStarted(Frame& originatingProgressFrame) +{ + BMessage message(LOAD_STARTED); + message.AddString("url", originatingProgressFrame.document()->url().string()); + dispatchMessage(message); + + progressEstimateChanged(originatingProgressFrame); + + // Enable the stop button, enable "Back" as needed + triggerNavigationHistoryUpdate(originatingProgressFrame); +} + +void ProgressTrackerClientHaiku::progressEstimateChanged(Frame& originatingProgressFrame) +{ + m_view->setLoadingProgress(originatingProgressFrame.page()->progress().estimatedProgress() * 100); +} + +void ProgressTrackerClientHaiku::progressFinished(Frame& frame) +{ + BMessage message(LOAD_DL_COMPLETED); + message.AddString("url", frame.document()->url().string()); + dispatchMessage(message); + + // Disable the stop button, enable "Back" as needed + triggerNavigationHistoryUpdate(frame); +} + +void ProgressTrackerClientHaiku::triggerNavigationHistoryUpdate(Frame& frame) const +{ + WebCore::Page* page = frame.page(); + WebCore::FrameLoader& loader = frame.loader(); + if (!page) + return; + BMessage message(UPDATE_NAVIGATION_INTERFACE); + message.AddBool("can go backward", page->backForward().canGoBackOrForward(-1)); + message.AddBool("can go forward", page->backForward().canGoBackOrForward(1)); + message.AddBool("can stop", loader.isLoading()); + dispatchMessage(message); +} + +status_t ProgressTrackerClientHaiku::dispatchMessage(BMessage& message) const +{ + message.AddPointer("view", m_view->WebView()); + message.AddPointer("frame", m_view->MainFrame()); + // FIXME do we get messages from subframes as well? If so, we need to + // find the BWebFrame matching the Frame we get in notifications. + + return m_messenger.SendMessage(&message); +} + +} // namespace WebCore diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/ProgressTrackerHaiku.h b/Source/WebKitLegacy/haiku/WebCoreSupport/ProgressTrackerHaiku.h new file mode 100644 index 000000000000..836191eaf8b2 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/ProgressTrackerHaiku.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * Copyright (C) 2014 Haiku, Inc. All righrs reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ProgressTrackerClientHaiku_h +#define ProgressTrackerClientHaiku_h + +#include "ProgressTrackerClient.h" + +#include + +class BWebPage; + +namespace WebCore { + +class ProgressTrackerClientHaiku final : public WebCore::ProgressTrackerClient { +public: + explicit ProgressTrackerClientHaiku(BWebPage*); + + void setDispatchTarget(const BMessenger& messenger) { m_messenger = messenger; } + +private: + // ProgressTrackerClient API + void progressTrackerDestroyed() override; + void progressStarted(WebCore::Frame& originatingProgressFrame) override; + void progressEstimateChanged(WebCore::Frame& originatingProgressFrame) override; + void progressFinished(WebCore::Frame& originatingProgressFrame) override; + + void triggerNavigationHistoryUpdate(WebCore::Frame&) const; + status_t dispatchMessage(BMessage& message) const; + + BWebPage* m_view; + BMessenger m_messenger; +}; + +} // namespace WebCore + +#endif // ProgressTrackerClientHaiku_h diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebApplicationCache.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/WebApplicationCache.cpp new file mode 100644 index 000000000000..c09e31b1d49d --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebApplicationCache.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WebApplicationCache.h" + +#include +#include +#include +#include "SecurityOrigin.h" + +#include +#include + +// WebApplicationCache --------------------------------------------------------------------------- + +WebApplicationCache::WebApplicationCache() + : m_refCount(0) +{ +} + +WebApplicationCache::~WebApplicationCache() +{ +} + +WebApplicationCache* WebApplicationCache::createInstance() +{ + WebApplicationCache* instance = new WebApplicationCache(); + return instance; +} + +static String applicationCachePath() +{ + BPath path; + find_directory(B_USER_CACHE_DIRECTORY, &path); + path.Append("webkit"); + + return path.Path(); +} + +WebCore::ApplicationCacheStorage& WebApplicationCache::storage() +{ + static WebCore::ApplicationCacheStorage& storage + = WebCore::ApplicationCacheStorage::create(applicationCachePath(), + "ApplicationCache").leakRef(); + + return storage; +} + diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebApplicationCache.h b/Source/WebKitLegacy/haiku/WebCoreSupport/WebApplicationCache.h new file mode 100644 index 000000000000..6eebc0baf646 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebApplicationCache.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebApplicationCache_h +#define WebApplicationCache_h + +#include + +namespace WebCore { +class ApplicationCacheStorage; +} + +class WebApplicationCache { +public: + static WebApplicationCache* createInstance(); + + static WebCore::ApplicationCacheStorage& storage(); + +protected: + WebApplicationCache(); + ~WebApplicationCache(); + +protected: + uint32_t m_refCount; +}; + +#endif diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebDatabaseProvider.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/WebDatabaseProvider.cpp new file mode 100644 index 000000000000..5d55c1b2c7a5 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebDatabaseProvider.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WebDatabaseProvider.h" + +#include +#include + + +#if ENABLE(INDEXED_DATABASE) +String WebDatabaseProvider::indexedDatabaseDirectoryPath() +{ + BPath storagePath; + find_directory(B_USER_SETTINGS_DIRECTORY, &storagePath); + storagePath.Append("WebKit/IndexedDB"); + + return storagePath.Path(); +} +#endif diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebDiagnosticLoggingClient.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/WebDiagnosticLoggingClient.cpp new file mode 100644 index 000000000000..1f8fcaed57c5 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebDiagnosticLoggingClient.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebDiagnosticLoggingClient.h" + +#include + +namespace WebKit { +using namespace WebCore; + +WebDiagnosticLoggingClient::WebDiagnosticLoggingClient() +{ +} + +WebDiagnosticLoggingClient::~WebDiagnosticLoggingClient() +{ +} + +void WebDiagnosticLoggingClient::logDiagnosticMessage(const String& message, const String& description, WebCore::ShouldSample shouldSample) +{ + if (!shouldLogAfterSampling(shouldSample)) + return; + + fprintf(stderr, "%s: %s\n", message.utf8().data(), description.utf8().data()); +} + +void WebDiagnosticLoggingClient::logDiagnosticMessageWithResult(const String& message, const String& description, WebCore::DiagnosticLoggingResultType result, WebCore::ShouldSample shouldSample) +{ + if (!shouldLogAfterSampling(shouldSample)) + return; + + fprintf(stderr, "%s: %s\n", message.utf8().data(), description.utf8().data()); +} + +void WebDiagnosticLoggingClient::logDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample shouldSample) +{ + if (!shouldLogAfterSampling(shouldSample)) + return; + + fprintf(stderr, "%s: %s (%f)\n", message.utf8().data(), description.utf8().data(), value); +} + +void WebDiagnosticLoggingClient::logDiagnosticMessageWithEnhancedPrivacy(const String& message, const String& description, WebCore::ShouldSample shouldSample) +{ + if (!shouldLogAfterSampling(shouldSample)) + return; + + fprintf(stderr, "%s: %s\n", message.utf8().data(), description.utf8().data()); +} + +void WebDiagnosticLoggingClient::logDiagnosticMessageWithValueDictionary( + const String& message, const String& description, const ValueDictionary&, + WebCore::ShouldSample shouldSample) +{ + if (!shouldLogAfterSampling(shouldSample)) + return; + + fprintf(stderr, "%s: %s\n", message.utf8().data(), description.utf8().data()); +} + +} // namespace WebKit diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebDiagnosticLoggingClient.h b/Source/WebKitLegacy/haiku/WebCoreSupport/WebDiagnosticLoggingClient.h new file mode 100644 index 000000000000..43c4d6dd8806 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebDiagnosticLoggingClient.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebDiagnosticLoggingClient_h +#define WebDiagnosticLoggingClient_h + +#include "DiagnosticLoggingClient.h" +#include + +namespace WebKit { + +class WebPage; + +class WebDiagnosticLoggingClient : public WebCore::DiagnosticLoggingClient { +public: + WebDiagnosticLoggingClient(); + virtual ~WebDiagnosticLoggingClient(); + +private: + void logDiagnosticMessage(const String& message, const String& description, WebCore::ShouldSample) override; + void logDiagnosticMessageWithResult(const String& message, const String& description, WebCore::DiagnosticLoggingResultType, WebCore::ShouldSample) override; + void logDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample) override; + void logDiagnosticMessageWithEnhancedPrivacy(const String& message, const String& description, WebCore::ShouldSample) override; + void logDiagnosticMessageWithValueDictionary(const String& message, const String& description, const ValueDictionary&, WebCore::ShouldSample) override; +}; + +} + +#endif diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebNavigatorContentUtilsClient.h b/Source/WebKitLegacy/haiku/WebCoreSupport/WebNavigatorContentUtilsClient.h new file mode 100644 index 000000000000..09bd8a3f0a86 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebNavigatorContentUtilsClient.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebNavigatorContentUtilsClient_h +#define WebNavigatorContentUtilsClient_h + +#if ENABLE(NAVIGATOR_CONTENT_UTILS) + +#include +#include +#include "wtf/URL.h" + +using namespace WebCore; + +namespace WebKit { + +class WebNavigatorContentUtilsClient : public WebCore::NavigatorContentUtilsClient { +public: + virtual ~WebNavigatorContentUtilsClient() { } + +private: + virtual void registerProtocolHandler(const String&, const URL&, const URL&, const String&) override { } + +#if ENABLE(CUSTOM_SCHEME_HANDLER) + virtual CustomHandlersState isProtocolHandlerRegistered(const String&, const URL&, const URL&) { return CustomHandlersDeclined; } + virtual void unregisterProtocolHandler(const String&, const URL&, const URL&) { } +#endif +}; + +} + +#endif // ENABLE(NAVIGATOR_CONTENT_UTILS) +#endif // WebNavigatorContentUtilsClient_h diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebVisitedLinkStore.cpp b/Source/WebKitLegacy/haiku/WebCoreSupport/WebVisitedLinkStore.cpp new file mode 100644 index 000000000000..c3471f1a07ac --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebVisitedLinkStore.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebVisitedLinkStore.h" + +#include "NotImplemented.h" +#include "WebView.h" +#include +#include + +using namespace WebCore; + +static bool s_shouldTrackVisitedLinks; + +static HashSet& visitedLinkStores() +{ + static NeverDestroyed> visitedLinkStores; + + return visitedLinkStores; +} + +Ref WebVisitedLinkStore::create() +{ + return adoptRef(*new WebVisitedLinkStore); +} + +WebVisitedLinkStore::WebVisitedLinkStore() + : m_visitedLinksPopulated(false) +{ + visitedLinkStores().add(this); +} + +WebVisitedLinkStore::~WebVisitedLinkStore() +{ + visitedLinkStores().remove(this); +} + +void WebVisitedLinkStore::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks) +{ + if (s_shouldTrackVisitedLinks == shouldTrackVisitedLinks) + return; + + s_shouldTrackVisitedLinks = shouldTrackVisitedLinks; + if (!s_shouldTrackVisitedLinks) + removeAllVisitedLinks(); +} + +void WebVisitedLinkStore::removeAllVisitedLinks() +{ + for (auto& visitedLinkStore : visitedLinkStores()) + visitedLinkStore->removeVisitedLinkHashes(); +} + +void WebVisitedLinkStore::addVisitedLink(const String& urlString) +{ + addVisitedLinkHash(computeSharedStringHash(urlString)); +} + +bool WebVisitedLinkStore::isLinkVisited(Page& page, SharedStringHash linkHash, const URL& baseURL, const AtomicString& attributeURL) +{ + populateVisitedLinksIfNeeded(page); + + return m_visitedLinkHashes.contains(linkHash); +} + +void WebVisitedLinkStore::addVisitedLink(Page&, SharedStringHash linkHash) +{ + if (!s_shouldTrackVisitedLinks) + return; + + addVisitedLinkHash(linkHash); +} + +void WebVisitedLinkStore::populateVisitedLinksIfNeeded(Page& sourcePage) +{ + if (m_visitedLinksPopulated) + return; + + m_visitedLinksPopulated = true; + + notImplemented(); +#if 0 + WebView* webView = kit(&sourcePage); + if (!webView) + return; + + COMPtr historyDelegate; + webView->historyDelegate(&historyDelegate); + if (historyDelegate) { + historyDelegate->populateVisitedLinksForWebView(webView); + return; + } + + WebHistory* history = WebHistory::sharedHistory(); + if (!history) + return; + history->addVisitedLinksToVisitedLinkStore(*this); +#endif +} + +void WebVisitedLinkStore::addVisitedLinkHash(SharedStringHash linkHash) +{ + ASSERT(s_shouldTrackVisitedLinks); + m_visitedLinkHashes.add(linkHash); + + invalidateStylesForLink(linkHash); +} + +void WebVisitedLinkStore::removeVisitedLinkHashes() +{ + m_visitedLinksPopulated = false; + if (m_visitedLinkHashes.isEmpty()) + return; + m_visitedLinkHashes.clear(); + + invalidateStylesForAllLinks(); +} diff --git a/Source/WebKitLegacy/haiku/WebCoreSupport/WebVisitedLinkStore.h b/Source/WebKitLegacy/haiku/WebCoreSupport/WebVisitedLinkStore.h new file mode 100644 index 000000000000..d36f2da0af37 --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebCoreSupport/WebVisitedLinkStore.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebVisitedLinkStore_h +#define WebVisitedLinkStore_h + +#include +#include + +class WebVisitedLinkStore final : public WebCore::VisitedLinkStore { +public: + static Ref create(); + virtual ~WebVisitedLinkStore(); + + static void setShouldTrackVisitedLinks(bool); + static void removeAllVisitedLinks(); + + void addVisitedLink(const String& urlString); + +private: + WebVisitedLinkStore(); + + virtual bool isLinkVisited(WebCore::Page&, WebCore::SharedStringHash, const WTF::URL& baseURL, const AtomicString& attributeURL) override; + virtual void addVisitedLink(WebCore::Page&, WebCore::SharedStringHash) override; + + void populateVisitedLinksIfNeeded(WebCore::Page&); + void addVisitedLinkHash(WebCore::SharedStringHash); + void removeVisitedLinkHashes(); + + HashSet m_visitedLinkHashes; + bool m_visitedLinksPopulated; +}; + +#endif // WebVisitedLinkStore_h diff --git a/Source/WebKitLegacy/haiku/WebKitPrefix.h b/Source/WebKitLegacy/haiku/WebKitPrefix.h new file mode 100644 index 000000000000..a3bd87e1218b --- /dev/null +++ b/Source/WebKitLegacy/haiku/WebKitPrefix.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 Haiku, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "PlatformExportMacros.h" diff --git a/Source/WebKitLegacy/scripts/generate-webkitversion.pl b/Source/WebKitLegacy/scripts/generate-webkitversion.pl index 133aa0fca6a4..f7355232f0d9 100644 --- a/Source/WebKitLegacy/scripts/generate-webkitversion.pl +++ b/Source/WebKitLegacy/scripts/generate-webkitversion.pl @@ -44,6 +44,7 @@ my $major_version = ""; my $minor_version = ""; +my $tiny_version = ""; # The appropriate Apple-maintained Version.xcconfig file for WebKit version information is in WebKit/mac/Configurations/. my $configFile = "./Source/WebKit/mac/Configurations/Version.xcconfig"; my $outputDir = ""; @@ -68,10 +69,15 @@ $line =~ s/^(MINOR_VERSION)\s+(=)\s+(\d+);/$3/; $minor_version = $line; } + if ($line =~ /^TINY_VERSION\s+=\s+\d+;/) { + $line =~ s/^(TINY_VERSION)\s+(=)\s+(\d+);/$3/; + $tiny_version = $line; + } } $major_version = "531" unless (length($major_version)); $minor_version = "3" unless (length($minor_version)); +$tiny_version = "0" unless (length($tiny_version)); my $webKitVersionPath = "$outputDir/WebKitVersion.h"; @@ -125,6 +131,7 @@ sub printWebKitVersionHeaderFile print F "#define WEBKIT_MAJOR_VERSION $major_version\n"; print F "#define WEBKIT_MINOR_VERSION $minor_version\n\n"; + print F "#define WEBKIT_TINY_VERSION $tiny_version\n\n"; print F "#endif //WebKitVersion_h\n"; diff --git a/Source/WebKitLegacy/win/WebView.cpp b/Source/WebKitLegacy/win/WebView.cpp index a89acc000d5e..235667979ea6 100644 --- a/Source/WebKitLegacy/win/WebView.cpp +++ b/Source/WebKitLegacy/win/WebView.cpp @@ -9,6 +9,7 @@ * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright + crypto/WebKitSubtleCrypto.cpp * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * diff --git a/Source/bmalloc/bmalloc/BPlatform.h b/Source/bmalloc/bmalloc/BPlatform.h index f7a4af43d3eb..f1865565230d 100644 --- a/Source/bmalloc/bmalloc/BPlatform.h +++ b/Source/bmalloc/bmalloc/BPlatform.h @@ -40,6 +40,11 @@ #define BOS_DARWIN 1 #endif +#ifdef __HAIKU__ +#define BOS_HAIKU 1 +#define BOS_UNIX 1 +#endif + #ifdef __unix #define BOS_UNIX 1 #endif diff --git a/Source/bmalloc/bmalloc/VMAllocate.h b/Source/bmalloc/bmalloc/VMAllocate.h index e3976ca2d436..03d0bf5f3b98 100644 --- a/Source/bmalloc/bmalloc/VMAllocate.h +++ b/Source/bmalloc/bmalloc/VMAllocate.h @@ -201,6 +201,8 @@ inline void vmDeallocatePhysicalPages(void* p, size_t vmSize) vmValidatePhysical(p, vmSize); #if BOS(DARWIN) SYSCALL(madvise(p, vmSize, MADV_FREE_REUSABLE)); +#elif BOS(HAIKU) + SYSCALL(posix_madvise(p, vmSize, POSIX_MADV_DONTNEED)); #elif BOS(FREEBSD) SYSCALL(madvise(p, vmSize, MADV_FREE)); #else @@ -216,6 +218,8 @@ inline void vmAllocatePhysicalPages(void* p, size_t vmSize) vmValidatePhysical(p, vmSize); #if BOS(DARWIN) SYSCALL(madvise(p, vmSize, MADV_FREE_REUSE)); +#elif BOS(HAIKU) + SYSCALL(posix_madvise(p, vmSize, POSIX_MADV_NORMAL)); #else SYSCALL(madvise(p, vmSize, MADV_NORMAL)); #if BOS(LINUX) diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake index 6c48a43ceb85..65d2b7e26bd3 100644 --- a/Source/cmake/OptionsCommon.cmake +++ b/Source/cmake/OptionsCommon.cmake @@ -119,7 +119,13 @@ endif () # GTK and WPE use the GNU installation directories as defaults. if (NOT PORT STREQUAL "GTK" AND NOT PORT STREQUAL "WPE") - set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Absolute path to library installation directory") + IF(HAIKU) + set(LIB_SUFFIX "/${CMAKE_HAIKU_SECONDARY_ARCH}" CACHE STRING + "Define suffix of directory name (x86/x86_gcc2)") + ELSE() + set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)") + ENDIF() + set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "Absolute path to library installation directory") set(EXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Absolute path to executable installation directory") set(LIBEXEC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Absolute path to install executables executed by the library") endif () diff --git a/Source/cmake/OptionsHaiku.cmake b/Source/cmake/OptionsHaiku.cmake new file mode 100644 index 000000000000..1bbdea7b0c0d --- /dev/null +++ b/Source/cmake/OptionsHaiku.cmake @@ -0,0 +1,295 @@ +include(GNUInstallDirs) +include(VersioningUtils) + +SET(PROJECT_VERSION_MAJOR 1) +SET(PROJECT_VERSION_MINOR 6) +SET(PROJECT_VERSION_PATCH 9) +SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}) + +add_definitions(-DHAIKU_WEBKIT_VERSION=\"${PROJECT_VERSION}\") +add_definitions(-DBUILDING_HAIKU__=1) + +CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 25 4 7) + +# Force libstdc++ to export std::isinf and friends. This should be fixed on +# Haiku side ultimately. +add_definitions(-D_GLIBCXX_USE_C99_MATH) + +set(ENABLE_WEBKIT ON) +set(ENABLE_WEBKIT_LEGACY ON) + +set(USE_ANGLE_EGL ON) + +if ("${CMAKE_BUILD_TYPE}" STREQUAL "debug" AND NOT SHARED_CORE) + message(FATAL_ERROR "Turn on the SHARED_CORE flag to make a debug build - e.g.\n build-webkit --haiku --debug --cmakeargs=\"-DSHARED_CORE=ON\".\n") +endif () + +# To get assertions in release mode, we replace all -DNDEBUG with -UNDEBUG +# (they are automatically added by CMake and there is no "release with asserts" +# build available in WebKit) +#foreach(flag_var +# CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE +# CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) +# if(${flag_var} MATCHES "-DNDEBUG") +# string(REGEX REPLACE "-DNDEBUG" "-UNDEBUG" ${flag_var} "${${flag_var}}") +# endif(${flag_var} MATCHES "-DNDEBUG") +#endforeach(flag_var) +#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility-inlines-hidden") + +find_package(LibGcrypt 1.6.0 REQUIRED) +FIND_PACKAGE(Sqlite REQUIRED) +FIND_PACKAGE(LibXml2 2.8.0 REQUIRED) +FIND_PACKAGE(LibXslt 1.1.7 REQUIRED) +find_package(ICU REQUIRED COMPONENTS data i18n uc) +find_package(Threads REQUIRED) +FIND_PACKAGE(JPEG REQUIRED) +FIND_PACKAGE(PNG REQUIRED) +FIND_PACKAGE(WebP REQUIRED) +FIND_PACKAGE(ZLIB REQUIRED) + +set(USE_ICU_UNICODE 1) + +set(DATA_INSTALL_DIR "data/WebKit" CACHE PATH "Installation path for data") +set(HEADER_INSTALL_DIR "develop/headers${CMAKE_HAIKU_SECONDARY_ARCH_SUBDIR}" CACHE PATH "Installation path for header files") +set(THEME_BINARY_DIR ${CMAKE_BINARY_DIR}/WebCore/platform/efl/DefaultTheme) +set(WEB_INSPECTOR_DIR "${DATA_INSTALL_DIR}/inspector") +set(WEBINSPECTORUI_DIR "${CMAKE_SOURCE_DIR}/Source/WebInspectorUI") + +add_definitions(-DDATA_DIR="${CMAKE_INSTALL_PREFIX}/${DATA_INSTALL_DIR}") + +WEBKIT_OPTION_BEGIN() +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_3D_TRANSFORMS PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ATTACHMENT_ELEMENT PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS3_TEXT PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_DEVICE_ADAPTATION PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_SCROLL_SNAP PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CSS_SELECTORS_LEVEL4 PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CUSTOM_SCHEME_HANDLER PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DATALIST_ELEMENT PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ENCRYPTED_MEDIA PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FILTERS_LEVEL_2 PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FULLSCREEN_API PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GEOLOCATION PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INDEXED_DATABASE_IN_WORKERS PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INDEXED_DATABASE PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_COLOR PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATE PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_MONTH PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CAPTURE PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CONTROLS_SCRIPT PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SOURCE PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEMORY_SAMPLER PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MOUSE_CURSOR_SCALE PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NOTIFICATIONS PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_RESOLUTION_MEDIA_QUERY PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SAMPLING_PROFILER PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPELLCHECK PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_SLIDER PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USERSELECT_ALL PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO_TRACK PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_AUDIO PUBLIC OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CRYPTO PUBLIC ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_XSLT PUBLIC ON) + +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER PRIVATE OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PUBLIC_SUFFIX_LIST PRIVATE OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_REMOTE_INSPECTOR PRIVATE OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SMOOTH_SCROLLING PRIVATE OFF) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL PRIVATE OFF) + +WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_SYSTEM_MALLOC PRIVATE ON) + +if (ENABLE_LLINT_C_LOOP) + message(STATUS "Force enabling LLINT C LOOP.") + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_JIT OFF) + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DFG_JIT OFF) + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTL_JIT OFF) +endif () + +WEBKIT_OPTION_END() + +if (ENABLE_WEBKIT AND ENABLE_NETSCAPE_PLUGIN_API) + set(ENABLE_PLUGIN_PROCESS 1) +endif () + +IF (ENABLE_WEB_AUDIO) + SET(USE_FFMPEG 1) + ADD_DEFINITIONS(-DUSE_FFMPEG=1) + ADD_DEFINITIONS(-DUSE_WEBAUDIO_FFMPEG=1) +ENDIF () + +set(USE_3D_GRAPHICS 0) +add_definitions(-DUSE_3D_GRAPHICS=0) + +if (ENABLE_WEBGL) + find_package(OpenGL REQUIRED) + option(ENABLE_EGL ON) + + if (ENABLE_EGL) + find_package(EGL REQUIRED) + endif () + + if (EGL_FOUND) + set(USE_EGL 1) + add_definitions(-DUSE_EGL=1) + option(ENABLE_GLES2 ON) + + if (ENABLE_GLES2) + find_package(GLES REQUIRED) + endif () + + if (OPENGLES2_FOUND) + set(USE_OPENGL_ES_2 1) + add_definitions(-DUSE_OPENGL_ES_2=1) + endif () + endif () + + if (EGL_FOUND) + set(USE_GRAPHICS_SURFACE 1) + endif () +endif () + +if (ENABLE_INSPECTOR) + set(WEB_INSPECTOR_DIR "${DATA_INSTALL_DIR}/inspector") + add_definitions(-DWEB_INSPECTOR_DIR=\"${CMAKE_BINARY_DIR}/${WEB_INSPECTOR_DIR}\") + add_definitions(-DWEB_INSPECTOR_INSTALL_DIR=\"${CMAKE_INSTALL_PREFIX}/${WEB_INSPECTOR_DIR}\") +endif () + +# Packaging data +if(CMAKE_HAIKU_SECONDARY_ARCH) + # Building for secondary architecture, setup the suffix + set(PACKAGE_SUFFIX _${CMAKE_HAIKU_SECONDARY_ARCH}) +endif() + +SET(CPACK_SOURCE_GENERATOR TBZ2) +set(CPACK_GENERATOR HPKG) + +# Optimize binary size for release builds by removing dead sections +if (CMAKE_BUILD_TYPE STREQUAL release AND CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS "-ffunction-sections -fdata-sections ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-ffunction-sections -fdata-sections ${CMAKE_CXX_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--gc-sections ${CMAKE_SHARED_LINKER_FLAGS}") +endif () + +# Haiku actually make use of rtti in several places, so we can't really disable +# it, unlike on other platforms... +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -frtti") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -frtti") + +string(TOLOWER ${CMAKE_HOST_SYSTEM_PROCESSOR} LOWERCASE_CMAKE_HOST_SYSTEM_PROCESSOR) +if (CMAKE_COMPILER_IS_GNUCC AND "${LOWERCASE_CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "x86") + # i686 is the official requirement for Haiku, let's try to keep this working + # for everyone. + set(CMAKE_C_FLAGS "-march=i686 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-march=i686 ${CMAKE_CXX_FLAGS}") +endif() + +if (CMAKE_COMPILER_IS_GNUCC AND "${LOWERCASE_CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + # GCC port issue? This is not needed for other platforms. + set(CMAKE_EXE_LINKER_FLAGS "-pie ${CMAKE_EXE_LINKER_FLAGS}") +endif() + +SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER TRUE) +SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS FALSE) +SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER_GL TRUE) +SET_AND_EXPOSE_TO_BUILD(ENABLE_GRAPHICS_CONTEXT_3D TRUE) +find_package(OpenGL) +SET_AND_EXPOSE_TO_BUILD(ENABLE_OPENGL TRUE) + +if (ENABLE_WEB_CRYPTO) + find_package(Libtasn1 REQUIRED) + if (NOT LIBTASN1_FOUND) + message(FATAL_ERROR "libtasn1 is required to enable Web Crypto API support.") + endif () + if (LIBGCRYPT_VERSION VERSION_LESS 1.7.0) + message(FATAL_ERROR "libgcrypt 1.7.0 is required to enable Web Crypto API support.") + endif () + SET_AND_EXPOSE_TO_BUILD(USE_GCRYPT TRUE) +endif () + +if (ENABLE_WEBGL) + set(ENABLE_WEBGL 1) + if (USE_GRAPHICS_SURFACE) + add_definitions(-DUSE_GRAPHICS_SURFACE=1) + endif () +endif () + +#SET_AND_EXPOSE_TO_BUILD(ENABLE_GRAPHICS_CONTEXT_3D FALSE) + +if (ENABLE_SPELLCHECK) + find_package(Enchant REQUIRED) +endif () + +if (ENABLE_ACCESSIBILITY) + find_package(ATK REQUIRED) +else () + add_definitions(-DHAVE_ACCESSIBILITY=0) +endif () + +if (ENABLE_INDEXED_DATABASE) + set(USE_LEVELDB 1) + add_definitions(-DUSE_LEVELDB=1) +endif () + +set(JavaScriptCore_LIBRARY_TYPE SHARED) +set(SHOULD_INSTALL_JS_SHELL ON) + +set(WEBKIT_CPACK_ALL_PORTS 1) # Until we can safely extract only the sources used by Haiku +set(WEBKIT_CPACK_ADD_TOOLS 1) # Mainly for generate_webkit_info.sh + +set(CPACK_PACKAGE_NAME "haikuwebkit${PACKAGE_SUFFIX}") +set(CPACK_PACKAGE_VENDOR "Haiku Project") +set(CPACK_HAIKU_PACKAGE_COPYRIGHT "1998-2013 Apple Inc., Google Inc., Haiku Inc., et al") +set(CPACK_HAIKU_PACKAGE_LICENSES "GNU LGPL v2" "GNU LGPL v2.1" "MIT") + # TODO apple webkit (needs to be added inside package) +set(CPACK_HAIKU_PACKAGE_REVISION "1") + +set(CPACK_HAIKU_PACKAGE_PROVIDES + "lib:libWebKit${PACKAGE_SUFFIX} = ${PROJECT_VERSION}" +) +set(CPACK_HAIKU_PACKAGE_REQUIRES + "haiku${PACKAGE_SUFFIX} >= r1~alpha4_pm-1" + "icu${PACKAGE_SUFFIX} >= 4.8.1.1" + "lib:libjpeg${PACKAGE_SUFFIX} >= 9" + "lib:libpng${PACKAGE_SUFFIX} >= 15.12.0" + "lib:libsqlite3${PACKAGE_SUFFIX} >= 0.8.6" + "lib:libxml2${PACKAGE_SUFFIX} >= 2.8.0" + "lib:libxslt${PACKAGE_SUFFIX} >= 1.1.18" +) + +set(CPACK_HAIKU_devel_PACKAGE_PROVIDES + "devel:libWebKit${PACKAGE_SUFFIX} = ${PROJECT_VERSION}" +) +set(CPACK_HAIKU_devel_PACKAGE_REQUIRES + "haiku${PACKAGE_SUFFIX}_devel >= r1~alpha4_pm-1" + "icu${PACKAGE_SUFFIX}_devel >= 4.8.1.1" + "devel:libjpeg${PACKAGE_SUFFIX} >= 9" + "devel:libpng${PACKAGE_SUFFIX} >= 15.12.0" + "devel:libsqlite3${PACKAGE_SUFFIX} >= 0.8.6" + "devel:libxml2${PACKAGE_SUFFIX} >= 2.8.0" + "devel:libxslt${PACKAGE_SUFFIX} >= 1.1.18" +) + +include(CPackComponent) +cpack_add_component(devel) + +# These could be shared with other flavors of CPack, if they are used anywhere. +# Maybe move them to non-Haiku specific place. +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open source web browser engine") +set(CPACK_PACKAGE_DESCRIPTION "WebKit is an open source web browser engine. +WebKit is also the name of the Mac OS X system framework version of the engine +that's used by Safari, Dashboard, Mail, and many other OS X applications. +WebKit's HTML and JavaScript code began as a branch of the KHTML and KJS +libraries from KDE.") +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) diff --git a/Source/cmake/WebKitMacros.cmake b/Source/cmake/WebKitMacros.cmake index 9a09cb7c48d5..11d9e0429272 100644 --- a/Source/cmake/WebKitMacros.cmake +++ b/Source/cmake/WebKitMacros.cmake @@ -159,6 +159,9 @@ macro(_WEBKIT_TARGET _target_logical_name _target_cmake_name) target_include_directories(${_target_cmake_name} PUBLIC "$") target_include_directories(${_target_cmake_name} SYSTEM PRIVATE "$") target_include_directories(${_target_cmake_name} PRIVATE "$") + foreach(inc ${${_target}_LOCAL_INCLUDE_DIRECTORIES}) + add_definitions(-iquote ${inc}) + endforeach() target_compile_definitions(${_target_cmake_name} PRIVATE "BUILDING_${_target_logical_name}") if (${_target_logical_name}_DEFINITIONS) diff --git a/Tools/DumpRenderTree/CMakeLists.txt b/Tools/DumpRenderTree/CMakeLists.txt index f579f4ee0f24..aa663a618ed4 100644 --- a/Tools/DumpRenderTree/CMakeLists.txt +++ b/Tools/DumpRenderTree/CMakeLists.txt @@ -37,6 +37,17 @@ set(DumpRenderTree_INCLUDE_DIRECTORIES ${WEBCORE_DIR}/testing/js ) +set(DumpRenderTree_LOCAL_INCLUDE_DIRECTORIES + ${WEBCORE_DIR}/css + ${WEBCORE_DIR}/dom + ${WEBCORE_DIR}/platform + ${WEBCORE_DIR}/platform/graphics + ${WEBCORE_DIR}/platform/graphics/transforms + ${WEBCORE_DIR}/rendering/shapes + ${JAVASCRIPTCORE_DIR}/heap + ${JAVASCRIPTCORE_DIR}/parser +) + set(TestNetscapePlugIn_SOURCES TestNetscapePlugIn/PluginObject.cpp TestNetscapePlugIn/PluginTest.cpp @@ -86,7 +97,22 @@ GENERATE_BINDINGS(DumpRenderTreeBindings WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() -include_directories(${DumpRenderTree_INCLUDE_DIRECTORIES}) +IF (HAIKU) + foreach(inc ${DumpRenderTree_LOCAL_INCLUDE_DIRECTORIES}) + ADD_DEFINITIONS(-iquote ${inc}) + endforeach(inc) + + include_directories( + ${DumpRenderTree_INCLUDE_DIRECTORIES} + ) + +LIST(APPEND DumpRenderTree_LIBRARIES WebCore translation) +ELSE (HAIKU) + include_directories( + ${DumpRenderTree_INCLUDE_DIRECTORIES} + ${DumpRenderTree_LOCAL_INCLUDE_DIRECTORIES} + ) +ENDIF (HAIKU) add_executable(DumpRenderTree ${DumpRenderTree_SOURCES}) target_link_libraries(DumpRenderTree ${DumpRenderTree_LIBRARIES}) diff --git a/Tools/DumpRenderTree/DumpRenderTree.h b/Tools/DumpRenderTree/DumpRenderTree.h index c2169340910d..ddbcb43f575e 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.h +++ b/Tools/DumpRenderTree/DumpRenderTree.h @@ -34,6 +34,8 @@ #include "DumpRenderTreeWin.h" #elif PLATFORM(GTK) #include "DumpRenderTreeGtk.h" +#elif PLATFORM(HAIKU) +#include "DumpRenderTreeHaiku.h" #endif #include diff --git a/Tools/DumpRenderTree/JavaScriptThreading.cpp b/Tools/DumpRenderTree/JavaScriptThreading.cpp index 5f98929c31bc..e732939fa65d 100644 --- a/Tools/DumpRenderTree/JavaScriptThreading.cpp +++ b/Tools/DumpRenderTree/JavaScriptThreading.cpp @@ -32,7 +32,7 @@ #include "config.h" #include "JavaScriptThreading.h" -#include +#include #include #include #include diff --git a/Tools/DumpRenderTree/PixelDumpSupport.cpp b/Tools/DumpRenderTree/PixelDumpSupport.cpp index cd76bcec101c..fb77a7df25c0 100644 --- a/Tools/DumpRenderTree/PixelDumpSupport.cpp +++ b/Tools/DumpRenderTree/PixelDumpSupport.cpp @@ -41,6 +41,8 @@ #include "PixelDumpSupportCG.h" #elif USE(CAIRO) #include "PixelDumpSupportCairo.h" +#elif PLATFORM(HAIKU) +#include "PixelDumpSupportHaiku.h" #elif USE(DIRECT2D) #include "PixelDumpSupportDirect2D.h" #endif diff --git a/Tools/DumpRenderTree/PlatformHaiku.cmake b/Tools/DumpRenderTree/PlatformHaiku.cmake new file mode 100644 index 000000000000..317db45a780a --- /dev/null +++ b/Tools/DumpRenderTree/PlatformHaiku.cmake @@ -0,0 +1,47 @@ +list(APPEND DumpRenderTree_SOURCES + haiku/DumpRenderTree.cpp + haiku/EditingCallbacks.cpp + haiku/EventSender.cpp + haiku/GCControllerHaiku.cpp + haiku/JSStringUtils.cpp + haiku/PixelDumpSupportHaiku.cpp + haiku/TestRunnerHaiku.cpp + haiku/WorkQueueItemHaiku.cpp +) + +list(APPEND DumpRenderTree_LIBRARIES + WebKitLegacy + WebCore +) + +list(APPEND DumpRenderTree_INCLUDE_DIRECTORIES + ${WEBKITLEGACY_DIR}/haiku/API + ${WEBKITLEGACY_DIR}/haiku + ${WEBKITLEGACY_DIR}/haiku/WebCoreSupport + ${WEBCORE_DIR}/css/parser + ${WEBCORE_DIR}/platform/graphics/haiku + ${WEBCORE_DIR}/platform/network/haiku + ${WEBCORE_DIR}/platform/text + ${WEBCORE_DIR}/style + ${TOOLS_DIR}/DumpRenderTree/haiku +) + +list(APPEND DumpRenderTree_LOCAL_INCLUDE_DIRECTORIES + ${FORWARDING_HEADERS_DIR}/WebCore +) + +foreach(inc ${DumpRenderTree_LOCAL_INCLUDE_DIRECTORIES}) + ADD_DEFINITIONS(-iquote ${inc}) +endforeach(inc) + +if (ENABLE_ACCESSIBILITY) + list(APPEND DumpRenderTree_INCLUDE_DIRECTORIES + ${TOOLS_DIR}/DumpRenderTree/haiku + ) +endif () + +# FIXME: DOWNLOADED_FONTS_DIR should not hardcode the directory +# structure. See . +add_definitions(-DFONTS_CONF_DIR="${TOOLS_DIR}/DumpRenderTree/gtk/fonts" + -DDOWNLOADED_FONTS_DIR="${CMAKE_SOURCE_DIR}/WebKitBuild/Dependencies/Source/webkitgtk-test-fonts-0.0.3" +) diff --git a/Tools/DumpRenderTree/TestRunner.cpp b/Tools/DumpRenderTree/TestRunner.cpp index 90c64c3614cd..f34e9a008048 100644 --- a/Tools/DumpRenderTree/TestRunner.cpp +++ b/Tools/DumpRenderTree/TestRunner.cpp @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Tools/DumpRenderTree/config.h b/Tools/DumpRenderTree/config.h index 3f90846d70b9..6181fb2cb749 100644 --- a/Tools/DumpRenderTree/config.h +++ b/Tools/DumpRenderTree/config.h @@ -23,7 +23,7 @@ #endif #include -#include +#include #include #ifdef __cplusplus diff --git a/Tools/DumpRenderTree/haiku/DumpRenderTree.cpp b/Tools/DumpRenderTree/haiku/DumpRenderTree.cpp new file mode 100644 index 000000000000..818c68cd119a --- /dev/null +++ b/Tools/DumpRenderTree/haiku/DumpRenderTree.cpp @@ -0,0 +1,806 @@ +/* + * Copyright (C) 2009 Maxime Simon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DumpRenderTree.h" + + +#include "AccessibilityController.h" +#include "DumpRenderTreeClient.h" +#include "EditingCallbacks.h" +#include "EventSender.h" +#include "Frame.h" +#include +#include "NotImplemented.h" +#include "PixelDumpSupport.h" +#include "ScriptController.h" +#include "TestRunner.h" +#include "WebCoreTestSupport.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebSettings.h" +#include "WebView.h" +#include "WebViewConstants.h" +#include "WebWindow.h" +#include "WorkQueue.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +BWebView* webView; +BWebFrame* topLoadingFrame = 0; +bool waitForPolicy = false; +BMessageRunner* waitToDumpWatchdog = NULL; + +// From the top-level DumpRenderTree.h +RefPtr gTestRunner; +volatile bool done = true; +volatile bool first = true; + +static bool dumpPixelsForCurrentTest; +static int dumpPixelsForAllTests = false; +static bool dumpTree = true; +static bool printSeparators = true; +static int useTimeoutWatchdog = true; + +using namespace std; + +const unsigned maxViewHeight = 600; +const unsigned maxViewWidth = 800; + +static String dumpFramesAsText(BWebFrame* frame) +{ + if (!frame) + return String(); + + String result = frame->InnerText(); + + if (webView->WebPage()->MainFrame() != frame) { + result.append("\n--------\nFrame: '"); + result.append(frame->Name()); + result.append("'\n--------\n"); + } + + result.append("\n"); + + if (gTestRunner->dumpChildFramesAsText()) { + BList children = WebCore::DumpRenderTreeClient::frameChildren(frame); + + for(int i = 0; i < children.CountItems(); i++) + { + BWebFrame* currentFrame = static_cast(children.ItemAt(i)); + String tempText(dumpFramesAsText(currentFrame)); + + if (tempText.isEmpty()) + continue; + + result.append(tempText); + } + } + + return result; +} + +static void dumpFrameScrollPosition(BWebFrame* frame) +{ + BPoint pos = frame->ScrollPosition(); + if (abs(pos.x) > 0 || abs(pos.y) > 0) { + StringBuilder result; + +#if 0 + Evas_Object* parent = evas_object_smart_parent_get(frame); + + // smart parent of main frame is view object. + if (parent != browser->mainView()) { + result.append("frame '"); + result.append(ewk_frame_name_get(frame)); + result.append("' "); + } +#endif + + printf("scrolled to %.f,%.f\n", pos.x, pos.y); + } + + if (gTestRunner->dumpChildFrameScrollPositions()) { +#if 0 + Eina_List* children = DumpRenderTreeSupportEfl::frameChildren(frame); + void* iterator; + + EINA_LIST_FREE(children, iterator) { + Evas_Object* currentFrame = static_cast(iterator); + dumpFrameScrollPosition(currentFrame); + } +#endif + } +} + +static void adjustOutputTypeByMimeType(BWebFrame* frame) +{ + const String responseMimeType(WebCore::DumpRenderTreeClient::responseMimeType(frame)); + if (responseMimeType == "text/plain") { + gTestRunner->setDumpAsText(true); + gTestRunner->setGeneratePixelResults(false); + } +} + +static void dumpFrameContentsAsText(BWebFrame* frame) +{ + String result; + if (gTestRunner->dumpAsText()) + result = dumpFramesAsText(frame); + else + result = frame->ExternalRepresentation(); + + printf("%s", result.utf8().data()); +} + +static bool shouldDumpFrameScrollPosition() +{ + return !gTestRunner->dumpAsText() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive(); +} + +static bool shouldDumpPixelsAndCompareWithExpected() +{ + return dumpPixelsForCurrentTest && gTestRunner->generatePixelResults() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive(); +} + +void dump() +{ + BWebFrame* frame = webView->WebPage()->MainFrame(); + + if (dumpTree) { + adjustOutputTypeByMimeType(frame); + dumpFrameContentsAsText(frame); + + if (shouldDumpFrameScrollPosition()) + dumpFrameScrollPosition(frame); + + if (gTestRunner->dumpBackForwardList()) { + // FIXME: + // not implemented. + } + + if (printSeparators) { + puts("#EOF"); + fputs("#EOF\n", stderr); + fflush(stdout); + fflush(stderr); + } + } + + if(shouldDumpPixelsAndCompareWithExpected()) { + dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash()); + } + + // Notify the BApplication it's ok to move on to the next test. + be_app->PostMessage('dump'); +} + +static bool shouldLogFrameLoadDelegates(const String& pathOrURL) +{ + return pathOrURL.contains("loading/"); +} + +static bool shouldDumpAsText(const String& pathOrURL) +{ + return pathOrURL.contains("dumpAsText/"); +} + +static bool shouldOpenWebInspector(const String& pathOrURL) +{ + return pathOrURL.contains("inspector/"); +} + +static String getFinalTestURL(const String& testURL) +{ + if (!testURL.startsWith("http://") && !testURL.startsWith("https://")) { + char* cFilePath = realpath(testURL.utf8().data(), NULL); + const String filePath = String::fromUTF8(cFilePath); + free(cFilePath); + + if (BFile(filePath.utf8().data(), B_READ_ONLY).IsFile()) + return String("file://") + filePath; + } + + return testURL; +} + +static inline bool isGlobalHistoryTest(const String& cTestPathOrURL) +{ + return cTestPathOrURL.contains("/globalhistory/"); +} + +static void createTestRunner(const String& testURL, const String& expectedPixelHash) +{ + gTestRunner = + TestRunner::create(std::string(testURL.utf8().data()), + std::string(expectedPixelHash.utf8().data())); + + topLoadingFrame = 0; + done = false; + first = true; + + gTestRunner->setIconDatabaseEnabled(false); + + if (shouldLogFrameLoadDelegates(testURL)) + gTestRunner->setDumpFrameLoadCallbacks(true); + + gTestRunner->setDeveloperExtrasEnabled(true); + if (shouldOpenWebInspector(testURL)) + gTestRunner->showWebInspector(); + + gTestRunner->setDumpHistoryDelegateCallbacks(isGlobalHistoryTest(testURL)); + + if (shouldDumpAsText(testURL)) { + gTestRunner->setDumpAsText(true); + gTestRunner->setGeneratePixelResults(false); + } +} + +static void resetDefaultsToConsistentValues() +{ +#if 0 + ewk_settings_icon_database_clear(); + ewk_settings_icon_database_path_set(0); + + ewk_web_database_remove_all(); + ewk_settings_web_database_default_quota_set(5 * 1024 * 1024); + + ewk_settings_memory_cache_clear(); + ewk_settings_application_cache_clear(); + ewk_settings_shadow_dom_enable_set(EINA_TRUE); + + ewk_view_setting_private_browsing_set(mainView(), EINA_FALSE); + ewk_view_setting_spatial_navigation_set(mainView(), EINA_FALSE); + ewk_view_setting_enable_frame_flattening_set(mainView(), EINA_FALSE); + ewk_view_setting_application_cache_set(mainView(), EINA_TRUE); + ewk_view_setting_enable_scripts_set(mainView(), EINA_TRUE); + ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_STANDARD, "Times"); + ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_MONOSPACE, "Courier"); + ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_SERIF, "Times"); + ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_SANS_SERIF, "Helvetica"); + ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_CURSIVE, "cursive"); + ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_FANTASY, "fantasy"); +#endif + webView->WebPage()->Settings()->SetDefaultStandardFontSize(16); + webView->WebPage()->Settings()->SetDefaultFixedFontSize(13); +#if 0 + ewk_view_setting_font_minimum_size_set(mainView(), 0); + ewk_view_setting_caret_browsing_set(mainView(), EINA_FALSE); + ewk_view_setting_page_cache_set(mainView(), EINA_FALSE); + ewk_view_setting_enable_auto_resize_window_set(mainView(), EINA_TRUE); + ewk_view_setting_enable_plugins_set(mainView(), EINA_TRUE); + ewk_view_setting_scripts_can_open_windows_set(mainView(), EINA_TRUE); + ewk_view_setting_scripts_can_close_windows_set(mainView(), EINA_TRUE); + ewk_view_setting_auto_load_images_set(mainView(), EINA_TRUE); + ewk_view_setting_user_stylesheet_set(mainView(), 0); + ewk_view_setting_enable_xss_auditor_set(browser->mainView(), EINA_TRUE); + ewk_view_setting_enable_webgl_set(mainView(), EINA_TRUE); + ewk_view_setting_enable_hyperlink_auditing_set(mainView(), EINA_FALSE); + ewk_view_setting_include_links_in_focus_chain_set(mainView(), EINA_FALSE); + ewk_view_setting_scripts_can_access_clipboard_set(mainView(), EINA_TRUE); + ewk_view_setting_allow_universal_access_from_file_urls_set(mainView(), EINA_TRUE); + ewk_view_setting_allow_file_access_from_file_urls_set(mainView(), EINA_TRUE); + ewk_view_setting_resizable_textareas_set(mainView(), EINA_TRUE); + +#endif + // This resets both the "text" and "page" zooms. + webView->ResetZoomFactor(); +#if 0 + ewk_view_visibility_state_set(mainView(), EWK_PAGE_VISIBILITY_STATE_VISIBLE, true); + ewk_view_text_direction_set(mainView(), EWK_TEXT_DIRECTION_DEFAULT); + + ewk_history_clear(ewk_view_history_get(mainView())); + + ewk_frame_feed_focus_in(mainFrame()); + + ewk_cookies_clear(); + ewk_cookies_policy_set(EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY); + + ewk_security_policy_whitelist_origin_reset(); + +#if HAVE(ACCESSIBILITY) + browser->accessibilityController()->resetToConsistentState(); +#endif + + DumpRenderTreeSupportEfl::clearFrameName(mainFrame()); + DumpRenderTreeSupportEfl::clearOpener(mainFrame()); +#endif + WebCore::DumpRenderTreeClient::clearUserScripts(webView); +#if 0 + DumpRenderTreeSupportEfl::clearUserStyleSheets(mainView()); + DumpRenderTreeSupportEfl::resetGeolocationClientMock(mainView()); + DumpRenderTreeSupportEfl::setInteractiveFormValidationEnabled(mainView(), true); + DumpRenderTreeSupportEfl::setValidationMessageTimerMagnification(mainView(), -1); + DumpRenderTreeSupportEfl::setAuthorAndUserStylesEnabled(mainView(), true); + DumpRenderTreeSupportEfl::setCSSGridLayoutEnabled(mainView(), false); + DumpRenderTreeSupportEfl::setDefersLoading(mainView(), false); + DumpRenderTreeSupportEfl::setLoadsSiteIconsIgnoringImageLoadingSetting(mainView(), false); + DumpRenderTreeSupportEfl::setSerializeHTTPLoads(false); + DumpRenderTreeSupportEfl::setMinimumLogicalFontSize(mainView(), 9); + DumpRenderTreeSupportEfl::setCSSRegionsEnabled(mainView(), true); + DumpRenderTreeSupportEfl::setShouldTrackVisitedLinks(false); + DumpRenderTreeSupportEfl::setTracksRepaints(mainFrame(), false); + DumpRenderTreeSupportEfl::setSeamlessIFramesEnabled(true); + DumpRenderTreeSupportEfl::setWebAudioEnabled(mainView(), false); + + // Reset capacities for the memory cache for dead objects. + static const unsigned cacheTotalCapacity = 8192 * 1024; + ewk_settings_object_cache_capacity_set(0, cacheTotalCapacity, cacheTotalCapacity); + DumpRenderTreeSupportEfl::setDeadDecodedDataDeletionInterval(0); + ewk_settings_page_cache_capacity_set(3); + + policyDelegateEnabled = false; + policyDelegatePermissive = false; +#endif +} + +static void runTest(const string& inputLine) +{ + TestCommand command = parseInputLine(inputLine); + const String testPathOrURL(command.pathOrURL.c_str()); + ASSERT(!testPathOrURL.isEmpty()); + dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests; + const String expectedPixelHash(command.expectedPixelHash.c_str()); + + // Convert the path into a full file URL if it does not look + // like an HTTP/S URL (doesn't start with http:// or https://). + const String testURL = getFinalTestURL(testPathOrURL); + + resetDefaultsToConsistentValues(); + createTestRunner(testURL, expectedPixelHash); + + DRT::WorkQueue::singleton().clear(); + DRT::WorkQueue::singleton().setFrozen(false); + + const bool isSVGW3CTest = testURL.contains("svg/W3C-SVG-1.1"); + const int width = isSVGW3CTest ? TestRunner::w3cSVGViewWidth : TestRunner::viewWidth; + const int height = isSVGW3CTest ? TestRunner::w3cSVGViewHeight : TestRunner::viewHeight; + webView->LockLooper(); + webView->ResizeTo(width - 1, height - 1); + webView->Window()->ResizeTo(width - 1, height - 1); + webView->UnlockLooper(); + + // TODO efl does some history cleanup here + + webView->WebPage()->MainFrame()->LoadURL(BString(testURL)); +} + +#pragma mark - + +class DumpRenderTreeApp : public BApplication, WebCore::DumpRenderTreeClient { +public: + DumpRenderTreeApp(); + ~DumpRenderTreeApp() { + delete m_webWindow->CurrentWebView(); + } + + // BApplication + void ArgvReceived(int32 argc, char** argv) override; + void ReadyToRun() override; + void MessageReceived(BMessage*) override; + + // DumpRenderTreeClient + void didClearWindowObjectInWorld(WebCore::DOMWrapperWorld&, + JSGlobalContextRef context, JSObjectRef windowObject) override; + + static status_t runTestFromStdin(); + +private: + void topLoadingFrameLoadFinished(); +private: + GCController* m_gcController; + AccessibilityController* m_accessibilityController; + BWebWindow* m_webWindow; + + int m_currentTest; + vector m_tests; + bool m_fromStdin; +}; + + +DumpRenderTreeApp::DumpRenderTreeApp() + : BApplication("application/x-vnd.DumpRenderTree") +{ +} + +void DumpRenderTreeApp::ArgvReceived(int32 argc, char** argv) +{ + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--notree")) { + dumpTree = false; + continue; + } + + if (!strcmp(argv[i], "--pixel-tests")) { + dumpPixelsForAllTests = true; + continue; + } + + if (!strcmp(argv[i], "--tree")) { + dumpTree = true; + continue; + } + + if (!strcmp(argv[i], "--no-timeout")) { + useTimeoutWatchdog = true; + continue; + } + + char* str = new char[strlen(argv[i]) + 1]; + strcpy(str, argv[i]); + m_tests.push_back(str); + } +} + +class DumpRenderTreeChrome: public BWebWindow +{ + public: + DumpRenderTreeChrome() + : BWebWindow(BRect(0, 0, maxViewWidth, maxViewHeight), "DumpRenderTree", + B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 0) + { + } + + void MessageReceived(BMessage* msg) + { + if (msg->what == SSL_CERT_ERROR) + { + // Always accept SSL certificates, since the test suite uses an + // auto-generated one and that would normally produce warnings. + BMessage reply; + reply.AddBool("continue", true); + msg->SendReply(&reply); + return; + } + + BWebWindow::MessageReceived(msg); + } +}; + +void DumpRenderTreeApp::ReadyToRun() +{ + BWebPage::InitializeOnce(); + BWebPage::SetCacheModel(B_WEBKIT_CACHE_MODEL_WEB_BROWSER); + + // Create the main application window. + m_webWindow = new DumpRenderTreeChrome(); + m_webWindow->SetSizeLimits(0, maxViewWidth - 1, 0, maxViewHeight - 1); + m_webWindow->ResizeTo(maxViewWidth - 1, maxViewHeight - 1); + + DumpRenderTreeClient::setMockScrollbarsEnabled(true); + + webView = new BWebView("DumpRenderTree"); + m_webWindow->AddChild(webView); + m_webWindow->SetCurrentWebView(webView); + webView->ResizeTo(maxViewWidth - 1, maxViewHeight - 1); + + webView->WebPage()->SetListener(this); + Register(webView->WebPage()); + webView->WebPage()->Settings()->SetDefaultStandardFontSize(16); + webView->WebPage()->Settings()->SetDefaultFixedFontSize(13); + // Make sure we use the same metrics are others for the tests. + webView->WebPage()->Settings()->Apply(); + + // Start the looper, but keep the window hidden + m_webWindow->Hide(); + m_webWindow->Show(); + + if (m_tests.size() == 1 && !strcmp(m_tests[0], "-")) { + printSeparators = true; + m_fromStdin = true; + runTestFromStdin(); + } else if(m_tests.size() != 0) { + printSeparators = (m_tests.size() > 1 || (dumpPixelsForAllTests && dumpTree)); + m_fromStdin = false; + runTest(m_tests[0]); + m_currentTest = 1; + } +} + +bool shouldSetWaitToDumpWatchdog() +{ + return !waitToDumpWatchdog && useTimeoutWatchdog; +} + +static void sendPixelResultsEOF() +{ + puts("#EOF"); + fflush(stdout); + fflush(stderr); +} + +void DumpRenderTreeApp::topLoadingFrameLoadFinished() +{ + topLoadingFrame = 0; + + DRT::WorkQueue::singleton().setFrozen(true); + if (gTestRunner->waitToDump()) { + return; + } + + if (DRT::WorkQueue::singleton().count()) { + // FIXME should wait until the work queue is done before dumping + // ecore_idler_add(processWork, 0 /*frame*/); + dump(); + } else { + dump(); + } +} + +extern void watchdogFired(); + +void DumpRenderTreeApp::MessageReceived(BMessage* message) +{ + switch (message->what) { + case 'dwdg': { + watchdogFired(); + break; + } + + case LOAD_STARTED: { + // efl: DumpRenderTreeChrome::onLoadStarted + BWebFrame* frame = NULL; + message->FindPointer("frame", (void**)&frame); + + // Make sure we only set this once per test. If it gets cleared, and + // then set again, we might end up doing two dumps for one test. + if (!topLoadingFrame && first) { + first = false; + topLoadingFrame = frame; + } + break; + } + + case RESPONSE_RECEIVED: { + if (!done && gTestRunner->dumpResourceLoadCallbacks()) { +#if 0 + CString responseDescription(descriptionSuitableForTestResult(response)); + printf("%s - didReceiveResponse %s\n", + m_dumpAssignedUrls.contains(response->identifier) ? m_dumpAssignedUrls.get(response->identifier).data() : "", + responseDescription.data()); +#endif + } + + if (!done && gTestRunner->dumpResourceResponseMIMETypes()) { + BString mimeType = message->FindString("mimeType"); + BString url = message->FindString("url"); + printf("%s has MIME type %s\n", + WTF::URL({ }, url).lastPathComponent().utf8().data(), + mimeType.String()); + } + break; + } + + case TITLE_CHANGED: { + // efl: DumpRenderTreeChrome::onFrameTitleChanged + BWebFrame* frame = NULL; + message->FindPointer("frame", (void**)&frame); + BString title = message->FindString("title"); + + if (!done && gTestRunner->dumpFrameLoadCallbacks()) { + const String frameName(DumpRenderTreeClient::suitableDRTFrameName( + frame)); + printf("%s - didReceiveTitle: %s\n", frameName.utf8().data(), + title.String()); + } + + if (!done && gTestRunner->dumpTitleChanges()) { + printf("TITLE CHANGED: '%s'\n", title.String()); + } + + if (!done && gTestRunner->dumpHistoryDelegateCallbacks()) { + printf("WebView updated the title for history URL \"%s\" to \"%s\".\n", + frame->URL().String(), title.String()); + } + + gTestRunner->setTitleTextDirection(message->FindBool("ltr") ? "ltr" : "rtl"); + break; + } + + case LOAD_FINISHED: { + // efl: DumpRenderTreeChrome::onFrameLoadFinished + if (!done && gTestRunner->dumpProgressFinishedCallback()) + printf("postProgressFinishedNotification\n"); + + BWebFrame* frame = NULL; + message->FindPointer("frame", (void**)&frame); + if (!done && gTestRunner->dumpFrameLoadCallbacks()) { + const String frameName(DumpRenderTreeClient::suitableDRTFrameName(frame)); + printf("%s - didFinishLoadForFrame\n", frameName.utf8().data()); + } + + if (frame == topLoadingFrame) + topLoadingFrameLoadFinished(); + + break; + } + + case LOAD_DOC_COMPLETED: { + //efl: DumpRenderTreeChrome::onDocumentLoadFinished + + BWebFrame* frame = NULL; + message->FindPointer("frame", (void**)&frame); + const String frameName(DumpRenderTreeClient::suitableDRTFrameName(frame)); + + if (!done && gTestRunner->dumpFrameLoadCallbacks()) + printf("%s - didFinishDocumentLoadForFrame\n", frameName.utf8().data()); + else if (!done) { + const unsigned pendingFrameUnloadEvents = DumpRenderTreeClient::pendingUnloadEventCount(frame); + if (pendingFrameUnloadEvents) + printf("%s - has %u onunload handler(s)\n", frameName.utf8().data(), pendingFrameUnloadEvents); + } + + break; + } + + case ADD_CONSOLE_MESSAGE: + { + // Follow the format used by other DRTs here. Note this doesn't + // include the fille URL, making it possible to have consistent + // results even if the tests are moved around. + int32 lineNumber = message->FindInt32("line"); + BString text = message->FindString("string"); + printf("CONSOLE MESSAGE: "); + if (lineNumber) + printf("line %" B_PRIu32 ": ", lineNumber); + printf("%s\n", text.String()); + fflush(stdout); + return; + } + + case SHOW_JS_ALERT: + { + BString text = message->FindString("text"); + printf("ALERT: %s\n", text.String()); + fflush(stdout); + return; + } + case SHOW_JS_CONFIRM: + { + BString text = message->FindString("text"); + printf("CONFIRM: %s\n", text.String()); + fflush(stdout); + + BMessage reply; + reply.AddBool("result", true); + message->SendReply(&reply); + return; + } + + case 'dump': + { + // Code from EFL runTest, after the test is done. We do this here as we're + // sure the test is done running. + + gTestRunner->closeWebInspector(); + gTestRunner->setDeveloperExtrasEnabled(false); + + //browser->clearExtraViews(); + + // FIXME: Move to DRTChrome::resetDefaultsToConsistentValues() after bug 85209 lands. + WebCoreTestSupport::resetInternalsObject( + DumpRenderTreeClient::globalContextRefForFrame( + webView->WebPage()->MainFrame())); + + // TODO efl goes to "about:blank" here. But this triggers an extra + // dump for us, confusing the test system. + + //gTestRunner.clear(); + sendPixelResultsEOF(); + + if (m_fromStdin) { + // run the next test. + if(runTestFromStdin() != B_OK) { + be_app->PostMessage(B_QUIT_REQUESTED); + } + break; + } else { + if (m_currentTest < m_tests.size()) { + runTest(m_tests[m_currentTest]); + m_currentTest++; + } else { + be_app->PostMessage(B_QUIT_REQUESTED); + } + } + return; + } + + default: + if(!handleEditingCallback(message)) + BApplication::MessageReceived(message); + break; + } +} + +void DumpRenderTreeApp::didClearWindowObjectInWorld(WebCore::DOMWrapperWorld&, JSGlobalContextRef context, JSObjectRef windowObject) +{ + JSValueRef exception = 0; + + gTestRunner->makeWindowObject(context, windowObject, &exception); + ASSERT(!exception); + + m_gcController->makeWindowObject(context, windowObject, &exception); + ASSERT(!exception); + + //m_accessibilityController->makeWindowObject(context, windowObject, &exception); + //ASSERT(!exception); + + JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender"); + JSValueRef eventSender = makeEventSender(context); + JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); + JSStringRelease(eventSenderStr); + + WebCoreTestSupport::injectInternalsObject(context); +} + +status_t DumpRenderTreeApp::runTestFromStdin() +{ + char filenameBuffer[2048]; + + if(fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) { + + char* newLineCharacter = strchr(filenameBuffer, '\n'); + + if (newLineCharacter) + *newLineCharacter = '\0'; + + if (!strlen(filenameBuffer)) { + // Got an empty line, try again... + return runTestFromStdin(); + } + + runTest(filenameBuffer); + return B_OK; + } + + return B_ERROR; + +} + +#pragma mark - + + +int main() +{ + DumpRenderTreeApp app; + app.Run(); +} + diff --git a/Tools/DumpRenderTree/haiku/DumpRenderTreeHaiku.h b/Tools/DumpRenderTree/haiku/DumpRenderTreeHaiku.h new file mode 100644 index 000000000000..6550f05bd066 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/DumpRenderTreeHaiku.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 Kevin Ollivier + * Copyright (C) 2009 Maxime Simon + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DumpRenderTreeHaiku_h +#define DumpRenderTreeHaiku_h + +#include + +class BWebFrame; + +class AccessibilityController; +class GCController; + +extern BWebFrame* topLoadingFrame; +extern bool waitForPolicy; +extern BMessageRunner* waitToDumpWatchdog; + +bool shouldSetWaitToDumpWatchdog(); + +#endif // DumpRenderTreeHaiku_h diff --git a/Tools/DumpRenderTree/haiku/EditingCallbacks.cpp b/Tools/DumpRenderTree/haiku/EditingCallbacks.cpp new file mode 100644 index 000000000000..ea72ed7aa869 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/EditingCallbacks.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * Copyright (C) 2012 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "EditingCallbacks.h" + +#include "DumpRenderTree.h" +#include "EditorClientHaiku.h" +#include "EditorInsertAction.h" +#include +#include +#include +#include "TestRunner.h" +#include "TextAffinity.h" +#include "WebViewConstants.h" +#include +#include + +static WTF::String dumpPath(WebCore::Node* node) +{ + ASSERT(node); + + WTF::String str(node->nodeName()); + + WebCore::Node* parent = node->parentNode(); + if (parent) { + str.append(" > "); + str.append(dumpPath(parent)); + } + return str; +} + +static BString dumpRange(WebCore::Range* range) +{ + if (!range) + return BString(); + + BString string; + string.SetToFormat("range from %d of %s to %d of %s", + range->startOffset(), dumpPath(&range->startContainer()).utf8().data(), + range->endOffset(), dumpPath(&range->endContainer()).utf8().data()); + return string; +} + +static const char* insertActionString(WebCore::EditorInsertAction action) +{ + switch (action) { + case WebCore::EditorInsertAction::Typed: + return "WebViewInsertActionTyped"; + case WebCore::EditorInsertAction::Pasted: + return "WebViewInsertActionPasted"; + case WebCore::EditorInsertAction::Dropped: + return "WebViewInsertActionDropped"; + } + ASSERT_NOT_REACHED(); + return "WebViewInsertActionTyped"; +} + +static const char* selectionAffinityString(WebCore::EAffinity affinity) +{ + switch (affinity) { + case WebCore::UPSTREAM: + return "NSSelectionAffinityUpstream"; + case WebCore::DOWNSTREAM: + return "NSSelectionAffinityDownstream"; + } + ASSERT_NOT_REACHED(); + return "NSSelectionAffinityUpstream"; +} + +static void shouldBeginEditing(WebCore::Range* range) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n", dumpRange(range).String()); + } +} + +static void shouldEndEditing(WebCore::Range* range) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n", dumpRange(range).String()); + } +} + +static void shouldInsertNode(WebCore::Node* node, WebCore::Range* range, + WebCore::EditorInsertAction action) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n", + dumpPath(node).utf8().data(), dumpRange(range).String(), + insertActionString(action)); + } +} + +static void shouldInsertText(BString text, WebCore::Range* range, + WebCore::EditorInsertAction action) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n", + text.String(), dumpRange(range).String(), insertActionString(action)); + } +} + +static void shouldDeleteRange(WebCore::Range* range) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldDeleteDOMRange:%s\n", dumpRange(range).String()); + } +} + +static void shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, + WebCore::EAffinity affinity, bool stillSelecting) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n", + dumpRange(fromRange).String(), dumpRange(toRange).String(), + selectionAffinityString(affinity), stillSelecting ? "TRUE" : "FALSE"); + } +} + +static void shouldApplyStyle(WebCore::StyleProperties* style, WebCore::Range* range) +{ + if (!done && gTestRunner->dumpEditingCallbacks()) { + printf("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n", + style->asText().utf8().data(), dumpRange(range).String()); + } +} + +static void editingBegan() +{ + if (!done && gTestRunner->dumpEditingCallbacks()) + printf("EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification\n"); +} + +static void userChangedContents() +{ + if (!done && gTestRunner->dumpEditingCallbacks()) + printf("EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification\n"); +} + +static void editingEnded() +{ + if (!done && gTestRunner->dumpEditingCallbacks()) + printf("EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification\n"); +} + +static void selectionChanged() +{ + if (!done && gTestRunner->dumpEditingCallbacks()) + printf("EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification\n"); +} + +bool handleEditingCallback(BMessage* message) +{ + switch(message->what) + { + case EDITOR_DELETE_RANGE: + { + WebCore::Range* range = NULL; + message->FindPointer("range", (void**)&range); + shouldDeleteRange(range); + return true; + } + case EDITOR_BEGIN_EDITING: + { + WebCore::Range* range = NULL; + message->FindPointer("range", (void**)&range); + shouldBeginEditing(range); + return true; + } + case EDITOR_EDITING_BEGAN: + editingBegan(); + return true; + case EDITOR_EDITING_ENDED: + editingEnded(); + return true; + case EDITOR_END_EDITING: + { + WebCore::Range* range = NULL; + message->FindPointer("range", (void**)&range); + shouldEndEditing(range); + return true; + } + case EDITOR_INSERT_NODE: + { + WebCore::Range* range = NULL; + WebCore::Node* node = NULL; + message->FindPointer("range", (void**)&range); + message->FindPointer("node", (void**)&node); + WebCore::EditorInsertAction action = (WebCore::EditorInsertAction)message->FindInt32("action"); + shouldInsertNode(node, range, action); + return true; + } + case EDITOR_INSERT_TEXT: + { + WebCore::Range* range = NULL; + message->FindPointer("range", (void**)&range); + BString text = message->FindString("text"); + WebCore::EditorInsertAction action = (WebCore::EditorInsertAction)message->FindInt32("action"); + shouldInsertText(text, range, action); + return true; + } + case EDITOR_CHANGE_SELECTED_RANGE: + { + WebCore::Range* fromRange = NULL; + WebCore::Range* toRange = NULL; + message->FindPointer("from", (void**)&fromRange); + message->FindPointer("to", (void**)&toRange); + WebCore::EAffinity affinity = (WebCore::EAffinity)message->FindInt32("affinity"); + bool stillSelecting = message->FindBool("stillSelecting"); + shouldChangeSelectedRange(fromRange, toRange, affinity, stillSelecting); + return true; + } + case EDITOR_APPLY_STYLE: + { + WebCore::Range* range = NULL; + WebCore::StyleProperties* style = NULL; + message->FindPointer("range", (void**)&range); + message->FindPointer("style", (void**)&style); + shouldApplyStyle(style, range); + return true; + } + case EDITOR_SELECTION_CHANGED: + { + selectionChanged(); + return true; + } + case EDITOR_CONTENTS_CHANGED: + { + userChangedContents(); + return true; + } + } + return false; +} diff --git a/Tools/DumpRenderTree/haiku/EditingCallbacks.h b/Tools/DumpRenderTree/haiku/EditingCallbacks.h new file mode 100644 index 000000000000..82da74128ac7 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/EditingCallbacks.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EditingCallbacks_h +#define EditingCallbacks_h + +class BMessage; + +bool handleEditingCallback(BMessage* message); + +#endif diff --git a/Tools/DumpRenderTree/haiku/EventSender.cpp b/Tools/DumpRenderTree/haiku/EventSender.cpp new file mode 100644 index 000000000000..2e62135947c7 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/EventSender.cpp @@ -0,0 +1,613 @@ +/* + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2009 Zan Dobersek + * Copyright (C) 2009 Holger Hans Peter Freyther + * Copyright (C) 2010 Igalia S.L. + * Copyright (C) 2011 ProFUSION Embedded Systems + * Copyright (C) 2011, 2012 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "EventSender.h" + +#include "DumpRenderTree.h" +#include "IntPoint.h" +#include "JSStringUtils.h" +#include "NotImplemented.h" +#include "PlatformEvent.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static bool gDragMode; +static int gTimeOffset = 0; + +static int gLastMousePositionX; +static int gLastMousePositionY; +static int gLastClickPositionX; +static int gLastClickPositionY; +static int gLastClickTimeOffset; +static int gLastClickButton; +static int gButtonCurrentlyDown; +static int gClickCount; + +static const float zoomMultiplierRatio = 1.2f; + +extern BWebView* webView; + +// Key event location code defined in DOM Level 3. +enum KeyLocationCode { + DomKeyLocationStandard, + DomKeyLocationLeft, + DomKeyLocationRight, + DomKeyLocationNumpad +}; + +enum EventQueueStrategy { + FeedQueuedEvents, + DoNotFeedQueuedEvents +}; + +static unsigned touchModifiers; + +WTF::Vector& delayedEventQueue() +{ + static NeverDestroyed> staticDelayedEventQueue; + return staticDelayedEventQueue; +} + + +static void feedOrQueueMouseEvent(BMessage*, EventQueueStrategy); +static void feedQueuedMouseEvents(); + +static int32 translateMouseButtonNumber(int eventSenderButtonNumber) +{ + static const int32 translationTable[] = { + B_PRIMARY_MOUSE_BUTTON, + B_TERTIARY_MOUSE_BUTTON, + B_SECONDARY_MOUSE_BUTTON, + B_TERTIARY_MOUSE_BUTTON // fast/events/mouse-click-events expects the 4th button to be treated as the middle button + }; + static const unsigned translationTableSize = sizeof(translationTable) / sizeof(translationTable[0]); + + if (eventSenderButtonNumber < translationTableSize) + return translationTable[eventSenderButtonNumber]; + + return 0; +} + +static JSValueRef scheduleAsynchronousClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + notImplemented(); + return JSValueMakeUndefined(context); +} + +static void updateClickCount(int button) +{ + if (gLastClickPositionX != gLastMousePositionX + || gLastClickPositionY != gLastMousePositionY + || gLastClickButton != button + || gTimeOffset - gLastClickTimeOffset >= 1) + gClickCount = 1; + else + gClickCount++; +} + +static int32 modifierFromJSValue(JSContextRef context, const JSValueRef value) +{ + JSRetainPtr jsKeyValue(Adopt, JSValueToStringCopy(context, value, 0)); + + if (equals(jsKeyValue, "ctrlKey") || equals(jsKeyValue, "addSelectionKey")) + return B_CONTROL_KEY; + if (equals(jsKeyValue, "shiftKey") || equals(jsKeyValue, "rangeSelectionKey")) + return B_SHIFT_KEY; + if (equals(jsKeyValue, "altKey")) + return B_COMMAND_KEY; + if (equals(jsKeyValue, "metaKey")) + return B_OPTION_KEY; + + return 0; +} + +static unsigned modifiersFromJSValue(JSContextRef context, const JSValueRef modifiers) +{ + // The value may either be a string with a single modifier or an array of modifiers. + if (JSValueIsString(context, modifiers)) + return modifierFromJSValue(context, modifiers); + + JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0); + if (!modifiersArray) + return 0; + + unsigned modifier = 0; + JSRetainPtr lengthProperty(Adopt, JSStringCreateWithUTF8CString("length")); + int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty.get(), 0), 0); + for (int i = 0; i < modifiersCount; ++i) + modifier |= modifierFromJSValue(context, JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0)); + return modifier; +} + +static JSValueRef getMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) +{ + notImplemented(); + return JSValueMakeString(context, JSStringCreateWithUTF8CString("")); +} + +static bool setMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + return true; +} + +static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + notImplemented(); + return JSValueMakeUndefined(context); +} + +static JSStaticFunction staticMenuItemFunctions[] = { + { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } +}; + +static JSStaticValue staticMenuItemValues[] = { + { "title", getMenuItemTitleCallback, setMenuItemTitleCallback, kJSPropertyAttributeNone }, + { 0, 0, 0, 0 } +}; + +static JSClassRef getMenuItemClass() +{ + static JSClassRef menuItemClass = 0; + + if (!menuItemClass) { + JSClassDefinition classDefinition = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + classDefinition.staticFunctions = staticMenuItemFunctions; + classDefinition.staticValues = staticMenuItemValues; + + menuItemClass = JSClassCreate(&classDefinition); + } + + return menuItemClass; +} + +static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + // Should invoke a context menu, and return its contents + notImplemented(); + return JSValueMakeUndefined(context); +} + +static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + int button = 0; + if (argumentCount == 1) { + button = static_cast(JSValueToNumber(context, arguments[0], exception)); + + if (exception && *exception) + return JSValueMakeUndefined(context); + } + + button = translateMouseButtonNumber(button); + // If the same mouse button is already in the down position don't send another event as it may confuse Xvfb. + if (gButtonCurrentlyDown == button) + return JSValueMakeUndefined(context); + + updateClickCount(button); + + unsigned modifiers = argumentCount >= 2 ? modifiersFromJSValue(context, arguments[1]) : 0; + BMessage* eventInfo = new BMessage(B_MOUSE_DOWN); + eventInfo->AddInt32("modifiers", modifiers); + eventInfo->AddInt32("buttons", button); + eventInfo->AddInt32("clicks", gClickCount); + eventInfo->AddPoint("where", BPoint(gLastMousePositionX, gLastMousePositionY)); + eventInfo->AddPoint("be:view_where", BPoint(gLastMousePositionX, gLastMousePositionY)); + feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); + gButtonCurrentlyDown = button; + return JSValueMakeUndefined(context); +} + +static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + int button = 0; + if (argumentCount == 1) { + button = static_cast(JSValueToNumber(context, arguments[0], exception)); + if (exception && *exception) + return JSValueMakeUndefined(context); + } + + button = translateMouseButtonNumber(button); + + gLastClickPositionX = gLastMousePositionX; + gLastClickPositionY = gLastMousePositionY; + gLastClickButton = gButtonCurrentlyDown; + gLastClickTimeOffset = gTimeOffset; + gButtonCurrentlyDown = 0; + + unsigned modifiers = argumentCount >= 2 ? modifiersFromJSValue(context, arguments[1]) : 0; + BMessage* eventInfo = new BMessage(B_MOUSE_UP); + eventInfo->AddInt32("modifiers", modifiers); + eventInfo->AddInt32("previous buttons", button); + eventInfo->AddPoint("where", BPoint(gLastMousePositionX, gLastMousePositionY)); + eventInfo->AddPoint("be:view_where", BPoint(gLastMousePositionX, gLastMousePositionY)); + feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); + return JSValueMakeUndefined(context); +} + +static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + gLastMousePositionX = static_cast(JSValueToNumber(context, arguments[0], exception)); + if (exception && *exception) + return JSValueMakeUndefined(context); + gLastMousePositionY = static_cast(JSValueToNumber(context, arguments[1], exception)); + if (exception && *exception) + return JSValueMakeUndefined(context); + + BMessage* eventInfo = new BMessage(B_MOUSE_MOVED); + eventInfo->AddPoint("where", BPoint(gLastMousePositionX, gLastMousePositionY)); + eventInfo->AddPoint("be:view_where", BPoint(gLastMousePositionX, gLastMousePositionY)); + feedOrQueueMouseEvent(eventInfo, DoNotFeedQueuedEvents); + eventInfo->AddInt32("buttons", gButtonCurrentlyDown); + return JSValueMakeUndefined(context); +} + +static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount > 0) { + const unsigned long leapForwardDelay = JSValueToNumber(context, arguments[0], exception); + if (delayedEventQueue().isEmpty()) + delayedEventQueue().append(new BMessage((uint32)0)); + delayedEventQueue().last()->AddInt32("delay", leapForwardDelay); + gTimeOffset += leapForwardDelay; + } + + return JSValueMakeUndefined(context); +} + +static BMessage* evasMouseEventFromHorizontalAndVerticalOffsets(int horizontalOffset, int verticalOffset) +{ + BMessage* message = new BMessage(B_MOUSE_WHEEL_CHANGED); + message->AddFloat("be:wheel_delta_x", horizontalOffset); + message->AddFloat("be:wheel_delta_y", verticalOffset); + return message; +} + +static JSValueRef mouseScrollByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 2) + return JSValueMakeUndefined(context); + + // We need to invert scrolling values since in EFL negative z value means that + // canvas is scrolling down + const int horizontal = -(static_cast(JSValueToNumber(context, arguments[0], exception))); + if (exception && *exception) + return JSValueMakeUndefined(context); + const int vertical = -(static_cast(JSValueToNumber(context, arguments[1], exception))); + if (exception && *exception) + return JSValueMakeUndefined(context); + + BMessage* eventInfo = evasMouseEventFromHorizontalAndVerticalOffsets(horizontal, vertical); + feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); + return JSValueMakeUndefined(context); +} + +static JSValueRef continuousMouseScrollByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + return JSValueMakeUndefined(context); +} + +struct mapping { + const char* name; + uint32_t code; + char byte; +}; + +static BMessage* keyPadNameFromJSValue(JSStringRef character, unsigned modifiers) +{ + BMessage* message = new BMessage(B_KEY_DOWN); + message->AddInt32("modifiers", modifiers); + + static const mapping keys [] = { + {"leftArrow", 0x48, B_LEFT_ARROW}, + {"rightArrow", 0x4a, B_RIGHT_ARROW}, + {"upArrow", 0x38, B_UP_ARROW}, + {"downArrow", 0x59, B_DOWN_ARROW}, + {"pageUp", 0x39, B_PAGE_UP}, + {"pageDown", 0x5a, B_PAGE_DOWN}, + {"home", 0x37, B_HOME}, + {"end", 0x58, B_END}, + {"insert", 0x64, B_INSERT}, + {"delete", 0x65, B_DELETE}, + }; + + bool special = false; + for(int i = 0; i < sizeof(keys)/sizeof(mapping); i++) + { + if (equals(character, keys[i].name)) { + message->AddInt32("key", keys[i].code); + message->AddData("bytes", B_STRING_TYPE, &keys[i].byte, 1); + special = true; + } + } + + if(!special) { + BString bytes(character->string()); + message->AddString("bytes", bytes); + if ((character->length() == 1) && (bytes[0] >= 'A' && bytes[0] <= 'Z')) + modifiers |= B_SHIFT_KEY; + } + return message; +} + +static BMessage* keyNameFromJSValue(JSStringRef character, unsigned modifiers) +{ + BMessage* message = new BMessage(B_KEY_DOWN); + + message->AddInt32("modifiers", modifiers); + + static const mapping keys [] = { + {"leftArrow", 0x61, B_LEFT_ARROW}, + {"rightArrow", 0x63, B_RIGHT_ARROW}, + {"upArrow", 0x57, B_UP_ARROW}, + {"downArrow", 0x62, B_DOWN_ARROW}, + {"pageUp", 0x21, B_PAGE_UP}, + {"pageDown", 0x36, B_PAGE_DOWN}, + {"home", 0x20, B_HOME}, + {"end", 0x35, B_END}, + {"insert", 0x1f, B_INSERT}, + {"delete", 0x34, B_DELETE}, + + {"printScreen",B_PRINT_KEY, B_FUNCTION_KEY}, + {"F1", B_F1_KEY, B_FUNCTION_KEY}, + {"F2", B_F2_KEY, B_FUNCTION_KEY}, + {"F3", B_F3_KEY, B_FUNCTION_KEY}, + {"F4", B_F4_KEY, B_FUNCTION_KEY}, + {"F5", B_F5_KEY, B_FUNCTION_KEY}, + {"F6", B_F6_KEY, B_FUNCTION_KEY}, + {"F7", B_F7_KEY, B_FUNCTION_KEY}, + {"F8", B_F8_KEY, B_FUNCTION_KEY}, + {"F9", B_F9_KEY, B_FUNCTION_KEY}, + {"F10", B_F10_KEY, B_FUNCTION_KEY}, + {"F11", B_F11_KEY, B_FUNCTION_KEY}, + {"F12", B_F12_KEY, B_FUNCTION_KEY} + }; + + bool special = false; + for(int i = 0; i < sizeof(keys)/sizeof(mapping); i++) + { + if (equals(character, keys[i].name)) { + message->AddInt32("key", keys[i].code); + message->AddData("bytes", B_STRING_TYPE, &keys[i].byte, 1); + special = true; + } + } + +#if 0 + // Modifiers + if (equals(character, "menu")) + return new KeyEventInfo("Menu", modifiers); + if (equals(character, "leftControl")) + return new KeyEventInfo("Control_L", modifiers); + if (equals(character, "rightControl")) + return new KeyEventInfo("Control_R", modifiers); + if (equals(character, "leftShift")) + return new KeyEventInfo("Shift_L", modifiers); + if (equals(character, "rightShift")) + return new KeyEventInfo("Shift_R", modifiers); + if (equals(character, "leftAlt")) + return new KeyEventInfo("Alt_L", modifiers); + if (equals(character, "rightAlt")) + return new KeyEventInfo("Alt_R", modifiers); +#endif + + if(!special) { + BString bytes(character->string()); + message->AddString("bytes", bytes); + if ((character->length() == 1) && (bytes[0] >= 'A' && bytes[0] <= 'Z')) + modifiers |= B_SHIFT_KEY; + } + + return message; +} + +static BMessage* createKeyEventInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return 0; + + // handle location argument. + int location = DomKeyLocationStandard; + if (argumentCount > 2) + location = static_cast(JSValueToNumber(context, arguments[2], exception)); + + JSRetainPtr character(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + if (exception && *exception) + return 0; + + unsigned modifiers = 0; + if (argumentCount >= 2) + modifiers = modifiersFromJSValue(context, arguments[1]); + + return (location == DomKeyLocationNumpad) ? keyPadNameFromJSValue(character.get(), modifiers) : keyNameFromJSValue(character.get(), modifiers); +} + +static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + BMessage* event = createKeyEventInfo(context, argumentCount, arguments, exception); + WebCore::DumpRenderTreeClient::injectKeyEvent(webView->WebPage(), event); + return JSValueMakeUndefined(context); +} + +static JSValueRef scalePageByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + notImplemented(); + return JSValueMakeUndefined(context); +} + +static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + webView->IncreaseZoomFactor(true); + return JSValueMakeUndefined(context); +} + +static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + webView->DecreaseZoomFactor(true); + return JSValueMakeUndefined(context); +} + +static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + webView->IncreaseZoomFactor(false); + return JSValueMakeUndefined(context); +} + +static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + webView->DecreaseZoomFactor(false); + return JSValueMakeUndefined(context); +} + +static JSValueRef scheduleAsynchronousKeyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + notImplemented(); + return JSValueMakeUndefined(context); +} + +static JSStaticFunction staticFunctions[] = { + { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "mouseScrollBy", mouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, +#if 0 + { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "continuousMouseScrollBy", continuousMouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "beginDragWithFiles", beginDragWithFilesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "scheduleAsynchronousClick", scheduleAsynchronousClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "scheduleAsynchronousKeyDown", scheduleAsynchronousKeyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "scalePageBy", scalePageByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, +#endif + { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } +}; + +static JSStaticValue staticValues[] = { + { 0, 0, 0, 0 } +}; + +static JSClassRef getClass(JSContextRef context) +{ + static JSClassRef eventSenderClass = 0; + + if (!eventSenderClass) { + JSClassDefinition classDefinition = { + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + classDefinition.staticFunctions = staticFunctions; + classDefinition.staticValues = staticValues; + + eventSenderClass = JSClassCreate(&classDefinition); + } + + return eventSenderClass; +} + +JSObjectRef makeEventSender(JSContextRef context) +{ + return JSObjectMake(context, getClass(context), 0); +} + +static void feedOrQueueMouseEvent(BMessage* eventInfo, EventQueueStrategy strategy) +{ + if (!delayedEventQueue().isEmpty()) { + if (delayedEventQueue().last() != NULL) + delayedEventQueue().append(eventInfo); + else + delayedEventQueue().last() = eventInfo; + + if (strategy == FeedQueuedEvents) + feedQueuedMouseEvents(); + } else + WebCore::DumpRenderTreeClient::injectMouseEvent(webView->WebPage(), eventInfo); +} + +namespace WebCore { + +void DumpRenderTreeClient::injectMouseEvent(BWebPage* target, BMessage* event) +{ + // We are short-circuiting the normal message delivery path, because tests + // expect this to be synchronous (the event must be processed when the + // method returns) + target->handleMouseEvent(event); + delete event; +} + +void DumpRenderTreeClient::injectKeyEvent(BWebPage* target, BMessage* event) +{ + // We are short-circuiting the normal message delivery path, because tests + // expect this to be synchronous (the event must be processed when the + // method returns) + target->handleKeyEvent(event); + event->what = B_KEY_UP; + target->handleKeyEvent(event); + delete event; +} +} + +static void feedQueuedMouseEvents() +{ + WTF::Vector::const_iterator it = delayedEventQueue().begin(); + for (; it != delayedEventQueue().end(); it++) { + BMessage* delayedEvent = *it; + int32 delay = delayedEvent->FindInt32("delay"); + if (delay) + usleep(delay * 1000); + WebCore::DumpRenderTreeClient::injectMouseEvent(webView->WebPage(), delayedEvent); + } + delayedEventQueue().clear(); +} diff --git a/Tools/DumpRenderTree/haiku/EventSender.h b/Tools/DumpRenderTree/haiku/EventSender.h new file mode 100644 index 000000000000..e8da88f035c7 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/EventSender.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2009 Holger Hans Peter Freyther + * Copyright (C) 2011 ProFUSION Embedded Systems + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EventSender_h +#define EventSender_h + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; + +JSObjectRef makeEventSender(JSContextRef); + +#endif // EventSender_h diff --git a/Tools/DumpRenderTree/haiku/GCControllerHaiku.cpp b/Tools/DumpRenderTree/haiku/GCControllerHaiku.cpp new file mode 100644 index 000000000000..54514379a031 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/GCControllerHaiku.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008 Kevin Ollivier + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include + +void GCController::collect() const +{ +} + +void GCController::collectOnAlternateThread(bool waitUntilDone) const +{ +} + +size_t GCController::getJSObjectCount() const +{ + return 0; +} diff --git a/Tools/DumpRenderTree/haiku/JSStringUtils.cpp b/Tools/DumpRenderTree/haiku/JSStringUtils.cpp new file mode 100644 index 000000000000..19ca557364ed --- /dev/null +++ b/Tools/DumpRenderTree/haiku/JSStringUtils.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 ProFUSION Embedded Systems + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ITS CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSStringUtils.h" + +bool equals(JSStringRef jsString, const char* cString) +{ + return JSStringIsEqualToUTF8CString(jsString, cString); +} + +bool equals(JSRetainPtr jsString, const char* cString) +{ + return equals(jsString.get(), cString); +} diff --git a/Tools/DumpRenderTree/haiku/JSStringUtils.h b/Tools/DumpRenderTree/haiku/JSStringUtils.h new file mode 100644 index 000000000000..04d7e08127b4 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/JSStringUtils.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 ProFUSION Embedded Systems + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ITS CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef JSStringUtils_h +#define JSStringUtils_h + +#include +#include + +bool equals(JSStringRef, const char*); +bool equals(JSRetainPtr, const char*); + +#endif // JSStringUtils_h + diff --git a/Tools/DumpRenderTree/haiku/PixelDumpSupportHaiku.cpp b/Tools/DumpRenderTree/haiku/PixelDumpSupportHaiku.cpp new file mode 100644 index 000000000000..08cb8e72ab80 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/PixelDumpSupportHaiku.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2013 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PixelDumpSupportHaiku.h" + +#include "DumpRenderTree.h" +#include "IntRect.h" +#include "NotImplemented.h" +#include "PixelDumpSupport.h" +#include "WebView.h" + +#include + +#include + +#include +#include +#include +#include +#include + +extern BWebView* webView; + +RefPtr createBitmapContextFromWebView(bool, bool, bool, bool drawSelectionRect) +{ + BSize size; + webView->LockLooper(); + BRect r = webView->Bounds(); + webView->UnlockLooper(); + size.width = r.Width() + 1; + size.height = r.Height() + 1; + BBitmap* bitmap = WebCore::DumpRenderTreeClient::getOffscreen(webView); + return BitmapContext::createByAdoptingData(size, bitmap); +} + +void computeMD5HashStringForBitmapContext(BitmapContext* context, char hashString[33]) +{ + hashString[0] = 0; + + if (!context || !context->m_bitmap) + return; + + BRect bounds = context->m_bitmap->Bounds(); + int pixelsWide = bounds.Width(); + int pixelsHigh = bounds.Height(); + int bytesPerRow = context->m_bitmap->BytesPerRow(); + unsigned char* pixelData = (unsigned char*)context->m_bitmap->Bits(); + + MD5 md5; + for (int i = 0; i <= pixelsHigh; ++i) { + md5.addBytes(pixelData, 4 * pixelsWide); + pixelData += bytesPerRow; + } + + MD5::Digest hash; + md5.checksum(hash); + + hashString[0] = '\0'; + for (int i = 0; i < 16; ++i) { + snprintf(&hashString[i * 2], 3, "%02x", hash[i]); + } +} + +void dumpBitmap(BitmapContext* context, const char* checksum) +{ + if (!context || !context->m_bitmap) + return; + + BBitmapStream stream(context->m_bitmap); + BMallocIO mio; + status_t err = BTranslatorRoster::Default()->Translate(&stream, NULL, NULL, &mio, B_PNG_FORMAT); + if (err == B_OK) + printPNG((const unsigned char*)mio.Buffer(), mio.BufferLength(), checksum); + else + fprintf(stderr, "Error translating bitmap: %s\n", strerror(err)); + + BBitmap* out; + stream.DetachBitmap(&out); + ASSERT(out == context->m_bitmap); +} diff --git a/Tools/DumpRenderTree/haiku/PixelDumpSupportHaiku.h b/Tools/DumpRenderTree/haiku/PixelDumpSupportHaiku.h new file mode 100644 index 000000000000..bc4ec61adc6e --- /dev/null +++ b/Tools/DumpRenderTree/haiku/PixelDumpSupportHaiku.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PixelDumpSupportHaiku_h +#define PixelDumpSupportHaiku_h + +#include +#include + +#include +#include +#include + + +class BitmapContext : public RefCounted { +public: + + static RefPtr createByAdoptingData(BSize size, + BBitmap* bitmap) + { + BitmapContext* context = new BitmapContext(size, bitmap); + return adoptRef(*context); + } + + ~BitmapContext() + { + delete m_bitmap; + } + + BBitmap* m_bitmap; + +private: + + BitmapContext(BSize size, BBitmap* bitmap) + { + // The size may be smaller than the bitmap, as we only want to keep the + // viewport. + m_bitmap = new BBitmap(BRect(0, 0, size.Width() - 1, size.Height() - 1), 0, + B_RGBA32); + m_bitmap->ImportBits(bitmap, BPoint(0, 0), BPoint(0, 0), size.Width(), + size.Height()); + } +}; + +#endif // PixelDumpSupportHaiku_h diff --git a/Tools/DumpRenderTree/haiku/TestRunnerHaiku.cpp b/Tools/DumpRenderTree/haiku/TestRunnerHaiku.cpp new file mode 100644 index 000000000000..31e42ed55864 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/TestRunnerHaiku.cpp @@ -0,0 +1,675 @@ +/* + * Copyright (C) 2013 Haiku, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TestRunner.h" + +#include "DumpRenderTree.h" +#include "JSStringUtils.h" +#include "NotImplemented.h" +#include "wtf/URL.h" +#include "WorkQueue.h" +#include "WorkQueueItem.h" + +#include +#include +#include +#include "FindOptions.h" +#include +#include +#include + +#include +#include +#include +#include + +// Same as Mac cache model enum in Source/WebKit/mac/WebView/WebPreferences.h. +enum { + WebCacheModelDocumentViewer = 0, + WebCacheModelDocumentBrowser = 1, + WebCacheModelPrimaryWebBrowser = 2 +}; + +extern BWebView* webView; + +TestRunner::~TestRunner() +{ +} + +JSContextRef TestRunner::mainFrameJSContext() +{ + notImplemented(); + return nullptr; +} + +void TestRunner::addDisallowedURL(JSStringRef) +{ + notImplemented(); +} + +void TestRunner::clearBackForwardList() +{ + notImplemented(); +} + +JSRetainPtr TestRunner::copyDecodedHostName(JSStringRef) +{ + notImplemented(); + return 0; +} + +JSRetainPtr TestRunner::copyEncodedHostName(JSStringRef) +{ + notImplemented(); + return 0; +} + +void TestRunner::dispatchPendingLoadRequests() +{ + // FIXME: Implement for testing fix for 6727495 + notImplemented(); +} + +void TestRunner::display() +{ + notImplemented(); + //displayWebView(); +} + +void TestRunner::displayAndTrackRepaints() +{ + notImplemented(); + //displayWebView(); +} + +void TestRunner::keepWebHistory() +{ + WebCore::DumpRenderTreeClient::setShouldTrackVisitedLinks(true); +} + +size_t TestRunner::webHistoryItemCount() +{ + notImplemented(); + return -1; +} + +void TestRunner::notifyDone() +{ + if (m_waitToDump && !topLoadingFrame && !DRT::WorkQueue::singleton().count()) + dump(); + m_waitToDump = false; + waitForPolicy = false; +} + +void TestRunner::forceImmediateCompletion() +{ + // Same as on mac. This can be shared. + if (m_waitToDump && !DRT::WorkQueue::singleton().count()) + dump(); + m_waitToDump = false; +} + +JSRetainPtr TestRunner::pathToLocalResource(JSContextRef context, JSStringRef url) +{ + String requestedUrl(url->characters(), url->length()); + String resourceRoot; + String requestedRoot; + + if (requestedUrl.find("LayoutTests") != notFound) { + // If the URL contains LayoutTests we need to remap that to + // LOCAL_RESOURCE_ROOT which is the path of the LayoutTests directory + // within the WebKit source tree. + requestedRoot = "/tmp/LayoutTests"; + resourceRoot = getenv("LOCAL_RESOURCE_ROOT"); + } else if (requestedUrl.find("tmp") != notFound) { + // If the URL is a child of /tmp we need to convert it to be a child + // DUMPRENDERTREE_TEMP replace tmp with DUMPRENDERTREE_TEMP + requestedRoot = "/tmp"; + resourceRoot = getenv("DUMPRENDERTREE_TEMP"); + } + + size_t indexOfRootStart = requestedUrl.reverseFind(requestedRoot); + size_t indexOfSeparatorAfterRoot = indexOfRootStart + requestedRoot.length(); + String fullPathToUrl = "file://" + resourceRoot + requestedUrl.substring(indexOfSeparatorAfterRoot); + + return JSStringCreateWithUTF8CString(fullPathToUrl.utf8().data()); +} + +void TestRunner::queueLoad(JSStringRef url, JSStringRef target) +{ + notImplemented(); +} + +void TestRunner::setAcceptsEditing(bool acceptsEditing) +{ + notImplemented(); +} + +void TestRunner::setAlwaysAcceptCookies(bool alwaysAcceptCookies) +{ + notImplemented(); +} + +void TestRunner::setOnlyAcceptFirstPartyCookies(bool onlyAcceptFirstPartyCookies) +{ + // FIXME: Implement. + fprintf(testResult, "ERROR: TestRunner::setOnlyAcceptFirstPartyCookies() not implemented\n"); +} + +void TestRunner::setCustomPolicyDelegate(bool enabled, bool permissive) +{ + notImplemented(); +} + +void TestRunner::waitForPolicyDelegate() +{ + setCustomPolicyDelegate(true, false); + waitForPolicy = true; + setWaitToDump(true); +} + +void TestRunner::setScrollbarPolicy(JSStringRef, JSStringRef) +{ + notImplemented(); +} + +void TestRunner::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains) +{ + notImplemented(); +} + +void TestRunner::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef protocol, JSStringRef host, bool includeSubdomains) +{ + notImplemented(); +} + +void TestRunner::setMainFrameIsFirstResponder(bool) +{ + notImplemented(); +} + +void TestRunner::setTabKeyCyclesThroughElements(bool) +{ + notImplemented(); +} + +static CString gUserStyleSheet; +static bool gUserStyleSheetEnabled = true; + +void TestRunner::setUserStyleSheetEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::setUserStyleSheetLocation(JSStringRef path) +{ + gUserStyleSheet = path->string().utf8(); + + if (gUserStyleSheetEnabled) + setUserStyleSheetEnabled(true); +} + +void TestRunner::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value) +{ + WebCore::DumpRenderTreeClient::setValueForUser(context, nodeObject, value->string()); +} + +void TestRunner::setWindowIsKey(bool) +{ + notImplemented(); +} + +void TestRunner::setViewSize(double width, double height) +{ + notImplemented(); +} + +void watchdogFired() +{ + delete waitToDumpWatchdog; + waitToDumpWatchdog = NULL; + gTestRunner->waitToDumpWatchdogTimerFired(); +} + +void TestRunner::setWaitToDump(bool waitUntilDone) +{ + m_waitToDump = waitUntilDone; + + if (m_waitToDump && shouldSetWaitToDumpWatchdog()) { + BMessage message('dwdg'); + waitToDumpWatchdog = new BMessageRunner(be_app, &message, 30000000, 1); + } +} + +int TestRunner::windowCount() +{ + return be_app->CountWindows(); +} + +void TestRunner::setPrivateBrowsingEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::setJavaScriptCanAccessClipboard(bool flag) +{ + notImplemented(); +} + +void TestRunner::setXSSAuditorEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::setSpatialNavigationEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::setAllowUniversalAccessFromFileURLs(bool flag) +{ + notImplemented(); +} + +void TestRunner::setAllowFileAccessFromFileURLs(bool flag) +{ + notImplemented(); +} + +void TestRunner::setNeedsStorageAccessFromFileURLsQuirk(bool needsQuirk) +{ + notImplemented(); +} + +void TestRunner::setAuthorAndUserStylesEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::setMockDeviceOrientation(bool, double, bool, double, bool, double) +{ + // FIXME: Implement for DeviceOrientation layout tests. + // See https://bugs.webkit.org/show_bug.cgi?id=30335. + notImplemented(); +} + +void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message) +{ + notImplemented(); +} + +void TestRunner::setGeolocationPermission(bool allow) +{ + notImplemented(); +} + +void TestRunner::setMockGeolocationPosition(double, double, double, bool, double, bool, double, bool, double, bool, double, bool, double) +{ + notImplemented(); +} + +int TestRunner::numberOfPendingGeolocationPermissionRequests() +{ + // FIXME: Implement for Geolocation layout tests. + printf("ERROR: TestRunner::numberOfPendingGeolocationPermissionRequests() not implemented\n"); + return -1; +} + +bool TestRunner::isGeolocationProviderActive() +{ + // FIXME: Implement for Geolocation layout tests. + printf("ERROR: TestRunner::isGeolocationProviderActive() not implemented\n"); + return false; +} + +void TestRunner::setIconDatabaseEnabled(bool enabled) +{ + notImplemented(); +} + +void TestRunner::setPopupBlockingEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::setPluginsEnabled(bool flag) +{ + notImplemented(); +} + +void TestRunner::execCommand(JSStringRef name, JSStringRef value) +{ + WebCore::DumpRenderTreeClient::executeCoreCommandByName(webView, name->string(), value->string()); +} + +bool TestRunner::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray) +{ + notImplemented(); + return false; +} + +bool TestRunner::isCommandEnabled(JSStringRef name) +{ + notImplemented(); + return false; +} + +void TestRunner::setCacheModel(int cacheModel) +{ + notImplemented(); +} + +void TestRunner::setPersistentUserStyleSheetLocation(JSStringRef) +{ + notImplemented(); +} + +void TestRunner::clearPersistentUserStyleSheet() +{ + notImplemented(); +} + +void TestRunner::clearAllApplicationCaches() +{ + notImplemented(); +} + +void TestRunner::clearApplicationCacheForOrigin(OpaqueJSString* url) +{ + notImplemented(); +} + +JSValueRef TestRunner::originsWithApplicationCache(JSContextRef context) +{ + // FIXME: Implement to get origins that contain application caches. + notImplemented(); + return JSValueMakeUndefined(context); +} + +long long TestRunner::applicationCacheDiskUsageForOrigin(JSStringRef) +{ + notImplemented(); + return 0; +} + +void TestRunner::clearAllDatabases() +{ + notImplemented(); +} + +void TestRunner::setIDBPerOriginQuota(uint64_t quota) +{ + notImplemented(); +} + +void TestRunner::setDatabaseQuota(unsigned long long quota) +{ + notImplemented(); +} + +void TestRunner::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme) +{ + WebCore::DumpRenderTreeClient::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme->string()); +} + +void TestRunner::goBack() +{ + notImplemented(); +} + +void TestRunner::setDefersLoading(bool defers) +{ + notImplemented(); +} + +void TestRunner::setAppCacheMaximumSize(unsigned long long size) +{ + notImplemented(); +} + +static inline bool toBool(JSStringRef value) +{ + return equals(value, "true") || equals(value, "1"); +} + +static inline int toInt(JSStringRef value) +{ + return atoi(value->string().utf8().data()); +} + +void TestRunner::overridePreference(JSStringRef key, JSStringRef value) +{ + if (equals(key, "WebKitAcceleratedCompositingEnabled")) + notImplemented(); + else if (equals(key, "WebKitCSSCustomFilterEnabled")) + notImplemented(); + else if (equals(key, "WebKitCSSGridLayoutEnabled")) + notImplemented(); + else if (equals(key, "WebKitCSSRegionsEnabled")) + notImplemented(); + else if (equals(key, "WebKitDefaultFontSize")) + notImplemented(); + else if (equals(key, "WebKitDisplayImagesKey")) + notImplemented(); + else if (equals(key, "WebKitEnableCaretBrowsing")) + notImplemented(); + else if (equals(key, "WebKitJavaEnabled")) + notImplemented(); + else if (equals(key, "WebKitJavaScriptEnabled")) + notImplemented(); + else if (equals(key, "WebKitPageCacheSupportsPluginsPreferenceKey")) + notImplemented(); + else if (equals(key, "WebKitShouldRespectImageOrientation")) + notImplemented(); + else if (equals(key, "WebKitSupportsMultipleWindows")) + notImplemented(); + else if (equals(key, "WebKitTabToLinksPreferenceKey")) + notImplemented(); + else if (equals(key, "WebKitUsePreHTML5ParserQuirks")) + notImplemented(); + else if (equals(key, "WebKitUsesPageCachePreferenceKey")) + notImplemented(); + else if (equals(key, "WebKitWebAudioEnabled")) + notImplemented(); + else if (equals(key, "WebKitWebGLEnabled")) + notImplemented(); + else + fprintf(stderr, "TestRunner::overridePreference tried to override unknown preference '%s'.\n", key->string().utf8().data()); +} + +void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) +{ + WebCore::DumpRenderTreeClient::addUserScript(webView, source->string(), + runAtStart, allFrames); +} + +void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames) +{ + notImplemented(); +} + +void TestRunner::setDeveloperExtrasEnabled(bool enabled) +{ + webView->WebPage()->SetDeveloperExtrasEnabled(enabled); +} + +void TestRunner::showWebInspector() +{ + notImplemented(); +} + +void TestRunner::closeWebInspector() +{ + notImplemented(); +} + +void TestRunner::evaluateInWebInspector(JSStringRef script) +{ + notImplemented(); +} + +JSRetainPtr TestRunner::inspectorTestStubURL() +{ + notImplemented(); + return nullptr; +} + +void TestRunner::evaluateScriptInIsolatedWorldAndReturnValue(unsigned, JSObjectRef, JSStringRef) +{ + notImplemented(); +} + +void TestRunner::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script) +{ + notImplemented(); +} + +void TestRunner::removeAllVisitedLinks() +{ + notImplemented(); +} + +bool TestRunner::callShouldCloseOnWebView() +{ + notImplemented(); +} + +void TestRunner::apiTestNewWindowDataLoadBaseURL(JSStringRef, JSStringRef) +{ + notImplemented(); +} + +void TestRunner::apiTestGoToCurrentBackForwardItem() +{ + notImplemented(); +} + +void TestRunner::setWebViewEditable(bool) +{ + notImplemented(); +} + +void TestRunner::authenticateSession(JSStringRef, JSStringRef, JSStringRef) +{ + notImplemented(); +} + +void TestRunner::abortModal() +{ + notImplemented(); +} + +void TestRunner::setSerializeHTTPLoads(bool serialize) +{ + WebCore::DumpRenderTreeClient::setSerializeHTTPLoads(serialize); +} + +void TestRunner::setTextDirection(JSStringRef direction) +{ + notImplemented(); +} + +void TestRunner::addChromeInputField() +{ + notImplemented(); +} + +void TestRunner::removeChromeInputField() +{ + notImplemented(); +} + +void TestRunner::focusWebView() +{ + notImplemented(); +} + +void TestRunner::setBackingScaleFactor(double) +{ + notImplemented(); +} + +void TestRunner::grantWebNotificationPermission(JSStringRef origin) +{ +} + +void TestRunner::denyWebNotificationPermission(JSStringRef jsOrigin) +{ +} + +void TestRunner::removeAllWebNotificationPermissions() +{ +} + +void TestRunner::simulateWebNotificationClick(JSValueRef jsNotification) +{ +} + +void TestRunner::simulateLegacyWebNotificationClick(JSStringRef title) +{ +} + +unsigned TestRunner::imageCountInGeneralPasteboard() const +{ + printf("ERROR: TestRunner::imageCountInGeneralPasteboard() not implemented\n"); + return 0; +} + +void TestRunner::setSpellCheckerLoggingEnabled(bool enabled) +{ + printf("ERROR: TestRunner::setSpellCheckerLoggingEnabled() not implemented\n"); +} + +void TestRunner::setSpellCheckerResults(JSContextRef, JSObjectRef) +{ + fprintf(testResult, "ERROR: TestRunner::setSpellCheckerResults() not implemented\n"); +} + +void TestRunner::resetPageVisibility() +{ + notImplemented(); +} + +void TestRunner::setPageVisibility(const char* visibility) +{ + notImplemented(); +} + +void TestRunner::setAutomaticLinkDetectionEnabled(bool) +{ + notImplemented(); +} + +void TestRunner::setStorageDatabaseIdleInterval(double) +{ + notImplemented(); +} + +void TestRunner::closeIdleLocalStorageDatabases() +{ + notImplemented(); +} + diff --git a/Tools/DumpRenderTree/haiku/WorkQueueItemHaiku.cpp b/Tools/DumpRenderTree/haiku/WorkQueueItemHaiku.cpp new file mode 100644 index 000000000000..45ddcfa36a29 --- /dev/null +++ b/Tools/DumpRenderTree/haiku/WorkQueueItemHaiku.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008 Kevin Ollivier + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WorkQueueItem.h" + +#include "DumpRenderTree.h" +#include "NotImplemented.h" + +bool LoadItem::invoke() const +{ + notImplemented(); + return false; +} + +bool LoadHTMLStringItem::invoke() const +{ + notImplemented(); + return true; +} + +bool ReloadItem::invoke() const +{ + notImplemented(); + return false; +} + +bool ScriptItem::invoke() const +{ + notImplemented(); + return false; +} + +bool BackForwardItem::invoke() const +{ + notImplemented(); + return false; +} diff --git a/Tools/HaikuLauncher/AuthenticationPanel.cpp b/Tools/HaikuLauncher/AuthenticationPanel.cpp new file mode 100644 index 000000000000..7b08c6bba869 --- /dev/null +++ b/Tools/HaikuLauncher/AuthenticationPanel.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. Distributed under the terms of the MIT License. + */ +#include "AuthenticationPanel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const uint32 kMsgPanelOK = 'pnok'; +static const uint32 kMsgJitter = 'jitr'; +static const uint32 kHidePassword = 'hdpw'; + +#define B_TRANSLATE(x) x + +AuthenticationPanel::AuthenticationPanel(BRect parentFrame) + : + BWindow(BRect(-1000, -1000, -900, -900), + B_TRANSLATE("Authentication required"), B_TITLED_WINDOW_LOOK, + B_MODAL_APP_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE + | B_NOT_ZOOMABLE | B_CLOSE_ON_ESCAPE | B_AUTO_UPDATE_SIZE_LIMITS), + m_parentWindowFrame(parentFrame), + m_usernameTextControl(new BTextControl("user", B_TRANSLATE("Username:"), + "", NULL)), + m_passwordTextControl(new BTextControl("pass", B_TRANSLATE("Password:"), + "", NULL)), + m_hidePasswordCheckBox(new BCheckBox("hide", B_TRANSLATE("Hide password " + "text"), new BMessage(kHidePassword))), + m_rememberCredentialsCheckBox(new BCheckBox("remember", + B_TRANSLATE("Remember username and password for this site"), NULL)), + m_okButton(new BButton("ok", B_TRANSLATE("OK"), + new BMessage(kMsgPanelOK))), + m_cancelButton(new BButton("cancel", B_TRANSLATE("Cancel"), + new BMessage(B_QUIT_REQUESTED))), + m_cancelled(false), + m_exitSemaphore(create_sem(0, "Authentication Panel")) +{ +} + + +AuthenticationPanel::~AuthenticationPanel() +{ + delete_sem(m_exitSemaphore); +} + + +bool +AuthenticationPanel::QuitRequested() +{ + m_cancelled = true; + release_sem(m_exitSemaphore); + return false; +} + + +void +AuthenticationPanel::MessageReceived(BMessage* message) +{ + switch (message->what) { + case kMsgPanelOK: + release_sem(m_exitSemaphore); + break; + case kHidePassword: { + // TODO: Toggling this is broken in BTextView. Workaround is to + // set the text and selection again. + BString text = m_passwordTextControl->Text(); + int32 selectionStart; + int32 selectionEnd; + m_passwordTextControl->TextView()->GetSelection(&selectionStart, + &selectionEnd); + m_passwordTextControl->TextView()->HideTyping( + m_hidePasswordCheckBox->Value() == B_CONTROL_ON); + m_passwordTextControl->SetText(text.String()); + m_passwordTextControl->TextView()->Select(selectionStart, + selectionEnd); + break; + } + case kMsgJitter: { + UpdateIfNeeded(); + BPoint leftTop = Frame().LeftTop(); + const float jitterOffsets[] = { -10, 0, 10, 0 }; + const int32 jitterOffsetCount = sizeof(jitterOffsets) / sizeof(float); + for (int32 i = 0; i < 20; i++) { + float offset = jitterOffsets[i % jitterOffsetCount]; + MoveTo(leftTop.x + offset, leftTop.y); + snooze(15000); + } + MoveTo(leftTop); + break; + } + default: + BWindow::MessageReceived(message); + } +} + + +bool AuthenticationPanel::getAuthentication(const BString& text, + const BString& previousUser, const BString& previousPass, + bool previousRememberCredentials, bool badPassword, + BString& user, BString& pass, bool* rememberCredentials) +{ + // Configure panel and layout controls. + rgb_color infoColor = ui_color(B_PANEL_TEXT_COLOR); + BRect textBounds(0, 0, 250, 200); + BTextView* textView = new BTextView(textBounds, "text", textBounds, + be_plain_font, &infoColor, B_FOLLOW_NONE, B_WILL_DRAW + | B_SUPPORTS_LAYOUT); + textView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + textView->SetText(text.String()); + textView->MakeEditable(false); + textView->MakeSelectable(false); + + m_usernameTextControl->SetText(previousUser.String()); + m_passwordTextControl->TextView()->HideTyping(true); + // Ignore the previous password, if it didn't work. + if (!badPassword) + m_passwordTextControl->SetText(previousPass.String()); + m_hidePasswordCheckBox->SetValue(B_CONTROL_ON); + m_rememberCredentialsCheckBox->SetValue(previousRememberCredentials); + + // create layout + SetLayout(new BGroupLayout(B_VERTICAL, 0.0)); + float spacing = be_control_look->DefaultItemSpacing(); + AddChild(BGroupLayoutBuilder(B_VERTICAL, 0.0) + .Add(BGridLayoutBuilder(0, spacing) + .Add(textView, 0, 0, 2) + .Add(m_usernameTextControl->CreateLabelLayoutItem(), 0, 1) + .Add(m_usernameTextControl->CreateTextViewLayoutItem(), 1, 1) + .Add(m_passwordTextControl->CreateLabelLayoutItem(), 0, 2) + .Add(m_passwordTextControl->CreateTextViewLayoutItem(), 1, 2) + .Add(BSpaceLayoutItem::CreateGlue(), 0, 3) + .Add(m_hidePasswordCheckBox, 1, 3) + .Add(m_rememberCredentialsCheckBox, 0, 4, 2) + .SetInsets(spacing, spacing, spacing, spacing) + ) + .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) + .Add(BGroupLayoutBuilder(B_HORIZONTAL, spacing) + .AddGlue() + .Add(m_cancelButton) + .Add(m_okButton) + .SetInsets(spacing, spacing, spacing, spacing) + ) + ); + + float textHeight = textView->LineHeight(0) * textView->CountLines(); + textView->SetExplicitMinSize(BSize(B_SIZE_UNSET, textHeight)); + + SetDefaultButton(m_okButton); + if (badPassword && previousUser.Length()) + m_passwordTextControl->MakeFocus(true); + else + m_usernameTextControl->MakeFocus(true); + + if (m_parentWindowFrame.IsValid()) + CenterIn(m_parentWindowFrame); + else + CenterOnScreen(); + + // Start AuthenticationPanel window thread + Show(); + + // Let the window jitter, if the previous password was invalid + if (badPassword) + PostMessage(kMsgJitter); + + // Block calling thread + // Get the originating window, if it exists, to let it redraw itself. + BWindow* window = dynamic_cast + (BLooper::LooperForThread(find_thread(NULL))); + if (window) { + status_t err; + for (;;) { + do { + err = acquire_sem_etc(m_exitSemaphore, 1, B_RELATIVE_TIMEOUT, + 10000); + // We've (probably) had our time slice taken away from us + } while (err == B_INTERRUPTED); + + if (err != B_TIMED_OUT) { + // Semaphore was finally released or nuked. + break; + } + window->UpdateIfNeeded(); + } + } else { + // No window to update, so just hang out until we're done. + while (acquire_sem(m_exitSemaphore) == B_INTERRUPTED) { + } + } + + // AuthenticationPanel wants to quit. + Lock(); + + user = m_usernameTextControl->Text(); + pass = m_passwordTextControl->Text(); + if (rememberCredentials) + *rememberCredentials = m_rememberCredentialsCheckBox->Value() + == B_CONTROL_ON; + + bool canceled = m_cancelled; + Quit(); + // AuthenticationPanel object is TOAST here. + return !canceled; +} diff --git a/Tools/HaikuLauncher/AuthenticationPanel.h b/Tools/HaikuLauncher/AuthenticationPanel.h new file mode 100644 index 000000000000..cb8b91410b4a --- /dev/null +++ b/Tools/HaikuLauncher/AuthenticationPanel.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. Distributed under the terms of the MIT License. + */ +#ifndef AuthenticationPanel_h +#define AuthenticationPanel_h + +#include +#include + +class BCheckBox; +class BTextControl; + +class AuthenticationPanel : public BWindow { +public: + AuthenticationPanel(BRect parentFrame = BRect()); + virtual ~AuthenticationPanel(); + + virtual bool QuitRequested(); + + virtual void MessageReceived(BMessage *message); + + bool getAuthentication(const BString& text, const BString& previousUser, + const BString& previousPass, bool previousRememberCredentials, + bool badPassword, BString& user, BString& pass, + bool* rememberCredentials); + +private: + BRect m_parentWindowFrame; + BTextControl* m_usernameTextControl; + BTextControl* m_passwordTextControl; + BCheckBox* m_hidePasswordCheckBox; + BCheckBox* m_rememberCredentialsCheckBox; + BButton* m_okButton; + BButton* m_cancelButton; + + bool m_cancelled; + + sem_id m_exitSemaphore; +}; + +#endif // AuthenticationPanel_h diff --git a/Tools/HaikuLauncher/CMakeLists.txt b/Tools/HaikuLauncher/CMakeLists.txt new file mode 100644 index 000000000000..b2c675783d03 --- /dev/null +++ b/Tools/HaikuLauncher/CMakeLists.txt @@ -0,0 +1,24 @@ +SET(HaikuLauncher_SOURCES + ${TOOLS_DIR}/HaikuLauncher/LauncherApp.cpp + ${TOOLS_DIR}/HaikuLauncher/LauncherWindow.cpp + ${TOOLS_DIR}/HaikuLauncher/AuthenticationPanel.cpp +) + +SET(HaikuLauncher_LIBRARIES + JavaScriptCore + WebCore + WebKitLegacy + ${LIBXML2_LIBRARIES} + ${LIBXSLT_LIBRARIES} + ${SQLITE_LIBRARIES} + ${ICU_I18N_LIBRARIES} + ${ICU_LIBRARIES} + be bsd network stdc++ translation tracker +) + +INCLUDE_DIRECTORIES("${WEBKITLEGACY_DIR}/haiku/API") + +ADD_EXECUTABLE(HaikuLauncher ${HaikuLauncher_SOURCES}) +TARGET_LINK_LIBRARIES(HaikuLauncher ${HaikuLauncher_LIBRARIES}) +SET_TARGET_PROPERTIES(HaikuLauncher PROPERTIES FOLDER "Tools") +SET_TARGET_PROPERTIES(HaikuLauncher PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") diff --git a/Tools/HaikuLauncher/Launcher.rdef b/Tools/HaikuLauncher/Launcher.rdef new file mode 100644 index 000000000000..3165079460ea --- /dev/null +++ b/Tools/HaikuLauncher/Launcher.rdef @@ -0,0 +1,254 @@ +resource app_signature "application/x-vnd.RJL-HaikuLauncher"; + +resource app_version { + major = 0, + middle = 0, + minor = 1, + variety = B_APPV_ALPHA, + internal = 0, + short_info = "HaikuLauncher", + long_info = "HaikuLauncher ©2007-2010 The WebKit Haiku Project" +}; + +resource app_flags B_SINGLE_LAUNCH; + +resource file_types message { + "types" = "text/html", + "types" = "image/gif", + "types" = "image/jpeg", + "types" = "image/png", + "types" = "application/x-vnd.Be-bookmark", + "types" = "text", + "types" = "application/x-vnd.Be-doc_bookmark", + "types" = "application/x-vnd.Be.URL.file", + "types" = "application/x-vnd.Be.URL.ftp", + "types" = "application/x-vnd.Be.URL.http", + "types" = "application/x-vnd.Be.URL.https" +}; + +resource vector_icon { + $"6E636966450500020106033D0AFE000000000000BD0AFE48F10748A0783133FF" + $"FFC80066FFFF0034CC020106033D0AFE000000000000BD0AFE48F10748A07854" + $"09B4B6D8033784FF051D61020106043D950B0000000000003D950B494FBC479B" + $"EC00FFFFFF4C00FF008F00B200FF008000050002030605B812A5BE03E13DE784" + $"B8021049F79F49EDD800F1F1F136D9DDF48A9996B9B4B8BEDBFFF4F4F404EBD0" + $"020006023C92C0388F5FB854503C576348D8DF48895B004137A9FFB9B9B90401" + $"7E03FF360003FFFF0003FF9C0003FF000002010202BB36AEBA1760B80FFF392B" + $"574ACCFB48652300000001FFFF0000013205400500020004024AFFFC00FFFFBA" + $"360500020106033D0AFE000000000000BD0AFE48F10748A0783133FFFFC80066" + $"FFFF0034CC020106023D0AFE000000000000BD0AFE48F10748A0780033FFFFFF" + $"0033CC020106023D0AFE000000000000BD0AFE48F10748A0780033FFFFFF0066" + $"FF020004027AFFFC00DDFFBA360201040289FF0000A9C000000200040200FFE5" + $"CED0ECB989020004020DEFBC8CFFD4AA820200040200FFCB9CE9ECB989020004" + $"0200FFCB9CE9ECB98902000402B3FFCB9CBBD4AA820500020106033D0AFE0000" + $"00000000BD0AFE48F10748A0783133FFFFC80066FFFF0034CC020106033D0AFE" + $"000000000000BD0AFE48F10748A0785409B4B6D8033784FF051D61020106043D" + $"950B0000000000003D950B494FBC479BEC00FFFFFF4C00FF008F00B200FF0080" + $"00050002030605B812A5BE03E13DE784B8021049F79F49EDD800F1F1F136D9DD" + $"F48A9996B9B4B8BEDBFFF4F4F404EBD0020006023C92C0388F5FB854503C5763" + $"48D8DF48895B004137A9FFB9B9B904017E03FF360003FFFF000200040200FFBC" + $"34FFFF9C0003FF000002010202BB36AEBA1760B80FFF392B574ACCFB48652300" + $"000001FFFF00000132054003FFFFC9020014020026FF1C0500050002030605B8" + $"12A5BE03E13DE784B8021049F79F49EDD800F1F1F136D9DDF48A9996B9B4B8BE" + $"DBFFF4F4F404EBD0020006023C92C0388F5FB854503C576348D8DF48895B0041" + $"37A9FFB9B9B904017E03FF360003FFFF0003FF9C0003FF000002010202BB36AE" + $"BA1760B80FFF392B574ACCFB48652300000001FFFF0000013205400500030052" + $"7502001002F8006BFF003E04006C050003900000020310020000006E00650400" + $"6B05000359463503C3A414039D816035000000000204BFC2B55BBBC5B55BC3BF" + $"B55BC6FABC93C6FAB896C6FAC090BFC2C3CBC3BFC3CBBBC5C3CBB88ABC93B88A" + $"C090B88AB896026EC5DCB8B6C713BAA0C4CAB706C110B579C307B5D5C0A2B565" + $"BFC2B55BC032B55BBDBCB55BBA69B7BABBC5B63AB8F9B94FB89DBD9CB84FBB7E" + $"B8C7BE9AB924BF77B8E0BEE7B9DEC11FBCE0C332BB38C279BEC5C405C2D8C31A" + $"C0FBC3FCC2C6C2C1C22FC2B7C27AC2BEC22FC2B7C227C2B7C227C2B7C227C2B7" + $"C241C2BDC241C2BDC206C2B0C199C2DBC1D0C2CBC159C2EEC0D4C2DDC115C2E5" + $"C051C2CEBF43C313BFB0C2B4BF3DC313BF36C313BF36C313BF36C313BF20C313" + $"BF20C313BF20C313BDEDC313BE23C313BDB9C2EDBD57C2DFBD87C2E3BD54C2DC" + $"BD3EC2C3BD3EC2C3BD31C2B4BD13C2A5BD26C2ABBD13C2A5BCA4C27EBCA4C27E" + $"BCA4C27EBC31C254BC31C254BC27C251BC12C24FBC1DC250BC10C24BBC0FC242" + $"BC11C246BC0FC242BBF5C219BBF5C219BBD3C1DEBB68C195BBAEC1A4BB71C16E" + $"BB58C129BB63C14EBB4BC101BB4BC0ADBB48C0D7BB4BC0ADBB4EC087BB4EC087" + $"BB52C054BB4DBFEEBB55C021BB9EBF93BBA9BEBFBBB0BF36BBA9BEBFBBA7BE93" + $"BBA7BE93BBA7BE53BBBCBE2FBBA8BE4BBBBCBE2FBBC7BE21BBC7BE21BC00BDD5" + $"BBE3BCFCBC5BBD3DBBE3BCFCBAB7BC58BAB7BC58BAB7BC58BA8BBC44BA90BC46" + $"BA8BBC44BA8BBC42BA8BBC42BA89BBEABA23BB79BA6ABBADBA23BB79BA12BB6B" + $"BA12BB6BBA12BB6BB9F8BB49B9F8BB49B9F8BB49B9AEBAF0B9AEBAF0B97EBAC3" + $"B928BAB1B950BAB5B924BAA9B91BBA9AB920BAA1B984BA6EB9DEB997B9B5B9F9" + $"B9F6B95DBA36B8F0BA0BB91FBA5EB8C4BA78B85EBA83B89EBACCB83DBB61B7E7" + $"BB18B813BB61B7E7BB6BB7E1BB6BB7E1BB6BB7E1BBFEB787BBFEB787BC65B74A" + $"BCB6B684BC94B6F6BCF5B68ABD58B665BD2DB67BBDA8B695BE6DB651BE29B697" + $"BE6FB650BE88B64FBE7CB64FBE62B6A0BEE1B72FBE88B70EBEE4B733BEE9B73E" + $"BEE5B73ABED8B744BEC6B74ABEC6B74ABEC6B74ABE75B7A5BE75B7A5BE63B7DD" + $"BE90B849BE74B817BE91B84CBE92B852BE92B852BE94B85CBE9DB87ABE97B86B" + $"BE94B884BE8CB88DBE8CB88DBE3AB8F0BD92B98FBDB7B906BD92B98FBD8DB9A1" + $"BD8DB9A1BD64B9D8BD7EBA55BD59BA19BD7BBA5CBD77BA63BD77BA63BD56BAA0" + $"BD4DBB2CBD39BAE6BD60BB70BDCCBBCEBD98BBA2BDFFBBFABE73BC3FBE33BC27" + $"BEBEBC5CBF5EBC42BF12BC56BF5EBC42BFAC37BFAC37BFD0BC1EC01CBC0FBFF5" + $"BC0BC046BC14C083BC4EC066BC35C04DBCD9C0F4BDDAC0B6BD63C0F4BDDAC107" + $"BDF9C102BDF2C0BABE84C127BF91C0B2BF1DC127BF91C133BF9DC133BF9DC131" + $"C00FC1C5C0F9C135C0D6C259C11CC348C059C2EEC0C9C348C059C36BC02FC36B" + $"C02FC36BC02FC388C019C388C019C3A8C003C3DBBFC5C3C9BFE8C3EEBFA0C409" + $"BF52C3F0BF73C409BF52C409BF53C409BF53C40DBF9AC495BFC1C450BFCEC4EB" + $"BFB3C542BF10C51FBF56C542BF10C551BEF2C551BEF2C551BEF2C555BEEBC555" + $"BEEBC57FBEA3C568BDFCC59EBE47C53ABDBBC4A3BDDFC4E1BDAAC4A3BDCAC4A3" + $"BDB5C4A3BDB5C4A3BDB5C4A5BD31C4A5BD31C4A8BD1EC4E8BCDFC4D2BCF5C4E8" + $"BCDFC4FEBCC9C4FEBCC9C4FEBCC9C516BCB3C516BCB3C545BC8BC582BC20C571" + $"BC5EC58CBC05C588BBBCC586BBD9C588BBBCC587BBA8C587BBA8C587BBA8C588" + $"BB9DC588BB9DC58DBB614EBAFAC584BB24C58ABADAC5C2BA5DC5B0BAA2C5C4BA" + $"62C5CBBA70C5CBBA70C5D9BA8EC60FBAD4C5EDBAB3C60ABB1FC648BBAAC627BB" + $"67C669BBEBC66FBC7BC670BC33C66FBC7BC672BCC4C672BCC4C674BCEAC66EBD" + $"37C678BD11C664BD5AC649BD9CC652BD79C633BDECC62CBE92C62DBE3FC621BE" + $"D5C67FBF2CC648BF16C750BD0F0006BC12B6E4BC12B6E4BC32B6B0BC55B638BC" + $"47B674BB81B6ABBA2BB802BAC4B747BA88B7E3BB30B77EBADDB7B0BB59B765BB" + $"AAB733BB82B74DBBCBB71DBC12B6E4BBFCB707BC12B6E4001DBACDBFD1BACDBF" + $"D1BAEBBFAABB29BF5CBB13BF89BB43BF24BB34BE93BB34BED0BB34BE4DBB60BD" + $"EABB34BE25BB80BDBEBBABBD60BBA1BD98BB48BD2ABA81BCBEBAE5BCF3BA67BC" + $"B1BA20BC83BA2DBCA0BA0FBC5BBA0DBC02BA1FBC28B9FEBBE5B9BABBB6B9D0BB" + $"D0B99BBB91B95FBB44B983BB66B93DBB24B8F0BB2DB91CBB16B8C0BB48B8BEBA" + $"DFB8C3BAFFB8B1BB14B89FBB7EB8A7BB49B8C9BB7EB8C5BBB2B8C3BB8AB8C6BB" + $"DBB8C9BC2EB8C7BC05B8D0BC40B8BABC49B8CBBC49B8B4BC4BB8AABC4EB8AFBC" + $"4DB8A0BC57B893BC4BB898BC56B882BC4AB88FBD10B88EBD00B893BD49B8E1BD" + $"E7B88DBE03B90DBE04B923BE75B906BE4BB946BEA8B985BF00B973BEC1B997BF" + $"3EB9A3BFC1B998BF81B9B0C011BA17C05FB9DBC02EBA25C0B3BA75C127BA3DC0" + $"E7BA8FC144BAC0C17FBAA9C160BAD8C19FBAFCC17CBAE4C19DBADDC13ABAD7C0" + $"A6BAD3C0EFBADBC061BACDBFD1BAEAC013BACDBFD10009BD5EB5D7BD5EB5D7BD" + $"81B5EEBDB1B60EBD84B605BDD0B613BE19B601BE01B61ABE55B5C3BEF6B5C4BE" + $"B0B5EFBF2DB5A2BFA3B55EBF5BB55EBFCEB55DC00CB58CBFE9B578C03CB5A7C0" + $"90B566C064B575BF3AB541BCA7B60EBDDDB57ABCECB623BD5EB5D7BD29B601BD" + $"5EB5D70005BF35B6EABF35B6EABF55B6ECBF9AB6F5BF7BB702BFCEB6E0BF87B6" + $"7DBF9CB693BF78B66DBF3CB664BF2FB623BF45B690BF35B6EABF6BB6CCBF35B6" + $"EA0004BA07B87FBA07B87FBA0CB868B9EFB850B9FEB85FB982B8E4B8F0BA35B9" + $"2CB988B97E31BA07B87FB974B8F0BA07B87F0066C6F7BC24C6F7BC24C6DCBB0A" + $"C6002FC68BB9F2C5B9B87CC4FFB79CC563B805C4CEB768C463B709C49AB737C4" + $"52B6FBC428B6EFC440B6E2C412B6FAC407B6C1C401B6D1C316B60FC0D0B56FC1" + $"F9B59AC0FBB58BC15FB59CC131B589C170B5A2C179B5C9C19FB5BDC12DB5E2C0" + $"8AB5C9C0D7B5C4C05AB5CDC03FB60EC043B5DDC03DB629C040B676C036B65DC0" + $"4BB694C0B6B65FC0A8B66FC0CDB643C0F1B61AC0B1B608C108B64BC0D0B6B1C1" + $"3AB6D6C0B5B6A7C066B689C083B67CC064B68AC05DB6AFC05FB6ABC053B6C0C0" + $"31B6D0C044B6CBBFE6B6E5BF94B741BFB0B6EFBF87B769BF5DB791BF88B781BF" + $"3BB79DBEF7B7B2BF17B7A4BECCB7C7BEFAB81CBEEAB7FFBF06B830BF19B86CBF" + $"03B860BF59B891BFBEB7E0BFA3B802BFE1B7B3C038B7ADC008B7BDC04FB7A6C0" + $"84B777C06CB76EC0D3B795C0F8B83EC0EBB7F4C110B83FC135B810C100B802C1" + $"0DB7E5C0ECB77043B7ABC125B795C15FB7FDC14DB7BDC170B83DC1C2B820C18E" + $"B860C1CFB813C1FDB7D5C1E2B7BDC214B7EAC1F1B838C215B82FC206B84BC23A" + $"B83DC222B843C25AB834C28BB842C26CB836C2AFB850C2FAB857C2D5B854C320" + $"B859C347B898C335B87BC377B8E7C24AB8C5C259B8C6C228B8C3C1E2B8D0C202" + $"B8C2C1C9B8DAC199B8F0C1B62FC179B8E5C13FB8B6C15BB8C8C118B89CC0C5B8" + $"72C0EFB885C07FB853BFE3B84FC02FB83FBFBFB856BF7FB87CBF9CB866BF5CB8" + $"97BF11B8A4BF35B87FBEDCB8DCBE6EB942BEB6B91FBE51B950BE19B976BE2EB9" + $"5CBE04B990BDF6B9D1BE04B9B4BDE9B9EEBDE2BA1DBDCAB9FCBDF8BA3CBDEFBA" + $"76BDFEBA53BDD9BAA9BDC9BB27BD9FBAEFBDF235BE71BBBCBE3ABB94BEAFBBE9" + $"BF41BBD2BEFBBBE5BF83BBC1C009BB9CBFC5BBA1C05FBB96C0DDBC03C0A1BBCD" + $"C104BC26C0F5BC67C114BC34C0D3BC9FC103BD00C0E8BCC8C11FBD37C159BDA3" + $"C13CBD6DC166BDBAC182BDE8C177BDD0C18EBE04C16DBE2DC17BBE15C152BE5E" + $"C13FBECFC13FBE97C13FBF0EC185BF4CC15DBF24C1AABF71C1A4BFE3C1A8BFB3" + $"C1A0C025C1DBC087C1B3C053C216C08AC289C06CC253C086C2CBC04DC319BFDE" + $"C2E8C00FC347BFB0C386BF66C378BFABC396BF13C3FEBEBFC3C2BEF2C435BE90" + $"C430BE0CC42EBE4DC432BDC0C433BD22C429BD6DC43CBCDEC4ABBC78C47EBCA7" + $"C4CDBC56C512BC03C505BC34C519BBE7C513BBA8C51336C513BB93C51135C51A" + $"BB71C4F8BB29C47EBB2CC48ABB5DC476BB0EC48BBB01C477BB14C4A1BAEDC478" + $"BACDC48BBAD8C442BAADC3F1BA66C418BA9AC3CCBA36C391B9CBC3AEBA00C389" + $"B9BEC36CB93BC342B92EC39AB94AC3E2B9A3C3C4B981C419B9DFC46DBA6AC44A" + $"BA20C46EBA73C496BA8AC48FBA85C4AFBA9CC4EABAA8C4CABAABC533BAA2C55A" + $"BA20C555BA61C562B9C7C4E8B9AFC51DB9DAC4CAB997C49EB958C4B6B975C48F" + $"B946C474B90EC466B92AC493B8F9C4BDB91DC49FB90BC4E0B932C52CB951C505" + $"B944C555B95EC5B4B96CC592B952C5C9B97CC5E7B9B8C5D9B9A2C5FEB9DCC627" + $"BA26C614BA00C645BA61C694BA9FC64DBA89C667BAE8C6B6BB83C693BB3FC6DF" + $"BBD4C6E3BC7CC6E4BC23C6E2BCCEC6D0BD79C6F5BD2CC6A7BDCCC69FBE9AC69F" + $"BE3EC6A1BE95C6A5BE88C6A3BE8DC6A2BE8FC6A1BEC0C696BEBEC6B2BEC4C6D6" + $"BE02C6D2BE15C6F6BD65C6F7BC24C700BCC4C6F7BC240008C301B7D8C301B7D8" + $"C2E6B7DCC2D4B7A4C2E8B7AEC2B1B792C269B7B8C288B7A7C204B7EFC236B743" + $"C221B77BC239B73AC285B744C27AB746C2A7B740C2F3B74FC2D8B731C30CB76B" + $"C33CB7A1C31FB787C360B7C2C301B7D8C31CB7D4C301B7D80004BB53C203BB53" + $"C203BB45C20DBB26C221BB38C21DBB55C249BBBAC291BB87C26EBB92C265BB53" + $"C203BB84C227BB53C2030005C4F4BE2EC4F4BE2EC4D3BE57C48CBEA4C4A6BE76" + $"C46EBEDAC47DBF53C47DBF18C4B6BF38C4EDBEB9C4D0BEECC502BE93C4F4BE2E" + $"C531BE48C4F4BE2E0009C213C327C213C327C17FC390BFF7C345C09DC332BFD0" + $"C349BF8EC36ABFACC350BF67C38CBF20C386BF56C386BEAFC386BDCDC386BE3E" + $"C386BEC1C3CBC0C0C3BABFC4C3DDC137C3AAC221C367C1AFC38EC22AC364C262" + $"C32BC280C337C249C322C213C327C22AC331C213C32702024E284E2C542E4C32" + $"4C30482E020250304C3252344C364E344C340202C951B81858305C3254365432" + $"4E300202583456365836563C5A3854380204BCD6C1F1BACDC370BEA5C09BC4A7" + $"BFA6C361BE3CC67FC1B1C065C5ADC23AC445BE91C715B827C85DB962C9B9B682" + $"C68C0204C3CFC072C309BF46C522C2743DC65FC0DEC4E4BC10C7F7B880C76BB8" + $"DAC831B842C6E2BC70C2E3B880C5CDBE43C189061EAEE6BAEAAAAF9A0EB9E5C6" + $"DFB9CC50B985C673BA12C5CDBAE4C593BA9EC0BFBC89BE0E36B8E6B993B8DA2E" + $"B874B92DB971B7B0BCD6BA52BCEFB87ABE3BB7AEBD62B7AEBF13B7AEBF862EBF" + $"93BA78C0D2BB91C49BBB6AC51ABC10C51ABBB6C51ABC5AC49BBCB6C21DBCC3BF" + $"A0BDCEBFCCC18BC1FDC323BF00C13E46C33BC197C43B46C3DCC12BC484C02CC4" + $"94C012C3EFC092C36FBE21C2BDBF40BC50C14BBBF74EBB8451BBE8C66FBA9EC6" + $"B90611AAAAA8BA02BBF0B9ECBB4ABAB8BCC9BB9DBCE2BE4EBB71C019BC7CC0A5" + $"BE08BF73BE6144BFA0BF6DBDDBC06CBD0245BCAFC1CABC30BF40BAABBE0EBB04" + $"BF0DBB04BD83BB04BD15BAB8BCAFBA38060BBAAA2A31C653BA0CC6C5BB84C646" + $"BB2BC69FBBB6C614BBB0C5A0BBDDC309BC1DC164BCAFC0CBBB71BFE6BAD8C0CB" + $"BACBC395BAE4C5C6060AAAAB0ABE47C125BF99C131BF80454448C1FDC395C21D" + $"C362C1C4C3F1C11EC448C052C494C02CC3EFC105C389BE67470605EA02BB37BA" + $"C5BBD7BA12B9ACB887B8E0B8ADB90BB86AB887B939B920B96C0A05C16BBB91C4" + $"74BB91C4DABC36C4A7BCC3C16BBCE906078A2EBD4F2EBDB5B814BEA7BF402EBF" + $"4DBA45BE0EBB04BEA7BB2BBD8ABAE3BD29BA520607AA3A39B8EDBE012F3CB99F" + $"3EB993BEDAB920BF99B946BE34B77BBFF6B7C339B74804032EBCE932BDCEBB2B" + $"BD34BB13BECDBB51BF4DBA380208CA68BA5FCB41BD02CA3AB9D0CA0FB6BCCAF4" + $"B7AEC947B5E955B58A55B58A55B58AC844B841C8FFB76C53B953C718B814C6E6" + $"B8FBC74BB728C5A02FC601B84FC2703DC646BCB6C5ADBC1DC712BD82C89DBEE7" + $"C79E40C89DBEE7060ABFFB0FC6F2C098C626BFCCC6F2BFCC5A345C3758315A2E" + $"5A305A2C582A562E582C54305230C692B854C692B920C692B7DAC53ABAAB4FB9" + $"ACC501BB1EC46EBBF7C4AEBB9DC3FBBCB6C56DBE0EC38FBE4EC64DBDF00207C8" + $"70BE74C870BE74C7A4BDA8C78BBB44C80BBB28C71835C633BBB7C6D5BBF0C5DB" + $"BB98C501BB44C50ABB7AC4F2BAEEC3F5BC43C43FBBD2C4B4BC83C6FF38C63336" + $"C7CB3AC83DBE9AC5B3BF8DC909BD020202C6392F4DB9F9C66CBAC54DBBE34FBB" + $"17C46EBAEB0202C969B7CEC967B916CAFFB9E2543654324E3002025834563658" + $"36C877BD8FC969BB84C7ABBBF70604EAC2BD4448C111C32FC07FC362C17EC33C" + $"C0E5C37CC1E40205C5ADB861C65F31C52CB75E50204E224E20C3E2BA5FC37CB9" + $"50C455BB91C606BD02C494BCB6C723BE0DCB1BBDA8CB97BDE4C79EBBF702044E" + $"B44BC4D4284EB5174BB9B9C408B8BAC43EBAD855BD4F4BBBD057BD4FC745BB77" + $"C818BC3C51BAC502034E28C4A1B847C53AB61650BA52C593B8A0C691BBAFC4E1" + $"BAAB59BD8FC4E1B7A104032EB77BC613B63CC969B50AC7ABB778CB36BCA9C99C" + $"04032EB966B906B953B7D4B8D3B86DB9C7B749BAB82C0406BE0BB689BE67B5FD" + $"C04CB608BF7FB5F1C11CB689C1D7B65BC1A2B73BC2A3B85448B77BC33CB801C3" + $"1EB70849B609C32304032EBDA8B887BEB4B76EBE11B775BFEC2BC059B8AD0403" + $"2E28BE01B3FFC0D8B4253FB3D3C288B5BDC2FC0406FE0BC79EBB2BC8F6BBAAC8" + $"41BB48C9ECBC2FCB27BDDBCB06BD15CB41BE74CA4FC07FCA99BFCBCA0FC118C9" + $"CFC27DCA0FC1E4C998C30058C3890A04C6FFBB11C857BC50C8BDBCC3C88ABD4F" + $"040CAAFABABC70C74BC092C699C303C5CDC3DBC54DC441C4CEC44EC382C1EAC3" + $"03C237C34DC1D5C2EEC05FC402C14AC3E0BF76C423BD88C461BD48C4FABE47C5" + $"14BE2E4DBE98C58CBDBBC5870608BAAABFECC1FD4448C1FDC395C21DC362C1C4" + $"C3F1C11EC448C052C494C02CC3EFC105C389BED4C2BD0A04C369BC83C6D838C6" + $"66BD1CC35CBD350A03B46542B4BE41B4BE420605AF03B6AFC969B63DC9F2B72F" + $"C8D0BE4155B821CA8EC11CC6FAC42EC5C6C560C53ABE67C91DC1E8C7EAB86DCB" + $"270604EEBFCCBB51C1FDBBD0C13EBC43C29FBB6FC18BBAAB43BB1EC146BAF2C0" + $"9ABB4B0A0430303050505050302C0A0001021240BAB100000000000040B755C6" + $"CCDBBE997901178300040A0101020240BAB100000000000040B755C6CCDBBE99" + $"790A0201030240BAB100000000000040B755C6CCDBBE99790A030A0506070809" + $"0A0C0D040B0240BAB100000000000040B755C6CCDBBE99790A11011312408447" + $"3AE65BBB0539406A8F40BD7AC6ED3001178400040A00012712401CCA00000000" + $"00004031D6BEA7B4C5651401178100040A150112024046733A7FB6BABB054015" + $"08437714C3BB840A3B012E0A401CC92E6813AE6813401CC9C0B293C4BE831DFF" + $"0A11011412402E52374883B74883402E5243A84DC5C35901178200040A160115" + $"02402E52374883B74883402E5243A84DC5C3590A17011602402E52374883B748" + $"83402E5243A84DC5C3590A18011702402E52374883B74883402E5243A84DC5C3" + $"590A17011802402E52374883B74883402E5243A84DC5C3590A1801190240268F" + $"36C1F1B73CD33FA9DD442903C369B00A1B011A02402E52374883B74883402E52" + $"43A84DC5C3590A2C011B02402E52374883B74883402E5243A84DC5C3590A1101" + $"1C12402E52374883B74883402E5243A84DC5C35901178100040A20011D124018" + $"A13C2DD3BC6F843F776243040C3B35B701178400040A28011D024018A13C481B" + $"BC6F843FA13143AD0CC180CE0A27011E024018A13C3669BC6F843F850B43AD0C" + $"BDA6830A2603212022023F94B53C057BBC14913F373546DE4E423FFC0A2B0122" + $"02401CCA000000000000401CCAC64FB846E7CF0A2B01230241774E3E9634BD97" + $"FB40685AC6A141CA33220A0001291240075E0000000000004029CCC0DC88C59D" + $"5C01178100040A2E0124123E3A7739EBE1BA96D53D1E7BC874E948577D011784" + $"00040A360124023DE4F539818BBA43313CC9E6C7EFC848861D0A350125023DE4" + $"F539818BBA43313CC9E6C7EFC848861D0A340126023DE4F539D28CBA43313D0A" + $"55C7EFC8485E9A0A000128123FEA4E3675EFB6F2733F44E3440366C2D2660117" + $"8200040A00012A12402E52374883B74883402E5241C554C5CE0401178100040A" + $"00012B12401CCA000000000000401CCAC0623FC4B46E01178100040A00012C12" + $"403196000000000000401CCAC3AEA8C4B46E01178100040A3A012D02401CCA00" + $"0000000000401CCAC0E971C4B46E0A3C012F0A401CCA000000000000401CCAC0" + $"E971C4B46E1DFF0A3B01300A3FEC520000000000003C6A0B41051D473FEE1DFF" + $"0A3E01310240FA05000000000000417C4D3E5061C9E26E0A3F013212401CCA00" + $"0000000000401CCAC0E971C42D3C01178200040A4001330A401CCA0000000000" + $"00401CCAC0E971C4B46E1DFF0A42013402360000000000000000360000489000" + $"4AE8000A420134023600000000000000003600004870004AE8000A4301340236" + $"00000000000000003600004850004AF8000A4301340236000000000000000036" + $"00004870004AF8000A430134023600000000000000003600004890004AF8000A" + $"44013402360000000000000000360000485000466000" +}; + diff --git a/Tools/HaikuLauncher/LauncherApp.cpp b/Tools/HaikuLauncher/LauncherApp.cpp new file mode 100644 index 000000000000..ed9ae770e246 --- /dev/null +++ b/Tools/HaikuLauncher/LauncherApp.cpp @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "LauncherApp.h" + +#include "LauncherWindow.h" +#include "WebPage.h" +#include "WebView.h" +#include "WebViewConstants.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char* kApplicationSignature = "application/x-vnd.RJL-HaikuLauncher"; +enum { + LOAD_AT_STARTING = 'lost' +}; + + +LauncherApp::LauncherApp() + : BApplication(kApplicationSignature) + , m_windowCount(0) + , m_lastWindowFrame(100, 100, 700, 750) + , m_launchRefsMessage(0) + , m_initialized(false) +{ +} + +LauncherApp::~LauncherApp() +{ + delete m_launchRefsMessage; +} + +void LauncherApp::AboutRequested() +{ + BAlert* alert = new BAlert("About HaikuLauncher", + "For testing WebKit...\n\nby Ryan Leavengood", "Sweet!"); + alert->Go(); +} + +void LauncherApp::ArgvReceived(int32 argc, char** argv) +{ + for (int i = 1; i < argc; i++) { + const char* url = argv[i]; + BEntry entry(argv[i], true); + BPath path; + if (entry.Exists() && entry.GetPath(&path) == B_OK) + url = path.Path(); + BMessage message(LOAD_AT_STARTING); + message.AddString("url", url); + message.AddBool("new window", m_initialized || i > 1); + PostMessage(&message); + } +} + +void LauncherApp::ReadyToRun() +{ + // Since we will essentially run the GUI... + set_thread_priority(Thread(), B_DISPLAY_PRIORITY); + + BWebPage::InitializeOnce(); + BWebPage::SetCacheModel(B_WEBKIT_CACHE_MODEL_WEB_BROWSER); + + mkdir("localStorage", 0755); + BWebSettings::SetPersistentStoragePath("localStorage"); + + BFile settingsFile; + BRect windowFrameFromSettings = m_lastWindowFrame; + if (openSettingsFile(settingsFile, B_READ_ONLY)) { + BMessage settingsArchive; + settingsArchive.Unflatten(&settingsFile); + settingsArchive.FindRect("window frame", &windowFrameFromSettings); + } + m_lastWindowFrame = windowFrameFromSettings; + + m_initialized = true; + + if (m_launchRefsMessage) { + RefsReceived(m_launchRefsMessage); + delete m_launchRefsMessage; + m_launchRefsMessage = 0; + } else { + LauncherWindow* window = new LauncherWindow(m_lastWindowFrame); + window->Show(); + } +} + +void LauncherApp::MessageReceived(BMessage* message) +{ + switch (message->what) { + case LOAD_AT_STARTING: { + BString url; + if (message->FindString("url", &url) != B_OK) + break; + bool openNewWindow = false; + message->FindBool("new window", &openNewWindow); + LauncherWindow* webWindow = NULL; + for (int i = 0; BWindow* window = WindowAt(i); i++) { + webWindow = dynamic_cast(window); + if (!webWindow) + continue; + if (!openNewWindow) { + // stop at the first window + break; + } + } + if (webWindow) { + // There should always be at least one window open. If not, maybe we are about + // to quit anyway... + if (openNewWindow) { + // open a new window with an offset to the last window + newWindow(url); + } else { + // load the URL in the first window + webWindow->CurrentWebView()->LoadURL(url.String()); + } + } + break; + } + case B_SILENT_RELAUNCH: + newWindow(""); + break; + case NEW_WINDOW: { + BString url; + if (message->FindString("url", &url) != B_OK) + break; + newWindow(url); + break; + } + case WINDOW_OPENED: + m_windowCount++; + break; + case WINDOW_CLOSED: + m_windowCount--; + message->FindRect("window frame", &m_lastWindowFrame); + if (m_windowCount <= 0) + PostMessage(B_QUIT_REQUESTED); + break; + + case B_SAVE_REQUESTED: + { + entry_ref dir; + message->FindRef("directory", &dir); + BString name = message->FindString("name"); + + BDirectory saveTo(&dir); + BFile file(&saveTo, name, + B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + + BWebPage* page = NULL; + message->FindPointer("page", (void**)&page); + + page->GetContentsAsMHTML(file); + break; + } + default: + BApplication::MessageReceived(message); + break; + } +} + +void LauncherApp::RefsReceived(BMessage* message) +{ + if (!m_initialized) { + delete m_launchRefsMessage; + m_launchRefsMessage = new BMessage(*message); + return; + } + + entry_ref ref; + for (int32 i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { + BEntry entry(&ref, true); + if (!entry.Exists()) + continue; + BPath path; + if (entry.GetPath(&path) != B_OK) + continue; + BString url; + url << path.Path(); + newWindow(url); + } +} + +bool LauncherApp::QuitRequested() +{ + for (int i = 0; BWindow* window = WindowAt(i); i++) { + LauncherWindow* webWindow = dynamic_cast(window); + if (!webWindow) + continue; + if (!webWindow->Lock()) + continue; + if (webWindow->QuitRequested()) { + m_lastWindowFrame = webWindow->Frame(); + webWindow->CurrentWebView()->Shutdown(); + delete webWindow->CurrentWebView(); + webWindow->Quit(); + i--; + } else { + webWindow->Unlock(); + return false; + } + } + + BFile settingsFile; + if (openSettingsFile(settingsFile, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY)) { + BMessage settingsArchive; + settingsArchive.AddRect("window frame", m_lastWindowFrame); + settingsArchive.Flatten(&settingsFile); + } + + return true; +} + +bool LauncherApp::openSettingsFile(BFile& file, uint32 mode) +{ + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK + || path.Append("HaikuLauncher") != B_OK) { + return false; + } + return file.SetTo(path.Path(), mode) == B_OK; +} + +void LauncherApp::newWindow(const BString& url) +{ + m_lastWindowFrame.OffsetBy(20, 20); + if (!BScreen().Frame().Contains(m_lastWindowFrame)) + m_lastWindowFrame.OffsetTo(50, 50); + + LauncherWindow* window = new LauncherWindow(m_lastWindowFrame); + window->Show(); + if (url.Length()) + window->CurrentWebView()->LoadURL(url.String()); +} + +// #pragma mark - + +int main(int, char**) +{ + new LauncherApp(); + be_app->Run(); + delete be_app; + + return 0; +} + diff --git a/Tools/HaikuLauncher/LauncherApp.h b/Tools/HaikuLauncher/LauncherApp.h new file mode 100644 index 000000000000..7e1e37aeba94 --- /dev/null +++ b/Tools/HaikuLauncher/LauncherApp.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LauncherApp_h +#define LauncherApp_h + +#include +#include +#include + +class BFile; +class LauncherWindow; + +class LauncherApp : public BApplication { +public: + LauncherApp(); + virtual ~LauncherApp(); + + virtual void AboutRequested(); + virtual void ArgvReceived(int32, char**); + virtual void MessageReceived(BMessage*); + virtual void RefsReceived(BMessage*); + virtual void ReadyToRun(); + virtual bool QuitRequested(); + +private: + bool openSettingsFile(BFile& file, uint32 mode); + void newWindow(const BString& url); + + int m_windowCount; + BRect m_lastWindowFrame; + BMessage* m_launchRefsMessage; + bool m_initialized; +}; + +extern const char* kApplicationSignature; + +#endif // LauncherApp_h + diff --git a/Tools/HaikuLauncher/LauncherWindow.cpp b/Tools/HaikuLauncher/LauncherWindow.cpp new file mode 100644 index 000000000000..9d010c01b12b --- /dev/null +++ b/Tools/HaikuLauncher/LauncherWindow.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2007 Andrea Anzani + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * Copyright (C) 2010 Michael Lotz + * Copyright (C) 2010 Rene Gollent + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "LauncherWindow.h" + +#include "AuthenticationPanel.h" +#include "LauncherApp.h" +#include "WebPage.h" +#include "WebView.h" +#include "WebViewConstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum { + OPEN_LOCATION = 'open', + OPEN_INSPECTOR = 'insp', + SAVE_PAGE = 'save', + GO_BACK = 'goba', + GO_FORWARD = 'gofo', + STOP = 'stop', + GOTO_URL = 'goul', + RELOAD = 'reld', + + TEXT_SIZE_INCREASE = 'tsin', + TEXT_SIZE_DECREASE = 'tsdc', + TEXT_SIZE_RESET = 'tsrs', +}; + +LauncherWindow::LauncherWindow(BRect frame, ToolbarPolicy toolbarPolicy) + : BWebWindow(frame, "HaikuLauncher", + B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, + B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS) +{ + init(new BWebView("web view"), toolbarPolicy); +} + +LauncherWindow::LauncherWindow(BRect frame, BWebView* webView, + ToolbarPolicy toolbarPolicy) + : BWebWindow(frame, "HaikuLauncher", + B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, + B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS) +{ + init(webView, toolbarPolicy); +} + +LauncherWindow::~LauncherWindow() +{ + delete m_saveFilePanel; +} + +void LauncherWindow::DispatchMessage(BMessage* message, BHandler* target) +{ + if (m_url && message->what == B_KEY_DOWN && target == m_url->TextView()) { + // Handle B_RETURN in the URL text control. This is the easiest + // way to react *only* when the user presses the return key in the + // address bar, as opposed to trying to load whatever is in there when + // the text control just goes out of focus. + const char* bytes; + if (message->FindString("bytes", &bytes) == B_OK + && bytes[0] == B_RETURN) { + // Do it in such a way that the user sees the Go-button go down. + m_goButton->SetValue(B_CONTROL_ON); + UpdateIfNeeded(); + m_goButton->Invoke(); + snooze(1000); + m_goButton->SetValue(B_CONTROL_OFF); + } + } + BWebWindow::DispatchMessage(message, target); +} + +void LauncherWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case OPEN_LOCATION: + if (m_url) { + if (m_url->TextView()->IsFocus()) + m_url->TextView()->SelectAll(); + else + m_url->MakeFocus(true); + } + break; + case OPEN_INSPECTOR: { + // FIXME: wouldn't the view better be in the same window? + BRect frame = Frame(); + frame.OffsetBy(20, 20); + LauncherWindow* inspectorWindow = new LauncherWindow(frame); + inspectorWindow->Show(); + + CurrentWebView()->SetInspectorView(inspectorWindow->CurrentWebView()); + break; + } + case SAVE_PAGE: { + BMessage* message = new BMessage(B_SAVE_REQUESTED); + message->AddPointer("page", CurrentWebView()->WebPage()); + + if (m_saveFilePanel == NULL) { + m_saveFilePanel = new BFilePanel(B_SAVE_PANEL, NULL, NULL, + B_DIRECTORY_NODE, false); + } + + m_saveFilePanel->SetSaveText(CurrentWebView()->WebPage()->MainFrameTitle()); + m_saveFilePanel->SetMessage(message); + m_saveFilePanel->Show(); + break; + } + + case RELOAD: + CurrentWebView()->Reload(); + break; + case GOTO_URL: { + BString url; + if (message->FindString("url", &url) != B_OK) + url = m_url->Text(); + CurrentWebView()->LoadURL(url.String()); + break; + } + case GO_BACK: + CurrentWebView()->GoBack(); + break; + case GO_FORWARD: + CurrentWebView()->GoForward(); + break; + case STOP: + CurrentWebView()->StopLoading(); + break; + + case B_SIMPLE_DATA: { + // User possibly dropped files on this window. + // If there is more than one entry_ref, let the app handle it (open one + // new page per ref). If there is one ref, open it in this window. + type_code type; + int32 countFound; + if (message->GetInfo("refs", &type, &countFound) != B_OK + || type != B_REF_TYPE) { + break; + } + if (countFound > 1) { + message->what = B_REFS_RECEIVED; + be_app->PostMessage(message); + break; + } + entry_ref ref; + if (message->FindRef("refs", &ref) != B_OK) + break; + BEntry entry(&ref, true); + BPath path; + if (!entry.Exists() || entry.GetPath(&path) != B_OK) + break; + CurrentWebView()->LoadURL(path.Path()); + break; + } + + case TEXT_SIZE_INCREASE: + CurrentWebView()->IncreaseZoomFactor(true); + break; + case TEXT_SIZE_DECREASE: + CurrentWebView()->DecreaseZoomFactor(true); + break; + case TEXT_SIZE_RESET: + CurrentWebView()->ResetZoomFactor(); + break; + + default: + BWebWindow::MessageReceived(message); + break; + } +} + +bool LauncherWindow::QuitRequested() +{ + BMessage message(WINDOW_CLOSED); + message.AddRect("window frame", Frame()); + be_app->PostMessage(&message); + return BWebWindow::QuitRequested(); +} + +// #pragma mark - Notification API + +void LauncherWindow::NavigationRequested(const BString& url, BWebView* view) +{ +} + +void LauncherWindow::NewWindowRequested(const BString& url, bool primaryAction) +{ + // Always open new windows in the application thread, since + // creating a BWebView will try to grab the application lock. + // But our own WebPage may already try to lock us from within + // the application thread -> dead-lock. Thus we can't wait for + // a reply here. + BMessage message(NEW_WINDOW); + message.AddString("url", url); + be_app->PostMessage(&message); +} + +void LauncherWindow::NewPageCreated(BWebView* view, BRect windowFrame, + bool modalDialog, bool resizable, bool activate) +{ + if (!windowFrame.IsValid()) + windowFrame = Frame().OffsetByCopy(10, 10); + LauncherWindow* window = new LauncherWindow(windowFrame, view, HaveToolbar); + window->Show(); +} + +void LauncherWindow::LoadNegotiating(const BString& url, BWebView* view) +{ + BString status("Requesting: "); + status << url; + StatusChanged(status, view); +} + +void LauncherWindow::LoadCommitted(const BString& url, BWebView* view) +{ + // This hook is invoked when the load is commited. + if (m_url) + m_url->SetText(url.String()); + + BString status("Loading: "); + status << url; + StatusChanged(status, view); + + NavigationCapabilitiesChanged(m_BackButton->IsEnabled(), + m_ForwardButton->IsEnabled(), true, view); +} + +void LauncherWindow::LoadProgress(float progress, BWebView* view) +{ + if (m_loadingProgressBar) { + if (progress < 100 && m_loadingProgressBar->IsHidden()) + m_loadingProgressBar->Show(); + m_loadingProgressBar->SetTo(progress); + } +} + +void LauncherWindow::LoadFailed(const BString& url, BWebView* view) +{ + BString status(url); + status << " failed."; + StatusChanged(status, view); + if (m_loadingProgressBar && !m_loadingProgressBar->IsHidden()) + m_loadingProgressBar->Hide(); +} + +void LauncherWindow::LoadFinished(const BString& url, BWebView* view) +{ + // Update the URL again to handle cases where LoadCommitted is not called + // (for example when navigating to anchors in the same page). + if (m_url) + m_url->SetText(url.String()); + + BString status(url); + status << " finished."; + StatusChanged(status, view); + if (m_loadingProgressBar && !m_loadingProgressBar->IsHidden()) + m_loadingProgressBar->Hide(); + + NavigationCapabilitiesChanged(m_BackButton->IsEnabled(), + m_ForwardButton->IsEnabled(), false, view); +} + +void LauncherWindow::SetToolBarsVisible(bool flag, BWebView* view) +{ + // TODO +} + +void LauncherWindow::SetStatusBarVisible(bool flag, BWebView* view) +{ + // TODO +} + +void LauncherWindow::SetMenuBarVisible(bool flag, BWebView* view) +{ + // TODO +} + +void LauncherWindow::TitleChanged(const BString& title, BWebView* view) +{ + updateTitle(title); +} + +void LauncherWindow::StatusChanged(const BString& statusText, BWebView* view) +{ + if (m_statusText) + m_statusText->SetText(statusText.String()); +} + +void LauncherWindow::NavigationCapabilitiesChanged(bool canGoBackward, + bool canGoForward, bool canStop, BWebView* view) +{ + if (m_BackButton) + m_BackButton->SetEnabled(canGoBackward); + if (m_ForwardButton) + m_ForwardButton->SetEnabled(canGoForward); + if (m_StopButton) + m_StopButton->SetEnabled(canStop); +} + + +bool +LauncherWindow::AuthenticationChallenge(BString message, BString& inOutUser, + BString& inOutPassword, bool& inOutRememberCredentials, + uint32 failureCount, BWebView* view) +{ + AuthenticationPanel* panel = new AuthenticationPanel(Frame()); + // Panel auto-destructs. + bool success = panel->getAuthentication(message, inOutUser, inOutPassword, + inOutRememberCredentials, failureCount > 0, inOutUser, inOutPassword, + &inOutRememberCredentials); + return success; +} + + +void LauncherWindow::init(BWebView* webView, ToolbarPolicy toolbarPolicy) +{ + SetCurrentWebView(webView); + + if (toolbarPolicy == HaveToolbar) { + // Menu + m_menuBar = new BMenuBar("Main menu"); + BMenu* menu = new BMenu("Window"); + BMessage* newWindowMessage = new BMessage(NEW_WINDOW); + newWindowMessage->AddString("url", ""); + BMenuItem* newItem = new BMenuItem("New", newWindowMessage, 'N'); + menu->AddItem(newItem); + newItem->SetTarget(be_app); + menu->AddItem(new BMenuItem("Open location", new BMessage(OPEN_LOCATION), 'L')); + menu->AddItem(new BMenuItem("Inspect page", new BMessage(OPEN_INSPECTOR), 'I')); + menu->AddItem(new BMenuItem("Save page", new BMessage(SAVE_PAGE), 'S')); + menu->AddSeparatorItem(); + menu->AddItem(new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), 'W', B_SHIFT_KEY)); + BMenuItem* quitItem = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'); + menu->AddItem(quitItem); + quitItem->SetTarget(be_app); + m_menuBar->AddItem(menu); + + menu = new BMenu("Text"); + menu->AddItem(new BMenuItem("Increase size", new BMessage(TEXT_SIZE_INCREASE), '+')); + menu->AddItem(new BMenuItem("Decrease size", new BMessage(TEXT_SIZE_DECREASE), '-')); + menu->AddItem(new BMenuItem("Reset size", new BMessage(TEXT_SIZE_RESET), '0')); + m_menuBar->AddItem(menu); + + // Back, Forward & Stop + m_BackButton = new BButton("Back", new BMessage(GO_BACK)); + m_ForwardButton = new BButton("Forward", new BMessage(GO_FORWARD)); + m_StopButton = new BButton("Stop", new BMessage(STOP)); + + // URL + m_url = new BTextControl("url", "", "", NULL); + + // Go + m_goButton = new BButton("", "Go", new BMessage(GOTO_URL)); + + // Status Bar + m_statusText = new BStringView("status", ""); + m_statusText->SetAlignment(B_ALIGN_LEFT); + m_statusText->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + m_statusText->SetExplicitMinSize(BSize(150, 12)); + // Prevent the window from growing to fit a long status message... + BFont font(be_plain_font); + font.SetSize(ceilf(font.Size() * 0.8)); + m_statusText->SetFont(&font, B_FONT_SIZE); + + // Loading progress bar + m_loadingProgressBar = new BStatusBar("progress"); + m_loadingProgressBar->SetMaxValue(100); + m_loadingProgressBar->Hide(); + m_loadingProgressBar->SetBarHeight(12); + + const float kInsetSpacing = 5; + const float kElementSpacing = 7; + + // Layout + AddChild(BGroupLayoutBuilder(B_VERTICAL) + .Add(m_menuBar) + .Add(BGridLayoutBuilder(kElementSpacing, kElementSpacing) + .Add(m_BackButton, 0, 0) + .Add(m_ForwardButton, 1, 0) + .Add(m_StopButton, 2, 0) + .Add(m_url, 3, 0) + .Add(m_goButton, 4, 0) + .SetInsets(kInsetSpacing, kInsetSpacing, kInsetSpacing, kInsetSpacing) + ) + .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) + .Add(webView) + .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) + .Add(BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing) + .Add(m_statusText) + .Add(m_loadingProgressBar, 0.2) + .AddStrut(12 - kElementSpacing) + .SetInsets(kInsetSpacing, 0, kInsetSpacing, 0) + ) + ); + + m_url->MakeFocus(true); + } else { + m_BackButton = 0; + m_ForwardButton = 0; + m_StopButton = 0; + m_goButton = 0; + m_url = 0; + m_menuBar = 0; + m_statusText = 0; + m_loadingProgressBar = 0; + + AddChild(BGroupLayoutBuilder(B_VERTICAL) + .Add(webView) + ); + } + + m_saveFilePanel = 0; + + AddShortcut('R', B_COMMAND_KEY, new BMessage(RELOAD)); + + be_app->PostMessage(WINDOW_OPENED); +} + +void LauncherWindow::updateTitle(const BString& title) +{ + BString windowTitle = title; + if (windowTitle.Length() > 0) + windowTitle << " - "; + windowTitle << "HaikuLauncher"; + SetTitle(windowTitle.String()); +} diff --git a/Tools/HaikuLauncher/LauncherWindow.h b/Tools/HaikuLauncher/LauncherWindow.h new file mode 100644 index 000000000000..45e6738747c7 --- /dev/null +++ b/Tools/HaikuLauncher/LauncherWindow.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007 Ryan Leavengood + * Copyright (C) 2009 Maxime Simon + * Copyright (C) 2010 Stephan Aßmus + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LauncherWindow_h +#define LauncherWindow_h + +#include "WebWindow.h" +#include +#include + +class BButton; +class BCheckBox; +class BFilePanel; +class BLayoutItem; +class BMenuBar; +class BStatusBar; +class BStringView; +class BTextControl; +class BWebView; + +enum ToolbarPolicy { + HaveToolbar, + DoNotHaveToolbar +}; + +enum { + NEW_WINDOW = 'nwnd', + WINDOW_OPENED = 'wndo', + WINDOW_CLOSED = 'wndc', +}; + +class LauncherWindow : public BWebWindow { +public: + LauncherWindow(BRect frame, ToolbarPolicy = HaveToolbar); + LauncherWindow(BRect frame, BWebView* view, ToolbarPolicy = HaveToolbar); + virtual ~LauncherWindow(); + + virtual void DispatchMessage(BMessage* message, BHandler* target); + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + +private: + // WebPage notification API implementations + virtual void NavigationRequested(const BString& url, BWebView* view) override; + virtual void NewWindowRequested(const BString& url, bool primaryAction) override; + virtual void NewPageCreated(BWebView* view, BRect windowFrame, + bool modalDialog, bool resizable, bool activate) override; + virtual void LoadNegotiating(const BString& url, BWebView* view) override; + virtual void LoadCommitted(const BString& url, BWebView* view) override; + virtual void LoadProgress(float progress, BWebView* view) override; + virtual void LoadFailed(const BString& url, BWebView* view) override; + virtual void LoadFinished(const BString& url, BWebView* view) override; + virtual void TitleChanged(const BString& title, BWebView* view) override; + virtual void SetToolBarsVisible(bool flag, BWebView* view) override; + virtual void SetStatusBarVisible(bool flag, BWebView* view) override; + virtual void SetMenuBarVisible(bool flag, BWebView* view) override; + virtual void StatusChanged(const BString& status, BWebView* view) override; + virtual void NavigationCapabilitiesChanged(bool canGoBackward, + bool canGoForward, bool canStop, BWebView* view) override; + virtual bool AuthenticationChallenge(BString message, + BString& inOutUser, BString& inOutPassword, + bool& inOutRememberCredentials, + uint32 failureCount, BWebView* view); + + void init(BWebView* view, ToolbarPolicy); + void updateTitle(const BString& title); + +private: + BMenuBar* m_menuBar; + BButton* m_BackButton; + BButton* m_ForwardButton; + BButton* m_StopButton; + BButton* m_goButton; + BTextControl* m_url; + BStringView* m_statusText; + BStatusBar* m_loadingProgressBar; + BFilePanel* m_saveFilePanel; +}; + +#endif // LauncherWindow_h + diff --git a/Tools/ImageDiff/PlatformHaiku.cmake b/Tools/ImageDiff/PlatformHaiku.cmake new file mode 100644 index 000000000000..191d86a87b09 --- /dev/null +++ b/Tools/ImageDiff/PlatformHaiku.cmake @@ -0,0 +1,12 @@ +list(APPEND ImageDiff_SOURCES + ${IMAGE_DIFF_DIR}/haiku/PlatformImageHaiku.cpp +) + +list(APPEND ImageDiff_INCLUDE_DIRECTORIES +) + +list(APPEND ImageDiff_LIBRARIES + be translation +) + +list(APPEND ImageDiff_PRIVATE_DEFINITIONS USE_HAIKU=1) diff --git a/Tools/ImageDiff/PlatformImage.h b/Tools/ImageDiff/PlatformImage.h index a632f34e8455..e6ed3f783dfc 100644 --- a/Tools/ImageDiff/PlatformImage.h +++ b/Tools/ImageDiff/PlatformImage.h @@ -28,6 +28,8 @@ #if defined(USE_CAIRO) && USE_CAIRO typedef struct _cairo_surface cairo_surface_t; +#elif defined(USE_HAIKU) +class BBitmap; #else typedef struct CGImage *CGImageRef; #endif @@ -41,6 +43,8 @@ class PlatformImage { #if defined(USE_CAIRO) && USE_CAIRO PlatformImage(cairo_surface_t*); +#elif defined(USE_HAIKU) + PlatformImage(BBitmap*); #else PlatformImage(CGImageRef); #endif @@ -58,6 +62,8 @@ class PlatformImage { private: #if defined(USE_CAIRO) && USE_CAIRO cairo_surface_t* m_image; +#elif defined(USE_HAIKU) + BBitmap* m_image; #else CGImageRef m_image; mutable void* m_buffer { nullptr }; diff --git a/Tools/ImageDiff/haiku/PlatformImageHaiku.cpp b/Tools/ImageDiff/haiku/PlatformImageHaiku.cpp new file mode 100644 index 000000000000..b2c2c9dff064 --- /dev/null +++ b/Tools/ImageDiff/haiku/PlatformImageHaiku.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2013-2019 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PlatformImage.h" + +#include +#include +#include +#include + +#include + + +namespace ImageDiff { + +std::unique_ptr PlatformImage::createFromStdin(size_t imageSize) +{ + auto imageBuffer = new unsigned char[imageSize]; + if (!imageBuffer) + return nullptr; + + const size_t bytesRead = fread(imageBuffer, 1, imageSize, stdin); + if (bytesRead <= 0) { + delete[] imageBuffer; + return nullptr; + } + + BMemoryIO imageData(imageBuffer, imageSize); + BBitmap* image = BTranslationUtils::GetBitmap(&imageData); + + delete[] imageBuffer; + + if (image == NULL) + return nullptr; + + return std::make_unique(image); +} + + +std::unique_ptr PlatformImage::createFromDiffData(void* data, size_t width, size_t height) +{ + BBitmap* surface = new BBitmap(BRect(0, 0, width - 1, height - 1), B_GRAY8); + void* dest = surface->Bits(); + memcpy(dest, data, width * height); + return std::make_unique(surface); +} + + +PlatformImage::PlatformImage(BBitmap* surface) + : m_image(surface) +{ +} + + +PlatformImage::~PlatformImage() +{ + delete m_image; +} + +size_t PlatformImage::width() const +{ + return m_image->Bounds().Width() + 1; +} + +size_t PlatformImage::height() const +{ + return m_image->Bounds().Height() + 1; +} + +size_t PlatformImage::rowBytes() const +{ + return m_image->BytesPerRow(); +} + + +bool PlatformImage::hasAlpha() const +{ + return m_image->ColorSpace() == B_RGBA32; +} + +unsigned char* PlatformImage::pixels() const +{ + return (unsigned char*)m_image->Bits(); +} + + +void PlatformImage::writeAsPNGToStdout() +{ + BMallocIO imageData; + BBitmapStream input(m_image); + // Will delete the image! + if (BTranslatorRoster::Default()->Translate(&input, NULL, NULL, + &imageData, B_PNG_FORMAT) == B_OK) { + printf("Content-Length: %ld\n", imageData.BufferLength()); + fflush(stdout); + + write(1, imageData.Buffer(), imageData.BufferLength()); + } +} + +} // namespace ImageDiff diff --git a/Tools/MiniBrowser/haiku/BrowserApp.cpp b/Tools/MiniBrowser/haiku/BrowserApp.cpp new file mode 100644 index 000000000000..b137cc12dd51 --- /dev/null +++ b/Tools/MiniBrowser/haiku/BrowserApp.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2019, RAJAGOPALAN-GANGADHARAN + * All rights reserved. Distributed under the terms of the MIT license. + */ + + + +#include +#include + +#include "BrowserApp.h" +#include "BrowserWindow.h" + +#include "WebViewConstants.h" + + +BrowserApp::BrowserApp(void) + : BApplication("application/x-vnd.lh-MiniBrowser") +{ + fWindow = new BrowserWindow(); + webView = new BWebView(BRect(100,100,800,800),fWindow); +} + +void BrowserApp::MessageReceived(BMessage *message) +{ + switch(message->what) + { + case READY_TO_PAINT: + webView->paintContent(); + break; + case URL_LOAD_HANDLE: + webView->loadURI(message); + break; + default: + BApplication::MessageReceived(message); + } +} +void BrowserApp::ReadyToRun() +{ + webView->initializeOnce(); + webView->navigationCallbacks(); + fWindow->Construct(webView); + fWindow->Show(); +} + +int main (void) +{ + BrowserApp *app = new BrowserApp(); + app->Run(); + delete app; + return 0; +} + diff --git a/Tools/MiniBrowser/haiku/BrowserApp.h b/Tools/MiniBrowser/haiku/BrowserApp.h new file mode 100644 index 000000000000..76f3ad4285d5 --- /dev/null +++ b/Tools/MiniBrowser/haiku/BrowserApp.h @@ -0,0 +1,29 @@ +/* + * Copyright 2019, RAJAGOPALAN-GANGADHARAN + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef APP_H +#define APP_H + +#include +#include +#include + +#include "WebView.h" +using namespace std; + +class BrowserWindow; + +class BrowserApp : public BApplication +{ +public: + BrowserApp(void); + void MessageReceived(BMessage *message); + void ReadyToRun(); +private: + BWebView* webView; + status_t result; + BrowserWindow* fWindow; +}; + +#endif diff --git a/Tools/MiniBrowser/haiku/BrowserWindow.cpp b/Tools/MiniBrowser/haiku/BrowserWindow.cpp new file mode 100644 index 000000000000..45837472eb68 --- /dev/null +++ b/Tools/MiniBrowser/haiku/BrowserWindow.cpp @@ -0,0 +1,214 @@ +/* + * Copyright 2019, RAJAGOPALAN-GANGADHARAN + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "BrowserWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "WebViewConstants.h" +#include "WebView.h" + +enum { + OPEN_LOCATION = 'open', + OPEN_INSPECTOR = 'insp', + SAVE_PAGE = 'save', + GO_BACK = 'goba', + GO_FORWARD = 'gofo', + STOP = 'stop', + GOTO_URL = 'goul', + RELOAD = 'reld', + + TEXT_SIZE_INCREASE = 'tsin', + TEXT_SIZE_DECREASE = 'tsdc', + TEXT_SIZE_RESET = 'tsrs', + + NEW_WINDOW = 'nwnd', + WINDOW_OPENED = 'wndo', + WINDOW_CLOSED = 'wndc', +}; + +BrowserWindow::BrowserWindow() +: +BWindow(BRect(100,100,800,800),"MiniBrowser", + B_DOCUMENT_WINDOW_LOOK,B_NORMAL_WINDOW_FEEL, + B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS + | B_QUIT_ON_WINDOW_CLOSE ), +fWebView(NULL) +{ + SetLayout(new BGroupLayout(B_HORIZONTAL)); + + m_menuBar = new BMenuBar("Main menu"); + BMenu* menu = new BMenu("Window"); + BMessage* newWindowMessage = new BMessage(NEW_WINDOW); + newWindowMessage->AddString("url", ""); + BMenuItem* newItem = new BMenuItem("New", newWindowMessage, 'N'); + menu->AddItem(newItem); + newItem->SetTarget(be_app); + menu->AddItem(new BMenuItem("Open location", new BMessage(OPEN_LOCATION), 'L')); + menu->AddItem(new BMenuItem("Inspect page", new BMessage(OPEN_INSPECTOR), 'I')); + menu->AddItem(new BMenuItem("Save page", new BMessage(SAVE_PAGE), 'S')); + menu->AddSeparatorItem(); + menu->AddItem(new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), 'W', B_SHIFT_KEY)); + BMenuItem* quitItem = new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q'); + menu->AddItem(quitItem); + quitItem->SetTarget(be_app); + m_menuBar->AddItem(menu); + + menu = new BMenu("Text"); + menu->AddItem(new BMenuItem("Increase size", new BMessage(TEXT_SIZE_INCREASE), '+')); + menu->AddItem(new BMenuItem("Decrease size", new BMessage(TEXT_SIZE_DECREASE), '-')); + menu->AddItem(new BMenuItem("Reset size", new BMessage(TEXT_SIZE_RESET), '0')); + m_menuBar->AddItem(menu); + + + m_BackButton = new BButton("","Back",new BMessage(GO_BACK)); + m_ForwardButton = new BButton("","Forward", new BMessage(GO_FORWARD)); + m_StopButton = new BButton("","Stop", new BMessage(STOP)); + + m_url = new BTextControl("url", "", "", NULL); + + m_goButton = new BButton("", "Go", new BMessage(GOTO_URL)); + + m_goButton->SetTarget(this); + m_BackButton->SetTarget(this); + m_ForwardButton->SetTarget(this); + m_StopButton->SetTarget(this); + + m_statusText = new BStringView("status", ""); + m_statusText->SetAlignment(B_ALIGN_LEFT); + m_statusText->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + m_statusText->SetExplicitMinSize(BSize(150, 12)); + + BFont font(be_plain_font); + font.SetSize(ceilf(font.Size() * 0.8)); + m_statusText->SetFont(&font, B_FONT_SIZE); + + m_loadingProgressBar = new BStatusBar("progress"); + m_loadingProgressBar->SetMaxValue(100); + m_loadingProgressBar->Hide(); + m_loadingProgressBar->SetBarHeight(12); + + + + m_url->MakeFocus(true); +} + +BrowserWindow::~BrowserWindow() +{ +} +void BrowserWindow::Construct(BWebView* webView) +{ + fWebView = webView; + + const float kInsetSpacing = 5; + const float kElementSpacing = 7; + AddChild(BGroupLayoutBuilder(B_VERTICAL) + .Add(m_menuBar) + .Add(BGridLayoutBuilder(kElementSpacing, kElementSpacing) + .Add(m_BackButton, 0, 0) + .Add(m_ForwardButton, 1, 0) + .Add(m_StopButton, 2, 0) + .Add(m_url, 3, 0) + .Add(m_goButton, 4, 0) + .SetInsets(kInsetSpacing, kInsetSpacing, kInsetSpacing, kInsetSpacing) + ) + .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) + .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) + .Add(fWebView->getRenderView())//this is the view be it mail or anywhere can be added + .Add(BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing) + .Add(m_statusText) + .Add(m_loadingProgressBar, 0.2) + .AddStrut(12 - kElementSpacing) + .SetInsets(kInsetSpacing, 0, kInsetSpacing, 0) + ) + ); +} +void BrowserWindow::MessageReceived(BMessage* message) +{ + switch(message->what) + { + case GOTO_URL: + SetStatus(m_url->Text()); + fWebView->loadURIRequest(m_url->Text()); + break; + + case GO_BACK: + //TODO - write through main loop + fWebView->goBackward(); + break; + + case GO_FORWARD: + //TODO - write through main loop + fWebView->goForward(); + break; + + case DID_COMMIT_NAVIGATION: + SetStatus("loading"); + break; + + case DID_FINISH_NAVIGATION: + SetStatus("finished"); + LoadingProgress(1); + break; + + case URL_CHANGE: + ChangeUrl(message); + break; + + case DID_CHANGE_PROGRESS: + LoadingProgress(fWebView->didChangeProgress()); + break; + + case DID_CHANGE_TITLE: + ChangeTitle(fWebView->title()); + break; + + case STOP: + SetStatus("cancelling"); + fWebView->stop(); + break; + + default: + BWindow::MessageReceived(message); + + } +} + +void BrowserWindow::SetStatus(const char* str) +{ + m_statusText->SetText(str); +} + +void BrowserWindow::ChangeUrl(BMessage* message) +{ + BString str; + message->FindString("url",&str); + m_url->SetText(str.String()); +} + +void BrowserWindow::LoadingProgress(double value) +{ + if(value*100<100 && m_loadingProgressBar->IsHidden()) + m_loadingProgressBar->Show(); + + m_loadingProgressBar->SetTo(value*100); +} + +void BrowserWindow::ChangeTitle(const char* title) +{ + SetTitle(title); +} diff --git a/Tools/MiniBrowser/haiku/BrowserWindow.h b/Tools/MiniBrowser/haiku/BrowserWindow.h new file mode 100644 index 000000000000..59eb4af49669 --- /dev/null +++ b/Tools/MiniBrowser/haiku/BrowserWindow.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019, RAJAGOPALAN-GANGADHARAN + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef BrowserWindow_H +#define BrowserWindow_H + +#include +#include +#include +#include +#include + +class BButton; +class BCheckBox; +class BLayoutItem; +class BMenuBar; +class BStatusBar; +class BStringView; +class BTextControl; +class BWebView; + +class BrowserWindow:public BWindow +{ +public: + BrowserWindow(); + ~BrowserWindow(); + void MessageReceived(BMessage*); + void Construct(BWebView*); +private: + void SetStatus(const char*); + void ChangeUrl(BMessage*); + void LoadingProgress(double value); + void ChangeTitle(const char* title); + + BWebView* fWebView; + + BMenuBar* m_menuBar; + BButton* m_BackButton; + BButton* m_ForwardButton; + BButton* m_StopButton; + BButton* m_goButton; + BTextControl* m_url; + BStringView* m_statusText; + BStatusBar* m_loadingProgressBar; +}; + + +#endif // _H diff --git a/Tools/MiniBrowser/haiku/CMakeLists.txt b/Tools/MiniBrowser/haiku/CMakeLists.txt new file mode 100644 index 000000000000..8690ce0de676 --- /dev/null +++ b/Tools/MiniBrowser/haiku/CMakeLists.txt @@ -0,0 +1,35 @@ +SET(MiniBrowser_SOURCES + ${TOOLS_DIR}/MiniBrowser/haiku/BrowserApp.cpp + ${TOOLS_DIR}/MiniBrowser/haiku/BrowserWindow.cpp +) + +INCLUDE_DIRECTORIES( + "${WEBKIT_DIR}/UIProcess/API/haiku" +) + +SET(MiniBrowser_LIBRARIES + WebKit + WebCore + JavaScriptCore + ${LIBXML2_LIBRARIES} + ${LIBXSLT_LIBRARIES} + ${SQLITE_LIBRARIES} + ${ICU_I18N_LIBRARIES} + ${ICU_LIBRARIES} + be bsd network stdc++ translation tracker +) + +set(MiniBrowser_LOCAL_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/css" + "${WEBCORE_DIR}/platform/graphics/transforms" + "${WEBCORE_DIR}/rendering/shapes" +) + +foreach(inc ${MiniBrowser_LOCAL_INCLUDE_DIRECTORIES}) + ADD_DEFINITIONS(-iquote ${inc}) +endforeach(inc) + +ADD_EXECUTABLE(MiniBrowser ${MiniBrowser_SOURCES}) +TARGET_LINK_LIBRARIES(MiniBrowser ${MiniBrowser_LIBRARIES}) +SET_TARGET_PROPERTIES(MiniBrowser PROPERTIES FOLDER "Tools") +SET_TARGET_PROPERTIES(MiniBrowser PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") diff --git a/Tools/PlatformHaiku.cmake b/Tools/PlatformHaiku.cmake new file mode 100644 index 000000000000..f6ee8bbb1e38 --- /dev/null +++ b/Tools/PlatformHaiku.cmake @@ -0,0 +1,4 @@ +add_subdirectory(DumpRenderTree) +add_subdirectory(HaikuLauncher) +add_subdirectory(ImageDiff) +add_subdirectory(MiniBrowser/haiku) \ No newline at end of file diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit index e3e00ada84f9..e8a695333169 100755 --- a/Tools/Scripts/build-webkit +++ b/Tools/Scripts/build-webkit @@ -1,4 +1,4 @@ -#!/usr/bin/env perl +#!/bin/perl -w # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Apple Inc. All rights reserved. # Copyright (C) 2009 Google Inc. All rights reserved. @@ -119,6 +119,7 @@ Usage: $programName [options] [options to pass to build system] --[no-]xcbuild Force the use of XCBuild or not --gtk Build the GTK+ port + --haiku Build the Haiku port --wpe Build the WPE port --wincairo Build using Cairo (rather than CoreGraphics) on Windows --playstation Build the PlayStation port diff --git a/Tools/Scripts/run-minibrowser b/Tools/Scripts/run-minibrowser index 4cf6be4047bf..fb7799569305 100755 --- a/Tools/Scripts/run-minibrowser +++ b/Tools/Scripts/run-minibrowser @@ -58,6 +58,9 @@ if (isGtk() || isWPE()) { } elsif (isAppleCocoaWebKit()) { printHelpAndExitForRunAndDebugWebKitAppIfNeeded(); exit exitStatus(runMiniBrowser()); +} elsif (isHaiku()) { + print "Starting MiniBrowser\n"; + exit exitStatus(runMiniBrowser()); } else { die "Unsupported platform." -} +} \ No newline at end of file diff --git a/Tools/Scripts/webkitdirs.pm b/Tools/Scripts/webkitdirs.pm index 67cc17a6b116..c5c260709126 100755 --- a/Tools/Scripts/webkitdirs.pm +++ b/Tools/Scripts/webkitdirs.pm @@ -105,6 +105,7 @@ BEGIN { use constant { AppleWin => "AppleWin", GTK => "GTK", + Haiku => "Haiku", iOS => "iOS", tvOS => "tvOS", watchOS => "watchOS", @@ -401,6 +402,7 @@ sub determineArchitecture } $architecture = 'x86_64' if $architecture =~ /amd64/i; + $architecture = 'x86' if ($architecture =~ /BePC/ && isHaiku()); $architecture = 'arm64' if $architecture =~ /aarch64/i; } @@ -437,6 +439,8 @@ sub determineNumberOfCPUs return if defined $numberOfCPUs; if (defined($ENV{NUMBER_OF_PROCESSORS})) { $numberOfCPUs = $ENV{NUMBER_OF_PROCESSORS}; + } elsif (isHaiku()) { + $numberOfCPUs = `sysinfo -cpu | grep "CPU #" | wc -l` } elsif (isLinux()) { # First try the nproc utility, if it exists. If we get no # results fall back to just interpretting /proc directly. @@ -492,6 +496,7 @@ sub argumentsForConfiguration() push(@args, '--32-bit') if ($architecture eq "x86" and !isWin64()); push(@args, '--64-bit') if (isWin64()); push(@args, '--gtk') if isGtk(); + push(@args, '--haiku') if isHaiku(); push(@args, '--wpe') if isWPE(); push(@args, '--jsc-only') if isJSCOnly(); push(@args, '--wincairo') if isWinCairo(); @@ -772,7 +777,7 @@ sub executableProductDir my $binaryDirectory; if (isAnyWindows() && !isPlayStation()) { $binaryDirectory = isWin64() ? "bin64" : "bin32"; - } elsif (isGtk() || isJSCOnly() || isWPE() || isPlayStation()) { + } elsif (isGtk() || isJSCOnly() || isWPE() || isHaiku() || isPlayStation()) { $binaryDirectory = "bin"; } else { return $productDirectory; @@ -1029,6 +1034,12 @@ sub builtDylibPathForName my $extension = isDarwin() ? ".dylib" : ".so"; return "$configurationProductDir/lib/libwebkit2gtk-4.0" . $extension; } + if (isHaiku()) { + if (isWK2()) { + return "$configurationProductDir/lib/libWebKit2.so"; + } + return "$configurationProductDir/lib/libWebKit.so"; + } if (isIOSWebKit()) { return "$configurationProductDir/$libraryName.framework/$libraryName"; } @@ -1158,6 +1169,7 @@ sub determinePortName() my %argToPortName = ( gtk => GTK, + haiku => Haiku, 'jsc-only' => JSCOnly, playstation => PlayStation, wincairo => WinCairo, @@ -1194,6 +1206,7 @@ sub determinePortName() if ($unknownPortProhibited) { my $portsChoice = join "\n\t", qw( --gtk + --haiku --jsc-only --wpe ); @@ -1350,6 +1363,11 @@ sub isBSD() return ($^O eq "freebsd") || ($^O eq "openbsd") || ($^O eq "netbsd") || 0; } +sub isHaiku() +{ + return ($^O eq "haiku") || 0; +} + sub isX86_64() { return (architecture() eq "x86_64") || 0; @@ -1654,7 +1672,7 @@ sub relativeScriptsDir() sub launcherPath() { my $relativeScriptsPath = relativeScriptsDir(); - if (isGtk() || isWPE()) { + if (isGtk() || isHaiku() || isWPE()) { if (inFlatpakSandbox()) { return "Tools/Scripts/run-minibrowser"; } @@ -1672,6 +1690,8 @@ sub launcherName() return "Safari"; } elsif (isAppleWinWebKit()) { return "MiniBrowser"; + } elsif (isHaiku()) { + return "HaikuLauncher"; } } @@ -1943,6 +1963,8 @@ sub getJhbuildPath() } if (isGtk()) { push(@jhbuildPath, "DependenciesGTK"); + } elsif (isHaiku()) { + return () # Unused on Haiku. } elsif (isWPE()) { push(@jhbuildPath, "DependenciesWPE"); } else { @@ -2026,7 +2048,7 @@ sub runInFlatpakIfAvailable(@) sub wrapperPrefixIfNeeded() { - if (isAnyWindows() || isJSCOnly() || isPlayStation()) { + if (isAnyWindows() || isHaiku() || isJSCOnly() || isPlayStation()) { return (); } if (isAppleCocoaWebKit()) { @@ -2843,6 +2865,10 @@ sub runMiniBrowser my $webKitLauncherPath = File::Spec->catfile(executableProductDir(), "MiniBrowser.exe"); return system { $webKitLauncherPath } $webKitLauncherPath, @ARGV; } + if(isHaiku()){ + my $webKitLauncherPath = File::Spec->catfile(productDir(), "MiniBrowser"); + return system { $webKitLauncherPath } $webKitLauncherPath, @ARGV; + } return 1; } diff --git a/Tools/Scripts/webkitpy/common/config/ports.py b/Tools/Scripts/webkitpy/common/config/ports.py index d7a78d8a5304..c87c1ab4073b 100644 --- a/Tools/Scripts/webkitpy/common/config/ports.py +++ b/Tools/Scripts/webkitpy/common/config/ports.py @@ -73,11 +73,13 @@ def port(port_name): "mac-wk2": MacWK2Port, "win": WinPort, "wincairo": WinCairoPort, + "haiku": HaikuPort, "wpe": WpePort, } default_port = { "Windows": WinPort, "Darwin": MacPort, + "Haiku": HaikuPort, } # Do we really need MacPort as the ultimate default? return ports.get(port_name, default_port.get(platform.system(), MacPort))() @@ -220,6 +222,23 @@ def run_webkit_tests_command(self, build_style=None): return command +class HaikuPort(DeprecatedPort): + port_flag_name = "haiku" + + def build_webkit_command(self, build_style=None): + command = super(HaikuPort, self).build_webkit_command(build_style=build_style) + command.append("--haiku") + command.append("--update-haiku") + command.append("--no-webkit2") + command.append(super(HaikuPort, self).makeArgs()) + return command + + def run_webkit_tests_command(self, build_style=None): + command = super(HaikuPort, self).run_webkit_tests_command(build_style) + command.append("--haiku") + return command + + class WpePort(DeprecatedPort): port_flag_name = "wpe" diff --git a/Tools/Scripts/webkitpy/common/system/file_lock.py b/Tools/Scripts/webkitpy/common/system/file_lock.py index e666a0a71a76..8af40e1fa4f8 100644 --- a/Tools/Scripts/webkitpy/common/system/file_lock.py +++ b/Tools/Scripts/webkitpy/common/system/file_lock.py @@ -58,7 +58,7 @@ def _remove_lock(self): fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_UN) def acquire_lock(self): - self._lock_file_descriptor = os.open(self._lock_file_path, os.O_TRUNC | os.O_CREAT) + self._lock_file_descriptor = os.open(self._lock_file_path, os.O_TRUNC | os.O_CREAT | os.O_WRONLY) start_time = time.time() while True: try: diff --git a/Tools/Scripts/webkitpy/common/system/platforminfo.py b/Tools/Scripts/webkitpy/common/system/platforminfo.py index 1b980d5414e7..12c2d62ec27e 100644 --- a/Tools/Scripts/webkitpy/common/system/platforminfo.py +++ b/Tools/Scripts/webkitpy/common/system/platforminfo.py @@ -84,6 +84,9 @@ def is_native_win(self): def is_cygwin(self): return self._is_cygwin + def is_haiku(self): + return self.os_name == 'haiku' + def is_linux(self): return self.os_name == 'linux' @@ -191,6 +194,8 @@ def _determine_os_name(self, sys_platform): return 'ios' if sys_platform.startswith('linux'): return 'linux' + if sys_platform.startswith('haiku'): + return 'haiku' if sys_platform.startswith('win') or sys_platform == 'cygwin': return 'win' if sys_platform.startswith('freebsd'): diff --git a/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py b/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py index 0b1495e08f13..97c9123e69ef 100644 --- a/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py +++ b/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py @@ -47,6 +47,9 @@ def is_ios(self): def is_linux(self): return self.os_name == 'linux' + def is_haiku(self): + return self.os_name == 'haiku' + def is_win(self): return self.os_name == 'win' diff --git a/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py b/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py index 81be3adb1ef0..02afcf0011db 100644 --- a/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py +++ b/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py @@ -80,7 +80,7 @@ def test_real_code(self): if info.is_mac() or info.is_win(): self.assertIsNotNone(info.os_version) self.assertNotEquals(info.display_name(), '') - self.assertTrue(info.is_mac() or info.is_win() or info.is_linux() or info.is_freebsd()) + self.assertTrue(info.is_mac() or info.is_win() or info.is_linux() or info.is_freebsd() or info.is_haiku()) self.assertIsNotNone(info.terminal_width()) if info.is_mac(): diff --git a/Tools/Scripts/webkitpy/common/version_name_map.py b/Tools/Scripts/webkitpy/common/version_name_map.py index daabbc871a3a..a06c84de1b70 100644 --- a/Tools/Scripts/webkitpy/common/version_name_map.py +++ b/Tools/Scripts/webkitpy/common/version_name_map.py @@ -72,7 +72,7 @@ def __init__(self, platform=None): 'Vista': Version(6), 'XP': Version(5, 1), }, - + 'haiku' : { '' : Version(1.4) }, # This entry avoids hitting the assert in mapping_for_platform() on Linux, # but otherwise shouldn't contain any useful key-value pairs. 'linux': {}, diff --git a/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py b/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py index 672b9a0de157..415a4020c631 100644 --- a/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py +++ b/Tools/Scripts/webkitpy/layout_tests/servers/http_server.py @@ -84,7 +84,7 @@ def _prepare_config(self): base_conf_file = self._port_obj.path_from_webkit_base('Tools', 'Scripts', 'webkitpy', 'layout_tests', 'servers', 'lighttpd.conf') out_conf_file = os.path.join(self._output_dir, 'lighttpd.conf') - time_str = time.strftime("%d%b%Y-%H%M%S") + time_str = time.asctime() access_file_name = "access.log-" + time_str + ".txt" access_log = os.path.join(self._output_dir, access_file_name) log_file_name = "error.log-" + time_str + ".txt" @@ -107,11 +107,13 @@ def _prepare_config(self): # Write out our cgi handlers. Run perl through env so that it # processes the #! line and runs perl with the proper command # line arguments. Emulate apache's mod_asis with a cat cgi handler. - f.write(('cgi.assign = ( ".cgi" => "/usr/bin/env",\n' - ' ".pl" => "/usr/bin/env",\n' + f.write(('cgi.assign = ( ".cgi" => "%s",\n' + ' ".pl" => "%s",\n' ' ".asis" => "/bin/cat",\n' ' ".php" => "%s" )\n\n') % - self._port_obj._path_to_lighttpd_php()) + (self._port_obj._path_to_lighttpd_env(), + self._port_obj._path_to_lighttpd_env(), + self._port_obj._path_to_lighttpd_php())) # Setup log files f.write(('server.errorlog = "%s"\n' diff --git a/Tools/Scripts/webkitpy/port/base.py b/Tools/Scripts/webkitpy/port/base.py index b0f88b6d8d13..362ced63754b 100644 --- a/Tools/Scripts/webkitpy/port/base.py +++ b/Tools/Scripts/webkitpy/port/base.py @@ -1410,6 +1410,12 @@ def _path_to_lighttpd_php(self): This is needed only by ports that use the http_server.py module.""" raise NotImplementedError('Port._path_to_lighttpd_php') + def _path_to_lighttpd_env(self): + """Returns path to the env executable. + + This is used to run CGI scripts in lighttpd.""" + return "/usr/bin/env" + def _webkit_baseline_path(self, platform): """Return the full path to the top of the baseline tree for a given platform.""" diff --git a/Tools/Scripts/webkitpy/port/factory.py b/Tools/Scripts/webkitpy/port/factory.py index 4d3c41ffcee5..4ca9bdcf3d6e 100644 --- a/Tools/Scripts/webkitpy/port/factory.py +++ b/Tools/Scripts/webkitpy/port/factory.py @@ -59,6 +59,9 @@ def platform_options(use_globs=False): optparse.make_option('--gtk', action='store_const', dest='platform', const=('gtk*' if use_globs else 'gtk'), help=('Alias for --platform=gtk*' if use_globs else 'Alias for --platform=gtk')), + optparse.make_option('--haiku', action='store_const', dest='platform', + const=('haiku*' if use_globs else 'haiku'), + help=('Alias for --platform=haiku*' if use_globs else 'Alias for --platform=haiku')), optparse.make_option('--wpe', action='store_const', dest='platform', const=('wpe*' if use_globs else 'wpe'), help=('Alias for --platform=wpe')), @@ -95,6 +98,7 @@ class PortFactory(object): # first. PORT_CLASSES = ( 'gtk.GtkPort', + 'haiku.HaikuPort', 'ios_simulator.IOSSimulatorPort', 'ios_simulator.IPhoneSimulatorPort', 'ios_simulator.IPadSimulatorPort', @@ -121,6 +125,8 @@ def _default_port(self, options): return 'mac' elif platform.is_win(): return 'win' + elif platform.is_haiku(): + return 'haiku' raise NotImplementedError('unknown platform: %s' % platform) def get(self, port_name=None, options=None, **kwargs): diff --git a/Tools/Scripts/webkitpy/port/haiku.py b/Tools/Scripts/webkitpy/port/haiku.py new file mode 100644 index 000000000000..a60709de1236 --- /dev/null +++ b/Tools/Scripts/webkitpy/port/haiku.py @@ -0,0 +1,150 @@ +# Copyright (C) 2011 ProFUSION Embedded Systems. All rights reserved. +# Copyright (C) 2011 Samsung Electronics. All rights reserved. +# Copyright (C) 2012 Intel Corporation +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""WebKit Haiku implementation of the Port interface.""" + +import os + +from webkitpy.layout_tests.models.test_configuration import TestConfiguration +from webkitpy.port.base import Port +from webkitpy.port.haikudriver import HaikuDriver +from webkitpy.port.haiku_get_crash_log import HaikuCrashLogGenerator + + +class HaikuPort(Port): + port_name = 'haiku' + + def __init__(self, host, port_name, **kwargs): + super(HaikuPort, self).__init__(host, port_name, **kwargs) + + self.webprocess_cmd_prefix = self.get_option('webprocess_cmd_prefix') + self._version = "1.4" + + def _port_flag_for_scripts(self): + return "--haiku" + + def setup_test_run(self, device_class=None): + super(HaikuPort, self).setup_test_run() + + def setup_environ_for_server(self, server_name=None): + env = super(HaikuPort, self).setup_environ_for_server(server_name) + + if self.webprocess_cmd_prefix: + env['WEB_PROCESS_CMD_PREFIX'] = self.webprocess_cmd_prefix + + return env + + def default_timeout_ms(self): + # Tests run considerably slower under gdb + # or valgrind. + if self.get_option('webprocess_cmd_prefix'): + return 350 * 1000 + return 45 * 1000 + + def clean_up_test_run(self): + super(HaikuPort, self).clean_up_test_run() + + def _generate_all_test_configurations(self): + return [TestConfiguration(version=self.version_name(), architecture='x86', build_type=build_type) for build_type in self.ALL_BUILD_TYPES] + + def _driver_class(self): + return HaikuDriver + + def _path_to_driver(self): + return self._build_path('bin', self.driver_name()) + + def _path_to_image_diff(self): + return self._build_path('bin', 'ImageDiff') + + def _image_diff_command(self, *args, **kwargs): + return super(HaikuPort, self)._image_diff_command(*args, **kwargs) + + def _path_to_webcore_library(self): + static_path = self._build_path('lib', 'libWebCore.a') + dyn_path = self._build_path('lib', 'libWebCore.so') + return static_path if self._filesystem.exists(static_path) else dyn_path + + def _search_paths(self): + search_paths = [] + if self.get_option('webkit_test_runner'): + search_paths.append(self.port_name + '-wk2') + search_paths.append('wk2') + else: + search_paths.append(self.port_name + '-wk1') + search_paths.append(self.port_name) + return search_paths + + def default_baseline_search_path(self): + return map(self._webkit_baseline_path, self._search_paths()) + + def _port_specific_expectations_files(self): + # FIXME: We should be able to use the default algorithm here. + return list(reversed([self._filesystem.join(self._webkit_baseline_path(p), 'TestExpectations') for p in self._search_paths()])) + + def show_results_html_file(self, results_filename): + # FIXME: We should find a way to share this implmentation with Gtk, + # or teach run-launcher how to call run-safari and move this down to WebKitPort. + run_launcher_args = ["file://%s" % results_filename] + if self.get_option('webkit_test_runner'): + run_launcher_args.append('-2') + # FIXME: old-run-webkit-tests also added ["-graphicssystem", "raster", "-style", "windows"] + # FIXME: old-run-webkit-tests converted results_filename path for cygwin. + self._run_script("run-launcher", run_launcher_args) + + def _uses_apache(self): + return False + + def _path_to_lighttpd(self): + return "/system/bin/lighttpd" + + def _path_to_lighttpd_modules(self): + if os.path.exists("/system/lib/lighttpd"): + return "/system/lib/lighttpd" + else: + return "/system/lib/x86/lighttpd" + + def _path_to_lighttpd_php(self): + return "/system/bin/php-cgi" + + def _path_to_lighttpd_env(self): + return "/bin/env" + + def check_sys_deps(self): + return super(HaikuPort, self).check_sys_deps() and self._driver_class().check_driver(self) + + def build_webkit_command(self, build_style=None): + command = super(HaikuPort, self).build_webkit_command(build_style) + command.extend(["--haiku", "--update-haiku"]) + if self.get_option('webkit_test_runner'): + command.append("--no-webkit1") + else: + command.append("--no-webkit2") + command.append(super(HaikuPort, self).make_args()) + return command + + def _get_crash_log(self, name, pid, stdout, stderr, newer_than, target_host=None): + return HaikuCrashLogGenerator(name, pid, newer_than, self._filesystem, self._path_to_driver).generate_crash_log(stdout, stderr) diff --git a/Tools/Scripts/webkitpy/port/haiku_get_crash_log.py b/Tools/Scripts/webkitpy/port/haiku_get_crash_log.py new file mode 100644 index 000000000000..9490b2869ea4 --- /dev/null +++ b/Tools/Scripts/webkitpy/port/haiku_get_crash_log.py @@ -0,0 +1,83 @@ +# Copyright (C) 2013 Haiku, inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import subprocess +import os + + +class HaikuCrashLogGenerator(object): + def __init__(self, name, pid, newer_than, filesystem, path_to_driver): + self.name = name + self.pid = pid + self.newer_than = newer_than + self._filesystem = filesystem + self._path_to_driver = path_to_driver + + def _get_debugger_output(self, coredump_path): + result = None + try: + with open(coredump_path) as corefile: + result = corefile.read().decode('utf8', 'ignore') + os.unlink(coredump_path) + except IOError: + result = None + return result + + def generate_crash_log(self, stdout, stderr): + pid_representation = str(self.pid or '') + log_directory = os.environ.get("WEBKIT_CORE_DUMPS_DIRECTORY") + errors = [] + crash_log = '' + expected_crash_dump_filename = "DumpRenderTree-%s-debug" % (pid_representation) + proc_name = "%s" % (self.name) + + def match_filename(filesystem, directory, filename): + return filename.find(expected_crash_dump_filename) > -1 + + if not log_directory: + log_directory = "/boot/home/Desktop" + + dumps = self._filesystem.files_under(log_directory, file_filter=match_filename) + if dumps: + # Get the most recent coredump matching the pid and/or process name. + coredump_path = list(reversed(sorted(dumps)))[0] + if not self.newer_than or self._filesystem.mtime(coredump_path) > self.newer_than: + crash_log = self._get_debugger_output(coredump_path) + core_pattern = os.path.join(log_directory, expected_crash_dump_filename) + + if not crash_log: + crash_log = """\ +Crash report %(expected_crash_dump_filename)s not found. To enable crash logs, +create the file ~/config/settings/system/debug_server/settings with the following contents: + +executable_actions { + DumpRenderTree log +} +""" % locals() + + return (stderr, """\ +crash log for %(proc_name)s (pid %(pid_representation)s): + +%(crash_log)s""" % locals()) diff --git a/Tools/Scripts/webkitpy/port/haikudriver.py b/Tools/Scripts/webkitpy/port/haikudriver.py new file mode 100644 index 000000000000..9ab6ef04df09 --- /dev/null +++ b/Tools/Scripts/webkitpy/port/haikudriver.py @@ -0,0 +1,86 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the Google name nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import os +import re +import time + +from webkitpy.port.server_process import ServerProcess +from webkitpy.port.driver import Driver +from webkitpy.common.system.file_lock import FileLock + +_log = logging.getLogger(__name__) + + +class HaikuDriver(Driver): + @staticmethod + def check_driver(port): + return 1 + + def __init__(self, *args, **kwargs): + Driver.__init__(self, *args, **kwargs) + self._guard_lock = None + self._startup_delay_secs = 1.0 + + def _next_free_display(self): + return 0 + + def _xvfb_screen_depth(self): + return 24 + + def _start(self, pixel_tests, per_test_args): + self.stop() + + # Use even displays for pixel tests and odd ones otherwise. When pixel tests are disabled, + # DriverProxy creates two drivers, one for normal and the other for ref tests. Both have + # the same worker number, so this prevents them from using the same Xvfb instance. + display_id = self._next_free_display() + + server_name = "haiku" + environment = self._port.setup_environ_for_server(server_name) + self._driver_tempdir = self._port.host.filesystem.mkdtemp(prefix='%s-' % self._port.driver_name()) + environment['DUMPRENDERTREE_TEMP'] = str(self._driver_tempdir) + environment['LOCAL_RESOURCE_ROOT'] = self._port.layout_tests_dir() + + # Currently on WebKit2, there is no API for setting the application + # cache directory. Each worker should have it's own and it should be + # cleaned afterwards, so we set it to inside the temporary folder by + # prepending XDG_CACHE_HOME with DUMPRENDERTREE_TEMP. + environment['XDG_CACHE_HOME'] = self._port.host.filesystem.join(str(self._driver_tempdir), 'appcache') + + self._crashed_process_name = None + self._crashed_pid = None + self._server_process = self._port._server_process_constructor(self._port, server_name, self.cmd_line(pixel_tests, per_test_args), environment) + self._server_process.start() + + def stop(self): + super(HaikuDriver, self).stop() + if self._guard_lock: + self._guard_lock.release_lock() + self._guard_lock = None diff --git a/Tools/TestWebKitAPI/PlatformWebView.h b/Tools/TestWebKitAPI/PlatformWebView.h index ad2a732d5194..b2f8836bd09e 100644 --- a/Tools/TestWebKitAPI/PlatformWebView.h +++ b/Tools/TestWebKitAPI/PlatformWebView.h @@ -47,6 +47,9 @@ typedef NSWindow *PlatformWindow; #elif PLATFORM(GTK) typedef WKViewRef PlatformWKView; typedef GtkWidget *PlatformWindow; +#elif PLATFORM(HAIKU) +typedef BView* PlatformWKView; +typedef BWindow* PlatformWindow; #elif PLATFORM(WPE) namespace WPEToolingBackends { class HeadlessViewBackend; diff --git a/Tools/WebKitTestRunner/CMakeLists.txt b/Tools/WebKitTestRunner/CMakeLists.txt index b2335b25b4b8..7d3c4b0efdd0 100644 --- a/Tools/WebKitTestRunner/CMakeLists.txt +++ b/Tools/WebKitTestRunner/CMakeLists.txt @@ -53,6 +53,10 @@ set(WebKitTestRunner_SYSTEM_INCLUDE_DIRECTORIES ${LIBSOUP_INCLUDE_DIRS} ) +SET(WebKitTestRunner_LOCAL_INCLUDE_DIRECTORIES + ${WEBCORE_DIR}/platform/graphics +) + set(WebKitTestRunnerInjectedBundle_SOURCES ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/AccessibilityController.cpp ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/AccessibilityTextMarker.cpp @@ -104,6 +108,9 @@ GENERATE_BINDINGS(WebKitTestRunnerBindings WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() +foreach(inc ${WebKitTestRunner_LOCAL_INCLUDE_DIRECTORIES}) + ADD_DEFINITIONS(-iquote ${inc}) +endforeach(inc) include_directories(${WebKitTestRunner_INCLUDE_DIRECTORIES}) include_directories(SYSTEM ${WebKitTestRunner_SYSTEM_INCLUDE_DIRECTORIES}) diff --git a/Tools/WebKitTestRunner/InjectedBundle/haiku/ActivateFontsHaiku.cpp b/Tools/WebKitTestRunner/InjectedBundle/haiku/ActivateFontsHaiku.cpp new file mode 100644 index 000000000000..a232c8845ecd --- /dev/null +++ b/Tools/WebKitTestRunner/InjectedBundle/haiku/ActivateFontsHaiku.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "ActivateFonts.h" + +#include "FontManagement.h" + +namespace WTR { + +void activateFonts() +{ + addFontsToEnvironment(); +} + +} // namespace WTR + diff --git a/Tools/WebKitTestRunner/InjectedBundle/haiku/FontManagement.cpp b/Tools/WebKitTestRunner/InjectedBundle/haiku/FontManagement.cpp new file mode 100644 index 000000000000..c2466bc1955a --- /dev/null +++ b/Tools/WebKitTestRunner/InjectedBundle/haiku/FontManagement.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FontManagement.h" + +#include "NotImplemented.h" + +void addFontsToEnvironment() +{ + notImplemented(); +} diff --git a/Tools/WebKitTestRunner/InjectedBundle/haiku/FontManagement.h b/Tools/WebKitTestRunner/InjectedBundle/haiku/FontManagement.h new file mode 100644 index 000000000000..1ebd87aef15a --- /dev/null +++ b/Tools/WebKitTestRunner/InjectedBundle/haiku/FontManagement.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 ProFUSION Embedded Systems + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FontManagement_h +#define FontManagement_h + +void addFontsToEnvironment(); + +#endif // FontManagement_h + diff --git a/Tools/WebKitTestRunner/InjectedBundle/haiku/InjectedBundleHaiku.cpp b/Tools/WebKitTestRunner/InjectedBundle/haiku/InjectedBundleHaiku.cpp new file mode 100644 index 000000000000..1198320955e2 --- /dev/null +++ b/Tools/WebKitTestRunner/InjectedBundle/haiku/InjectedBundleHaiku.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "InjectedBundle.h" + +#include + +namespace WTR { + +void InjectedBundle::platformInitialize(WKTypeRef) +{ + WTFInstallReportBacktraceOnCrashHook(); +} + +} // namespace WTR diff --git a/Tools/WebKitTestRunner/InjectedBundle/haiku/TestRunnerHaiku.cpp b/Tools/WebKitTestRunner/InjectedBundle/haiku/TestRunnerHaiku.cpp new file mode 100644 index 000000000000..a1540da404f4 --- /dev/null +++ b/Tools/WebKitTestRunner/InjectedBundle/haiku/TestRunnerHaiku.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "TestRunner.h" + +#include +#include +#include "NotImplemented.h" +#include +#include + +namespace WTR { + +void TestRunner::platformInitialize() +{ + m_waitToDumpWatchdogTimer = 0; +} + +void TestRunner::invalidateWaitToDumpWatchdogTimer() +{ + if (!m_waitToDumpWatchdogTimer) + return; + + delete m_waitToDumpWatchdogTimer; +} + +void TestRunner::initializeWaitToDumpWatchdogTimerIfNeeded() +{ + if (m_waitToDumpWatchdogTimer) + return; + + notImplemented(); +} + +JSRetainPtr TestRunner::pathToLocalResource(JSStringRef url) +{ + String requestedUrl(url->characters(), url->length()); + String resourceRoot; + String requestedRoot; + + if (requestedUrl.find("LayoutTests") != notFound) { + // If the URL contains LayoutTests we need to remap that to + // LOCAL_RESOURCE_ROOT which is the path of the LayoutTests directory + // within the WebKit source tree. + requestedRoot = "/tmp/LayoutTests"; + resourceRoot = getenv("LOCAL_RESOURCE_ROOT"); + } else if (requestedUrl.find("tmp") != notFound) { + // If the URL is a child of /tmp we need to convert it to be a child + // DUMPRENDERTREE_TEMP replace tmp with DUMPRENDERTREE_TEMP + requestedRoot = "/tmp"; + resourceRoot = getenv("DUMPRENDERTREE_TEMP"); + } + + size_t indexOfRootStart = requestedUrl.reverseFind(requestedRoot); + size_t indexOfSeparatorAfterRoot = indexOfRootStart + requestedRoot.length(); + String fullPathToUrl = "file://" + resourceRoot + requestedUrl.substring(indexOfSeparatorAfterRoot); + + return JSStringCreateWithUTF8CString(fullPathToUrl.utf8().data()); +} + +JSRetainPtr TestRunner::inspectorTestStubURL() +{ + StringBuilder builder; + builder.append("file://"); + builder.append(WebCore::inspectorResourcePath()); + builder.appendLiteral("/TestStub.html"); + + return JSStringCreateWithUTF8CString(builder.toString().utf8().data()); +} + +} diff --git a/Tools/WebKitTestRunner/PlatformHaiku.cmake b/Tools/WebKitTestRunner/PlatformHaiku.cmake new file mode 100644 index 000000000000..7ba9d3231432 --- /dev/null +++ b/Tools/WebKitTestRunner/PlatformHaiku.cmake @@ -0,0 +1,29 @@ +add_custom_target(forwarding-headersHaikuForWebKitTestRunner + COMMAND ${PERL_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-forwarding-headers.pl ${WEBKIT_TESTRUNNER_DIR} ${DERIVED_SOURCES_WEBKIT2_DIR}/include haiku +) +set(ForwardingHeadersForWebKitTestRunner_NAME forwarding-headersHaikuForWebKitTestRunner) + +list(APPEND WebKitTestRunner_SOURCES + ${WEBKIT_TESTRUNNER_DIR}/haiku/EventSenderProxyHaiku.cpp + ${WEBKIT_TESTRUNNER_DIR}/haiku/PlatformWebViewHaiku.cpp + ${WEBKIT_TESTRUNNER_DIR}/haiku/TestControllerHaiku.cpp + ${WEBKIT_TESTRUNNER_DIR}/haiku/TestInvocationHaiku.cpp + ${WEBKIT_TESTRUNNER_DIR}/haiku/main.cpp +) + +list(APPEND WebKitTestRunner_INCLUDE_DIRECTORIES + ${DERIVED_SOURCES_WEBCORE_DIR} + ${DERIVED_SOURCES_WEBCORE_DIR}/include + ${DERIVED_SOURCES_WEBKIT2_DIR}/include + + ${WEBKIT2_DIR}/UIProcess/API/cpp + ${WEBKIT2_DIR}/UIProcess/API/haiku + ${WEBKIT2_DIR}/UIProcess/API/C/haiku +) + +list(APPEND WebKitTestRunnerInjectedBundle_SOURCES + ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/haiku/ActivateFontsHaiku.cpp + ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/haiku/FontManagement.cpp + ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/haiku/InjectedBundleHaiku.cpp + ${WEBKIT_TESTRUNNER_INJECTEDBUNDLE_DIR}/haiku/TestRunnerHaiku.cpp +) diff --git a/Tools/WebKitTestRunner/PlatformWebView.h b/Tools/WebKitTestRunner/PlatformWebView.h index f74cc2d393d5..7e7d6453be01 100644 --- a/Tools/WebKitTestRunner/PlatformWebView.h +++ b/Tools/WebKitTestRunner/PlatformWebView.h @@ -44,6 +44,11 @@ typedef RetainPtr PlatformImage; typedef struct _GtkWidget GtkWidget; typedef WKViewRef PlatformWKView; typedef GtkWidget* PlatformWindow; +#elif PLATFORM(HAIKU) +class BWebView; +class BWindow; +typedef BWebView* PlatformWKView; +typedef BWindow* PlatformWindow; #elif PLATFORM(WPE) namespace WPEToolingBackends { class HeadlessViewBackend; diff --git a/Tools/WebKitTestRunner/haiku/EventSenderProxyHaiku.cpp b/Tools/WebKitTestRunner/haiku/EventSenderProxyHaiku.cpp new file mode 100644 index 000000000000..4586012e4999 --- /dev/null +++ b/Tools/WebKitTestRunner/haiku/EventSenderProxyHaiku.cpp @@ -0,0 +1,118 @@ +/* + Copyright (C) 2014 Haiku, inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "EventSenderProxy.h" + +#include "NotImplemented.h" + +namespace WTR { + +EventSenderProxy::EventSenderProxy(TestController* testController) + : m_testController(testController) + , m_time(0) + , m_leftMouseButtonDown(false) + , m_clickCount(0) + , m_clickTime(0) + , m_clickButton(kWKEventMouseButtonNoButton) +#if ENABLE(TOUCH_EVENTS) + , m_touchPoints(0) +#endif +{ +} + +EventSenderProxy::~EventSenderProxy() +{ +#if ENABLE(TOUCH_EVENTS) + clearTouchPoints(); +#endif +} + +void EventSenderProxy::updateClickCountForButton(int button) +{ + if (m_time - m_clickTime < 1 && m_position == m_clickPosition && button == m_clickButton) { + ++m_clickCount; + m_clickTime = m_time; + return; + } + + m_clickCount = 1; + m_clickTime = m_time; + m_clickPosition = m_position; + m_clickButton = button; +} + +void EventSenderProxy::mouseDown(unsigned button, WKEventModifiers wkModifiers) +{ + notImplemented(); + updateClickCountForButton(button); +} + +void EventSenderProxy::mouseUp(unsigned button, WKEventModifiers wkModifiers) +{ + notImplemented(); + + m_clickPosition = m_position; + m_clickTime = currentEventTime(); +} + +void EventSenderProxy::mouseMoveTo(double x, double y) +{ + m_position.x = x; + m_position.y = y; + + notImplemented(); +} + +void EventSenderProxy::mouseScrollBy(int horizontal, int vertical) +{ + notImplemented(); +} + +void EventSenderProxy::continuousMouseScrollBy(int horizontal, int vertical, bool paged) +{ + notImplemented(); +} + +void EventSenderProxy::mouseScrollByWithWheelAndMomentumPhases(int x, int y, int /*phase*/, int /*momentum*/) +{ + // EFL does not have the concept of wheel gesture phases or momentum. Just relay to + // the mouse wheel handler. + mouseScrollBy(x, y); +} + +void EventSenderProxy::leapForward(int milliseconds) +{ + notImplemented(); + + m_time += milliseconds / 1000.0; +} + +void EventSenderProxy::keyDown(WKStringRef keyRef, WKEventModifiers wkModifiers, unsigned location) +{ + notImplemented(); +} + +} diff --git a/Tools/WebKitTestRunner/haiku/PlatformWebViewHaiku.cpp b/Tools/WebKitTestRunner/haiku/PlatformWebViewHaiku.cpp new file mode 100644 index 000000000000..bbaa0e9ad01f --- /dev/null +++ b/Tools/WebKitTestRunner/haiku/PlatformWebViewHaiku.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "PlatformWebView.h" + +#include "NotImplemented.h" +#include +#include + +using namespace WebKit; + +namespace WTR { + +PlatformWebView::PlatformWebView(WKContextRef context, WKPageGroupRef pageGroup, + WKPageRef /* relatedPage */, WKDictionaryRef options) +{ + WKRetainPtr useFixedLayoutKey(AdoptWK, + WKStringCreateWithUTF8CString("UseFixedLayout")); + m_usingFixedLayout = options ? WKBooleanGetValue(static_cast( + WKDictionaryGetItemForKey(options, useFixedLayoutKey.get()))) : false; + + m_window = new BWindow(BRect(0, 0, 800, 600), "WebKitTestRunner", + B_DOCUMENT_WINDOW, 0); + + // TODO create m_view + m_view = new BWebView(context, pageGroup); + WKPageSetUseFixedLayout(WKViewGetPage(m_view->GetWKView()), + m_usingFixedLayout); + + m_window->AddChild(m_view); + + if (m_usingFixedLayout) + resizeTo(800, 600); + + m_windowIsKey = false; +} + +PlatformWebView::~PlatformWebView() +{ + delete m_window; // The window owns the view +} + +void PlatformWebView::resizeTo(unsigned width, unsigned height) +{ + m_view->ResizeTo(width, height); +} + +WKPageRef PlatformWebView::page() +{ + return WKViewGetPage(m_view->GetWKView()); +} + +void PlatformWebView::focus() +{ + notImplemented(); +} + +WKRect PlatformWebView::windowFrame() +{ + BRect r = m_window->Frame(); + return WKRectMake(r.left, r.top, r.Width(), r.Height()); +} + +void PlatformWebView::setWindowFrame(WKRect frame) +{ + m_window->MoveTo(frame.origin.x, frame.origin.y); + m_window->ResizeTo(frame.size.width, frame.size.height); +} + +void PlatformWebView::addChromeInputField() +{ +} + +void PlatformWebView::removeChromeInputField() +{ +} + +void PlatformWebView::makeWebViewFirstResponder() +{ +} + +void PlatformWebView::changeWindowScaleIfNeeded(float) +{ +} + +void PlatformWebView::didInitializeClients() +{ +} + +} diff --git a/Tools/WebKitTestRunner/haiku/TestControllerHaiku.cpp b/Tools/WebKitTestRunner/haiku/TestControllerHaiku.cpp new file mode 100644 index 000000000000..20cdc5455958 --- /dev/null +++ b/Tools/WebKitTestRunner/haiku/TestControllerHaiku.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014 Haiku, inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "TestController.h" + +#include +#include "NotImplemented.h" +#include "PlatformWebView.h" +#include "WebView.h" + +namespace WTR { + +void TestController::notifyDone() +{ + notImplemented(); +} + +void TestController::platformInitialize() +{ + const char* isDebugging = getenv("WEB_PROCESS_CMD_PREFIX"); + if (isDebugging && *isDebugging) { + m_useWaitToDumpWatchdogTimer = false; + m_forceNoTimeout = true; + } + + new BApplication("application/x-vnd.haiku-webkit.testrunner"); +} + +void TestController::platformDestroy() +{ + delete be_app; +} + +void TestController::platformWillRunTest(const TestInvocation&) +{ +} + +unsigned TestController::imageCountInGeneralPasteboard() const +{ + // FIXME implement (scan BClipboard?) + return 0; +} + +void TestController::platformRunUntil(bool& condition, double timeout) +{ + // FIXME condition (?), timeout (via BMessageRunnner) + notImplemented(); + + be_app->Run(); +} + +static const char* getEnvironmentVariableOrExit(const char* variableName) +{ + const char* value = getenv(variableName); + if (!value) { + fprintf(stderr, "%s environment variable not found\n", variableName); + exit(0); + } + + return value; +} + +void TestController::initializeInjectedBundlePath() +{ + const char* bundlePath = getEnvironmentVariableOrExit("TEST_RUNNER_INJECTED_BUNDLE_FILENAME"); + m_injectedBundlePath.adopt(WKStringCreateWithUTF8CString(bundlePath)); +} + +void TestController::initializeTestPluginDirectory() +{ + const char* pluginPath = getEnvironmentVariableOrExit("TEST_RUNNER_PLUGIN_PATH"); + m_testPluginDirectory.adopt(WKStringCreateWithUTF8CString(pluginPath)); +} + +void TestController::platformInitializeContext() +{ +} + +void TestController::setHidden(bool hidden) +{ + PlatformWKView view = mainWebView()->platformView(); + + if (!view) { + fprintf(stderr, "ERROR: view is null.\n"); + return; + } + + if (hidden) + view->Hide(); + else + view->Show(); +} + +void TestController::runModal(PlatformWebView*) +{ + // FIXME: Need to implement this to test showModalDialog. +} + +const char* TestController::platformLibraryPathForTesting() +{ + return 0; +} + +} diff --git a/Tools/WebKitTestRunner/haiku/TestInvocationHaiku.cpp b/Tools/WebKitTestRunner/haiku/TestInvocationHaiku.cpp new file mode 100644 index 000000000000..d7e1e6722e16 --- /dev/null +++ b/Tools/WebKitTestRunner/haiku/TestInvocationHaiku.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * (C) 2011 Brent Fulgham . All rights reserved. + * (C) 2010, 2011 Igalia S.L + * (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TestInvocation.h" + +#include +#include "NotImplemented.h" +#include "PixelDumpSupport.h" +#include "PlatformWebView.h" +#include "TestController.h" +#include +#include +#include +#include +#include + +namespace WTR { + +void computeMD5HashStringForCairoSurface(BBitmap* surface, char hashString[33]) +{ + ASSERT(surface->ColorSpace() == B_RGB32); // ImageDiff assumes 32 bit RGBA, we must as well. + + BRect r = surface->Bounds(); + size_t pixelsHigh = r.Height(); + size_t pixelsWide = r.Width(); + size_t bytesPerRow = surface->BytesPerRow(); + + MD5 md5Context; + unsigned char* bitmapData = static_cast(surface->Bits()); + for (size_t row = 0; row < pixelsHigh; ++row) { + md5Context.addBytes(bitmapData, 4 * pixelsWide); + bitmapData += bytesPerRow; + } + MD5::Digest hash; + md5Context.checksum(hash); + + snprintf(hashString, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], + hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]); +} + +#if 0 +static status_t writeFunction(void* closure, const unsigned char* data, unsigned length) +{ + Vector* in = reinterpret_cast*>(closure); + in->append(data, length); + return B_OK; +} +#endif + +static void dumpBitmap(BBitmap* surface, const char* checksum) +{ + notImplemented(); +#if 0 + Vector pixelData; + cairo_surface_write_to_png_stream(surface, writeFunction, &pixelData); + const size_t dataLength = pixelData.size(); + const unsigned char* data = pixelData.data(); + + printPNG(data, dataLength, checksum); +#endif +} + +void TestInvocation::dumpPixelsAndCompareWithExpected(WKImageRef wkImage, WKArrayRef repaintRects) +{ + notImplemented(); +#if 0 +#if PLATFORM(EFL) || PLATFORM(GTK) + UNUSED_PARAM(wkImage); + cairo_surface_t* surface = WKImageCreateCairoSurface(TestController::shared().mainWebView()->windowSnapshotImage().get()); +#else + cairo_surface_t* surface = WKImageCreateCairoSurface(wkImage); +#endif + + if (repaintRects) + paintRepaintRectOverlay(surface, repaintRects); + + char actualHash[33]; + computeMD5HashStringForCairoSurface(surface, actualHash); + if (!compareActualHashToExpectedAndDumpResults(actualHash)) + dumpBitmap(surface, actualHash); + + cairo_surface_destroy(surface); +#endif +} + +} // namespace WTR + diff --git a/Tools/WebKitTestRunner/haiku/main.cpp b/Tools/WebKitTestRunner/haiku/main.cpp new file mode 100644 index 000000000000..6d632ecca682 --- /dev/null +++ b/Tools/WebKitTestRunner/haiku/main.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Haiku, inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "TestController.h" +#include +#include + +int main(int argc, char** argv) +{ + WTFInstallReportBacktraceOnCrashHook(); + + WTR::TestController controller(argc, const_cast(argv)); + + return 0; +} diff --git a/Tools/haiku/libroot_debug.sh b/Tools/haiku/libroot_debug.sh new file mode 100755 index 000000000000..8046fd258b55 --- /dev/null +++ b/Tools/haiku/libroot_debug.sh @@ -0,0 +1,2 @@ +#!sh +LD_PRELOAD=/system/lib/x86/libroot_debug.so $* diff --git a/Tools/haiku/mimefix.sh b/Tools/haiku/mimefix.sh new file mode 100644 index 000000000000..88b0c6fcdc55 --- /dev/null +++ b/Tools/haiku/mimefix.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# This script fixes some known issues with MIME type detection in Haiku. The MIME sniffer does not +# always make the best guess on the type of files, and the test suite relies on the types being +# correct. So, let's fix them! + +set TESTS=BEOS:TYPE LayoutTests/webgl/1.0.3/resources/webgl_test_files/conformance/*/*.html LayoutTests/css3/filters/regions-expanding.html LayoutTests/editing/caret/*.html + +rmattr -f BEOS:TYPE $TESTS +addattr BEOS:TYPE $TESTS diff --git a/Tools/haiku/webkit-buildloop.sh b/Tools/haiku/webkit-buildloop.sh new file mode 100755 index 000000000000..a72ad7445e65 --- /dev/null +++ b/Tools/haiku/webkit-buildloop.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +cd /path/to/working/dir + +function build_webkit { + rm -r JavaScriptCore/DerivedSources + rm -r WebCore/DerivedSources + rm -r WebKitBuild + /bin/sh WebKitTools/haiku/make-generated-sources.sh > logs/buildlog_$1.log 2>&1 + NDEBUG=1 jam -qj3 WebPositive >> logs/buildlog_$1.log 2>&1 + if [ $? == 0 ] + then + cp WebKitBuild/Release/JavaScriptCore/libjavascriptcore.so package/WebPositive/lib + cp WebKitBuild/Release/WebCore/libwebcore.so package/WebPositive/lib + cp WebKitBuild/Release/WebKit/libwebkit.so package/WebPositive/lib + cp WebKitBuild/Release/WebKit/WebPositive package/WebPositive + cd package + zip -r WebPositive.zip WebPositive + cd .. + cp package/WebPositive.zip /Source/trac/webkit/htdocs/nightlies/WebPositive-r$1.zip + generate-index.sh /target/dir/nightlies http://base.url/ + fi + cp logs/buildlog_$1.log /target/dir/buildlogs/buildlog_$1.txt + generate-index.sh /target/dir/buildlogs http://base.url/ +} + +while true +do + oldRevision=$(svn info | grep Revision | cut -d" " -f 2) + svn update > /dev/null 2>&1 + newRevision=$(svn info | grep Revision | cut -d" " -f 2) + if [ $oldRevision != $newRevision ] + then + build_webkit $newRevision + fi + + sleep 60 +done +