diff options
Diffstat (limited to 'Source/WebKit2/WebProcess')
227 files changed, 32342 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.cpp b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.cpp new file mode 100644 index 0000000..36757d6 --- /dev/null +++ b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.cpp @@ -0,0 +1,104 @@ +/* + * 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 "AuthenticationManager.h" + +#include "MessageID.h" +#include "WebCoreArgumentCoders.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/AuthenticationChallenge.h> +#include <WebCore/AuthenticationClient.h> + +namespace WebKit { + +static uint64_t generateAuthenticationChallengeID() +{ + static uint64_t uniqueAuthenticationChallengeID = 1; + return uniqueAuthenticationChallengeID++; +} + +AuthenticationManager& AuthenticationManager::shared() +{ + static AuthenticationManager& manager = *new AuthenticationManager; + return manager; +} + +AuthenticationManager::AuthenticationManager() +{ +} + +void AuthenticationManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveAuthenticationManagerMessage(connection, messageID, arguments); +} + +void AuthenticationManager::didReceiveAuthenticationChallenge(WebFrame* frame, const WebCore::AuthenticationChallenge& authenticationChallenge) +{ + ASSERT(frame); + ASSERT(frame->page()); + + uint64_t id = generateAuthenticationChallengeID(); + m_challenges.set(id, authenticationChallenge); + + WebProcess::shared().connection()->send(Messages::WebPageProxy::DidReceiveAuthenticationChallenge(frame->frameID(), authenticationChallenge, id), frame->page()->pageID()); +} + +void AuthenticationManager::useCredentialForChallenge(uint64_t challengeID, const WebCore::Credential& credential) +{ + WebCore::AuthenticationChallenge challenge = m_challenges.take(challengeID); + ASSERT(!challenge.isNull()); + WebCore::AuthenticationClient* coreClient = challenge.authenticationClient(); + if (!coreClient) + return; + + coreClient->receivedCredential(challenge, credential); +} + +void AuthenticationManager::continueWithoutCredentialForChallenge(uint64_t challengeID) +{ + WebCore::AuthenticationChallenge challenge = m_challenges.take(challengeID); + ASSERT(!challenge.isNull()); + WebCore::AuthenticationClient* coreClient = challenge.authenticationClient(); + if (!coreClient) + return; + + coreClient->receivedRequestToContinueWithoutCredential(challenge); +} + +void AuthenticationManager::cancelChallenge(uint64_t challengeID) +{ + WebCore::AuthenticationChallenge challenge = m_challenges.take(challengeID); + ASSERT(!challenge.isNull()); + WebCore::AuthenticationClient* coreClient = challenge.authenticationClient(); + if (!coreClient) + return; + + coreClient->receivedCancellation(challenge); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.h b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.h new file mode 100644 index 0000000..ce5ff1c --- /dev/null +++ b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.h @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#ifndef AuthenticationManager_h +#define AuthenticationManager_h + +#include <wtf/HashMap.h> + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebCore { + class AuthenticationChallenge; + class Credential; +} + +namespace WebKit { + +class WebFrame; + +class AuthenticationManager { + WTF_MAKE_NONCOPYABLE(AuthenticationManager); + +public: + static AuthenticationManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void didReceiveAuthenticationChallenge(WebFrame*, const WebCore::AuthenticationChallenge&); + + void useCredentialForChallenge(uint64_t challengeID, const WebCore::Credential&); + void continueWithoutCredentialForChallenge(uint64_t challengeID); + void cancelChallenge(uint64_t challengeID); + +private: + AuthenticationManager(); + + void didReceiveAuthenticationManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + typedef HashMap<uint64_t, WebCore::AuthenticationChallenge> AuthenticationChallengeMap; + AuthenticationChallengeMap m_challenges; +}; + +} // namespace WebKit + +#endif // AuthenticationManager_h diff --git a/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.messages.in b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.messages.in new file mode 100644 index 0000000..264cd55 --- /dev/null +++ b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.messages.in @@ -0,0 +1,27 @@ +# 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. + +messages -> AuthenticationManager { + void UseCredentialForChallenge(uint64_t challengeID, WebCore::Credential credential); + void ContinueWithoutCredentialForChallenge(uint64_t challengeID); + void CancelChallenge(uint64_t challengeID); +} diff --git a/Source/WebKit2/WebProcess/Downloads/Download.cpp b/Source/WebKit2/WebProcess/Downloads/Download.cpp new file mode 100644 index 0000000..3cb5588 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/Download.cpp @@ -0,0 +1,132 @@ +/* + * 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 "Download.h" + +#include "Connection.h" +#include "DataReference.h" +#include "DownloadProxyMessages.h" +#include "DownloadManager.h" +#include "SandboxExtension.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcess.h" + +using namespace WebCore; + +namespace WebKit { + +PassOwnPtr<Download> Download::create(uint64_t downloadID, const ResourceRequest& request) +{ + return adoptPtr(new Download(downloadID, request)); +} + +Download::Download(uint64_t downloadID, const ResourceRequest& request) + : m_downloadID(downloadID) + , m_request(request) +{ + ASSERT(m_downloadID); +} + +Download::~Download() +{ + platformInvalidate(); +} + +CoreIPC::Connection* Download::connection() const +{ + return WebProcess::shared().connection(); +} + +void Download::didStart() +{ + send(Messages::DownloadProxy::DidStart(m_request)); +} + +void Download::didReceiveResponse(const ResourceResponse& response) +{ + send(Messages::DownloadProxy::DidReceiveResponse(response)); +} + +void Download::didReceiveData(uint64_t length) +{ + send(Messages::DownloadProxy::DidReceiveData(length)); +} + +bool Download::shouldDecodeSourceDataOfMIMEType(const String& mimeType) +{ + bool result; + if (!sendSync(Messages::DownloadProxy::ShouldDecodeSourceDataOfMIMEType(mimeType), Messages::DownloadProxy::ShouldDecodeSourceDataOfMIMEType::Reply(result))) + return true; + + return result; +} + +String Download::decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite) +{ + String destination; + SandboxExtension::Handle sandboxExtensionHandle; + if (!sendSync(Messages::DownloadProxy::DecideDestinationWithSuggestedFilename(filename), Messages::DownloadProxy::DecideDestinationWithSuggestedFilename::Reply(destination, allowOverwrite, sandboxExtensionHandle))) + return String(); + + m_sandboxExtension = SandboxExtension::create(sandboxExtensionHandle); + if (m_sandboxExtension) + m_sandboxExtension->consume(); + + return destination; +} + +void Download::didCreateDestination(const String& path) +{ + send(Messages::DownloadProxy::DidCreateDestination(path)); +} + +void Download::didFinish() +{ + send(Messages::DownloadProxy::DidFinish()); + + if (m_sandboxExtension) + m_sandboxExtension->invalidate(); + DownloadManager::shared().downloadFinished(this); +} + +void Download::didFail(const ResourceError& error, const CoreIPC::DataReference& resumeData) +{ + send(Messages::DownloadProxy::DidFail(error, resumeData)); + + if (m_sandboxExtension) + m_sandboxExtension->invalidate(); + DownloadManager::shared().downloadFinished(this); +} + +void Download::didCancel(const CoreIPC::DataReference& resumeData) +{ + send(Messages::DownloadProxy::DidCancel(resumeData)); + + if (m_sandboxExtension) + m_sandboxExtension->invalidate(); + DownloadManager::shared().downloadFinished(this); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/Download.h b/Source/WebKit2/WebProcess/Downloads/Download.h new file mode 100644 index 0000000..2319ec7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/Download.h @@ -0,0 +1,112 @@ +/* + * 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. + */ + +#ifndef Download_h +#define Download_h + +#include "MessageSender.h" +#include <WebCore/ResourceRequest.h> +#include <wtf/Noncopyable.h> +#include <wtf/PassOwnPtr.h> + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#ifdef __OBJC__ +@class NSURLDownload; +@class WKDownloadAsDelegate; +#else +class NSURLDownload; +class WKDownloadAsDelegate; +#endif +#endif + +#if USE(CFNETWORK) +#include <CFNetwork/CFURLDownloadPriv.h> +#endif + +namespace CoreIPC { + class DataReference; +} + +namespace WebCore { + class ResourceError; + class ResourceHandle; + class ResourceResponse; +} + +namespace WebKit { + +class SandboxExtension; +class WebPage; + +class Download : public CoreIPC::MessageSender<Download> { + WTF_MAKE_NONCOPYABLE(Download); + +public: + static PassOwnPtr<Download> create(uint64_t downloadID, const WebCore::ResourceRequest&); + ~Download(); + + // Used by MessageSender. + CoreIPC::Connection* connection() const; + uint64_t destinationID() const { return downloadID(); } + + void start(WebPage* initiatingWebPage); + void startWithHandle(WebPage* initiatingPage, WebCore::ResourceHandle*, const WebCore::ResourceRequest& initialRequest, const WebCore::ResourceResponse&); + void cancel(); + + uint64_t downloadID() const { return m_downloadID; } + + void didStart(); + void didReceiveResponse(const WebCore::ResourceResponse&); + void didReceiveData(uint64_t length); + bool shouldDecodeSourceDataOfMIMEType(const String& mimeType); + String decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite); + void didCreateDestination(const String& path); + void didFinish(); + void didFail(const WebCore::ResourceError&, const CoreIPC::DataReference& resumeData); + void didCancel(const CoreIPC::DataReference& resumeData); + +private: + Download(uint64_t downloadID, const WebCore::ResourceRequest&); + + void platformInvalidate(); + + uint64_t m_downloadID; + WebCore::ResourceRequest m_request; + + RefPtr<SandboxExtension> m_sandboxExtension; + +#if PLATFORM(MAC) + RetainPtr<NSURLDownload> m_nsURLDownload; + RetainPtr<WKDownloadAsDelegate> m_delegate; +#endif +#if USE(CFNETWORK) + RetainPtr<CFURLDownloadRef> m_download; +#endif +}; + +} // namespace WebKit + +#endif // Download_h diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp new file mode 100644 index 0000000..e65883a --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp @@ -0,0 +1,83 @@ +/* + * 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 "DownloadManager.h" + +#include "Download.h" +#include "WebProcess.h" +#include <wtf/StdLibExtras.h> + +using namespace WebCore; + +namespace WebKit { + +DownloadManager& DownloadManager::shared() +{ + DEFINE_STATIC_LOCAL(DownloadManager, downloadManager, ()); + return downloadManager; +} + +DownloadManager::DownloadManager() +{ +} + +void DownloadManager::startDownload(uint64_t downloadID, WebPage* initiatingPage, const ResourceRequest& request) +{ + OwnPtr<Download> download = Download::create(downloadID, request); + download->start(initiatingPage); + + ASSERT(!m_downloads.contains(downloadID)); + m_downloads.set(downloadID, download.leakPtr()); +} + +void DownloadManager::convertHandleToDownload(uint64_t downloadID, WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response) +{ + OwnPtr<Download> download = Download::create(downloadID, request); + + download->startWithHandle(initiatingPage, handle, initialRequest, response); + ASSERT(!m_downloads.contains(downloadID)); + m_downloads.set(downloadID, download.leakPtr()); +} + +void DownloadManager::cancelDownload(uint64_t downloadID) +{ + Download* download = m_downloads.get(downloadID); + if (!download) + return; + + download->cancel(); +} + +void DownloadManager::downloadFinished(Download* download) +{ + ASSERT(m_downloads.contains(download->downloadID())); + m_downloads.remove(download->downloadID()); + + delete download; + + WebProcess::shared().shutdownIfPossible(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.h b/Source/WebKit2/WebProcess/Downloads/DownloadManager.h new file mode 100644 index 0000000..1f27b86 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef DownloadManager_h +#define DownloadManager_h + +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { + class ResourceHandle; + class ResourceRequest; + class ResourceResponse; +} + +namespace WebKit { + +class Download; +class WebPage; + +class DownloadManager { + WTF_MAKE_NONCOPYABLE(DownloadManager); + +public: + static DownloadManager& shared(); + + void startDownload(uint64_t downloadID, WebPage* initiatingPage, const WebCore::ResourceRequest&); + void convertHandleToDownload(uint64_t downloadID, WebPage* initiatingPage, WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest& initialRequest, const WebCore::ResourceResponse&); + + void cancelDownload(uint64_t downloadID); + + void downloadFinished(Download*); + bool isDownloading() const { return !m_downloads.isEmpty(); } + +private: + DownloadManager(); + + HashMap<uint64_t, Download*> m_downloads; +}; + +} // namespace WebKit + +#endif // DownloadManager_h diff --git a/Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp b/Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp new file mode 100644 index 0000000..08c381f --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/cf/DownloadCFNet.cpp @@ -0,0 +1,185 @@ +/* + * 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 "Download.h" + +#include "DataReference.h" +#include "NotImplemented.h" + +#pragma warning(push, 0) +#include <WebCore/LoaderRunLoopCF.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceHandle.h> +#include <WebCore/ResourceResponse.h> +#pragma warning(pop) + +using namespace WebCore; + +namespace WebKit { + +// CFURLDownload Callbacks ---------------------------------------------------------------- +static void didStartCallback(CFURLDownloadRef download, const void* clientInfo); +static CFURLRequestRef willSendRequestCallback(CFURLDownloadRef download, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void* clientInfo); +static void didReceiveAuthenticationChallengeCallback(CFURLDownloadRef download, CFURLAuthChallengeRef challenge, const void* clientInfo); +static void didReceiveResponseCallback(CFURLDownloadRef download, CFURLResponseRef response, const void* clientInfo); +static void willResumeWithResponseCallback(CFURLDownloadRef download, CFURLResponseRef response, UInt64 startingByte, const void* clientInfo); +static void didReceiveDataCallback(CFURLDownloadRef download, CFIndex length, const void* clientInfo); +static Boolean shouldDecodeDataOfMIMETypeCallback(CFURLDownloadRef download, CFStringRef encodingType, const void* clientInfo); +static void decideDestinationWithSuggestedObjectNameCallback(CFURLDownloadRef download, CFStringRef objectName, const void* clientInfo); +static void didCreateDestinationCallback(CFURLDownloadRef download, CFURLRef path, const void* clientInfo); +static void didFinishCallback(CFURLDownloadRef download, const void* clientInfo); +static void didFailCallback(CFURLDownloadRef download, CFErrorRef error, const void* clientInfo); + +void Download::start(WebPage* initiatingWebPage) +{ + ASSERT(!m_download); + + CFURLRequestRef cfRequest = m_request.cfURLRequest(); + + CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback, + didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback, + decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback}; + m_download.adoptCF(CFURLDownloadCreate(0, cfRequest, &client)); + + // FIXME: Allow this to be changed by the client. + CFURLDownloadSetDeletesUponFailure(m_download.get(), false); + + CFURLDownloadScheduleWithCurrentMessageQueue(m_download.get()); + CFURLDownloadScheduleDownloadWithRunLoop(m_download.get(), loaderRunLoop(), kCFRunLoopDefaultMode); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& initialRequest, const ResourceResponse& response) +{ + ASSERT(!m_download); + + CFURLConnectionRef connection = handle->connection(); + if (!connection) + return; + + CFURLDownloadClient client = {0, this, 0, 0, 0, didStartCallback, willSendRequestCallback, didReceiveAuthenticationChallengeCallback, + didReceiveResponseCallback, willResumeWithResponseCallback, didReceiveDataCallback, shouldDecodeDataOfMIMETypeCallback, + decideDestinationWithSuggestedObjectNameCallback, didCreateDestinationCallback, didFinishCallback, didFailCallback}; + + m_download.adoptCF(CFURLDownloadCreateAndStartWithLoadingConnection(0, connection, initialRequest.cfURLRequest(), response.cfURLResponse(), &client)); + + // It is possible for CFURLDownloadCreateAndStartWithLoadingConnection() to fail if the passed in CFURLConnection is not in a "downloadable state" + // However, we should never hit that case + if (!m_download) + ASSERT_NOT_REACHED(); + + // The CFURLDownload either starts successfully and retains the CFURLConnection, + // or it fails to creating and we have a now-useless connection with a dangling ref. + // Either way, we need to release the connection to balance out ref counts + handle->releaseConnectionForDownload(); + CFRelease(connection); +} + +void Download::cancel() +{ + notImplemented(); +} + +void Download::platformInvalidate() +{ + m_download = nullptr; +} + +// CFURLDownload Callbacks ---------------------------------------------------------------- +static Download* downloadFromClientInfo(const void* clientInfo) +{ + return reinterpret_cast<Download*>(const_cast<void*>(clientInfo)); +} + +void didStartCallback(CFURLDownloadRef, const void* clientInfo) +{ + downloadFromClientInfo(clientInfo)->didStart(); +} + +CFURLRequestRef willSendRequestCallback(CFURLDownloadRef, CFURLRequestRef request, CFURLResponseRef redirectionResponse, const void* clientInfo) +{ + // CFNetwork requires us to return a retained request. + CFRetain(request); + return request; +} + +void didReceiveAuthenticationChallengeCallback(CFURLDownloadRef, CFURLAuthChallengeRef challenge, const void* clientInfo) +{ + // FIXME: implement. + notImplemented(); +} + +void didReceiveResponseCallback(CFURLDownloadRef, CFURLResponseRef response, const void* clientInfo) +{ + downloadFromClientInfo(clientInfo)->didReceiveResponse(ResourceResponse(response)); +} + +void willResumeWithResponseCallback(CFURLDownloadRef, CFURLResponseRef response, UInt64 startingByte, const void* clientInfo) +{ + // FIXME: implement. + notImplemented(); +} + +void didReceiveDataCallback(CFURLDownloadRef, CFIndex length, const void* clientInfo) +{ + downloadFromClientInfo(clientInfo)->didReceiveData(length); +} + +Boolean shouldDecodeDataOfMIMETypeCallback(CFURLDownloadRef, CFStringRef encodingType, const void* clientInfo) +{ + return downloadFromClientInfo(clientInfo)->shouldDecodeSourceDataOfMIMEType(encodingType); +} + +void decideDestinationWithSuggestedObjectNameCallback(CFURLDownloadRef cfURLDownloadRef, CFStringRef objectName, const void* clientInfo) +{ + Download* download = downloadFromClientInfo(clientInfo); + bool allowOverwrite; + String destination = download->decideDestinationWithSuggestedFilename(objectName, allowOverwrite); + if (destination.isNull()) + return; + + RetainPtr<CFStringRef> cfPath(AdoptCF, CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar*>(destination.characters()), destination.length(), kCFAllocatorNull)); + RetainPtr<CFURLRef> pathURL(AdoptCF, CFURLCreateWithFileSystemPath(0, cfPath.get(), kCFURLWindowsPathStyle, false)); + CFURLDownloadSetDestination(cfURLDownloadRef, pathURL.get(), allowOverwrite); +} + +void didCreateDestinationCallback(CFURLDownloadRef, CFURLRef url, const void* clientInfo) +{ + RetainPtr<CFStringRef> path(AdoptCF, CFURLCopyFileSystemPath(url, kCFURLWindowsPathStyle)); + String result(path.get()); + downloadFromClientInfo(clientInfo)->didCreateDestination(result); +} + +void didFinishCallback(CFURLDownloadRef, const void* clientInfo) +{ + downloadFromClientInfo(clientInfo)->didFinish(); +} + +void didFailCallback(CFURLDownloadRef, CFErrorRef error, const void* clientInfo) +{ + CoreIPC::DataReference dataReference(0, 0); + downloadFromClientInfo(clientInfo)->didFail(ResourceError(error), dataReference); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp b/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp new file mode 100644 index 0000000..25ed351 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.org> + * + * 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 "Download.h" + +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +void Download::start(WebPage* initiatingWebPage) +{ + notImplemented(); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle*, const ResourceRequest& initialRequest, const ResourceResponse&) +{ + notImplemented(); +} + +void Download::cancel() +{ + notImplemented(); +} + +void Download::platformInvalidate() +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm new file mode 100644 index 0000000..6839020 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm @@ -0,0 +1,287 @@ +/* + * 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 "Download.h" + +#include <WebCore/BackForwardController.h> +#include <WebCore/HistoryItem.h> +#include <WebCore/Page.h> +#include <WebCore/ResourceHandle.h> +#include <WebCore/ResourceResponse.h> +#include "DataReference.h" +#include "NotImplemented.h" +#include "WebPage.h" + +@interface NSURLDownload (WebNSURLDownloadDetails) ++(id)_downloadWithLoadingConnection:(NSURLConnection *)connection + request:(NSURLRequest *)request + response:(NSURLResponse *)r + delegate:(id)delegate + proxy:(id)proxy; +- (void)_setOriginatingURL:(NSURL *)originatingURL; +@end + +@interface WKDownloadAsDelegate : NSObject <NSURLConnectionDelegate> { + WebKit::Download* _download; +} +- (id)initWithDownload:(WebKit::Download*)download; +- (void)invalidate; +@end + +using namespace WebCore; + +namespace WebKit { + +static KURL originatingURLFromBackForwardList(WebPage *webPage) +{ + if (!webPage) + return KURL(); + + Page* page = webPage->corePage(); + if (!page) + return KURL(); + + KURL originalURL; + int backCount = page->backForward()->backCount(); + for (int backIndex = 0; backIndex <= backCount; backIndex++) { + // FIXME: At one point we had code here to check a "was user gesture" flag. + // Do we need to restore that logic? + HistoryItem* historyItem = page->backForward()->itemAtIndex(-backIndex); + if (!historyItem) + continue; + + originalURL = historyItem->originalURL(); + if (!originalURL.isNull()) + return originalURL; + } + + return KURL(); +} + +static void setOriginalURLForDownload(WebPage *webPage, NSURLDownload *download, const ResourceRequest& initialRequest) +{ + KURL originalURL; + + // If there was no referrer, don't traverse the back/forward history + // since this download was initiated directly. <rdar://problem/5294691> + if (!initialRequest.httpReferrer().isNull()) { + // find the first item in the history that was originated by the user + originalURL = originatingURLFromBackForwardList(webPage); + } + + if (originalURL.isNull()) + originalURL = initialRequest.url(); + + NSURL *originalNSURL = originalURL; + + NSString *scheme = [originalNSURL scheme]; + NSString *host = [originalNSURL host]; + if (scheme && host && [scheme length] && [host length]) { + NSNumber *port = [originalNSURL port]; + if (port && [port intValue] < 0) + port = nil; + RetainPtr<NSString> hostOnlyURLString; + if (port) + hostOnlyURLString.adoptNS([[NSString alloc] initWithFormat:@"%@://%@:%d", scheme, host, [port intValue]]); + else + hostOnlyURLString.adoptNS([[NSString alloc] initWithFormat:@"%@://%@", scheme, host]); + + RetainPtr<NSURL> hostOnlyURL = [[NSURL alloc] initWithString:hostOnlyURLString.get()]; + + ASSERT([download respondsToSelector:@selector(_setOriginatingURL:)]); + [download _setOriginatingURL:hostOnlyURL.get()]; + } +} + +void Download::start(WebPage* initiatingPage) +{ + ASSERT(!m_nsURLDownload); + ASSERT(!m_delegate); + + m_delegate.adoptNS([[WKDownloadAsDelegate alloc] initWithDownload:this]); + m_nsURLDownload.adoptNS([[NSURLDownload alloc] initWithRequest:m_request.nsURLRequest() delegate:m_delegate.get()]); + + // FIXME: Allow this to be changed by the client. + [m_nsURLDownload.get() setDeletesFileUponFailure:NO]; + + setOriginalURLForDownload(initiatingPage, m_nsURLDownload.get(), m_request); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceRequest& initialRequest, const ResourceResponse& response) +{ + ASSERT(!m_nsURLDownload); + ASSERT(!m_delegate); + + id proxy = handle->releaseProxy(); + ASSERT(proxy); + + m_delegate.adoptNS([[WKDownloadAsDelegate alloc] initWithDownload:this]); + m_nsURLDownload = [NSURLDownload _downloadWithLoadingConnection:handle->connection() + request:m_request.nsURLRequest() + response:response.nsURLResponse() + delegate:m_delegate.get() + proxy:proxy]; + + // FIXME: Allow this to be changed by the client. + [m_nsURLDownload.get() setDeletesFileUponFailure:NO]; + + setOriginalURLForDownload(initiatingPage, m_nsURLDownload.get(), initialRequest); +} + +void Download::cancel() +{ + [m_nsURLDownload.get() cancel]; + + RetainPtr<NSData> resumeData = [m_nsURLDownload.get() resumeData]; + didCancel(CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([resumeData.get() bytes]), [resumeData.get() length])); +} + +void Download::platformInvalidate() +{ + ASSERT(m_nsURLDownload); + ASSERT(m_delegate); + + [m_delegate.get() invalidate]; + m_delegate = nullptr; + m_nsURLDownload = nullptr; +} + +} // namespace WebKit + +@implementation WKDownloadAsDelegate + +- (id)initWithDownload:(WebKit::Download*)download +{ + self = [super init]; + if (!self) + return nil; + + _download = download; + return self; +} + +- (void)invalidate +{ + _download = 0; +} + +- (void)downloadDidBegin:(NSURLDownload *)download +{ + if (_download) + _download->didStart(); +} + +- (NSURLRequest *)download:(NSURLDownload *)download willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse +{ + return request; +} + +- (BOOL)download:(NSURLDownload *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace +{ + // FIXME: Implement. + notImplemented(); + return NO; +} + +- (void)download:(NSURLDownload *)download didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge +{ + // FIXME: Implement. + notImplemented(); +} + +- (void)download:(NSURLDownload *)download didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge +{ + // FIXME: Implement. + notImplemented(); +} + +- (BOOL)downloadShouldUseCredentialStorage:(NSURLDownload *)download +{ + // FIXME: Implement. + notImplemented(); + return YES; +} + +- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response +{ + if (_download) + _download->didReceiveResponse(response); +} + +- (void)download:(NSURLDownload *)download willResumeWithResponse:(NSURLResponse *)response fromByte:(long long)startingByte +{ + // FIXME: Implement. + notImplemented(); +} + +- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(NSUInteger)length +{ + if (_download) + _download->didReceiveData(length); +} + +- (BOOL)download:(NSURLDownload *)download shouldDecodeSourceDataOfMIMEType:(NSString *)encodingType +{ + if (_download) + return _download->shouldDecodeSourceDataOfMIMEType(encodingType); + + return YES; +} + +- (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename +{ + String destination; + bool allowOverwrite; + if (_download) + destination = _download->decideDestinationWithSuggestedFilename(filename, allowOverwrite); + + if (!destination.isNull()) + [download setDestination:destination allowOverwrite:allowOverwrite]; +} + +- (void)download:(NSURLDownload *)download didCreateDestination:(NSString *)path +{ + if (_download) + _download->didCreateDestination(path); +} + +- (void)downloadDidFinish:(NSURLDownload *)download +{ + if (_download) + _download->didFinish(); +} + +- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error +{ + if (!_download) + return; + + RetainPtr<NSData> resumeData = [download resumeData]; + CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>([resumeData.get() bytes]), [resumeData.get() length]); + + _download->didFail(error, dataReference); +} + +@end diff --git a/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp b/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp new file mode 100644 index 0000000..34fd60e --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp @@ -0,0 +1,54 @@ +/* + * 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 "Download.h" + +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +void Download::start(WebPage* initiatingWebPage) +{ + notImplemented(); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle*, const ResourceRequest& initialRequest, const ResourceResponse&) +{ + notImplemented(); +} + +void Download::cancel() +{ + notImplemented(); +} + +void Download::platformInvalidate() +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp new file mode 100644 index 0000000..3068d5e --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011 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 "GeolocationPermissionRequestManager.h" + +#include "WebFrame.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include <WebCore/Frame.h> +#include <WebCore/Geolocation.h> +#include <WebCore/SecurityOrigin.h> + +using namespace WebCore; + +namespace WebKit { + +static uint64_t generateGeolocationID() +{ + static uint64_t uniqueGeolocationID = 1; + return uniqueGeolocationID++; +} + +GeolocationPermissionRequestManager::GeolocationPermissionRequestManager(WebPage* page) + : m_page(page) +{ +} + +void GeolocationPermissionRequestManager::startRequestForGeolocation(Geolocation* geolocation) +{ + uint64_t geolocationID = generateGeolocationID(); + + m_geolocationToIDMap.set(geolocation, geolocationID); + m_idToGeolocationMap.set(geolocationID, geolocation); + + + Frame* frame = geolocation->frame(); + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + SecurityOrigin* origin = frame->document()->securityOrigin(); + + m_page->send(Messages::WebPageProxy::RequestGeolocationPermissionForFrame(geolocationID, webFrame->frameID(), origin->databaseIdentifier())); +} + +void GeolocationPermissionRequestManager::cancelRequestForGeolocation(Geolocation* geolocation) +{ + GeolocationToIDMap::iterator it = m_geolocationToIDMap.find(geolocation); + if (it == m_geolocationToIDMap.end()) + return; + + m_geolocationToIDMap.remove(it); + m_idToGeolocationMap.remove(it->second); +} + +void GeolocationPermissionRequestManager::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) +{ + IDToGeolocationMap::iterator it = m_idToGeolocationMap.find(geolocationID); + if (it == m_idToGeolocationMap.end()) + return; + + Geolocation* geolocation = it->second; + geolocation->setIsAllowed(allowed); + + m_idToGeolocationMap.remove(it); + m_geolocationToIDMap.remove(geolocation); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.h b/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.h new file mode 100644 index 0000000..5e37163 --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 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 GeolocationPermissionRequestManager_h +#define GeolocationPermissionRequestManager_h + +#include <wtf/HashMap.h> +#include <wtf/RefPtr.h> + +namespace WebCore { +class Geolocation; +} + +namespace WebKit { + +class WebPage; + +class GeolocationPermissionRequestManager { +public: + explicit GeolocationPermissionRequestManager(WebPage*); + + void startRequestForGeolocation(WebCore::Geolocation*); + void cancelRequestForGeolocation(WebCore::Geolocation*); + + void didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed); + +private: + typedef HashMap<uint64_t, WebCore::Geolocation*> IDToGeolocationMap; + typedef HashMap<WebCore::Geolocation*, uint64_t> GeolocationToIDMap; + IDToGeolocationMap m_idToGeolocationMap; + GeolocationToIDMap m_geolocationToIDMap; + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // GeolocationPermissionRequestManager_h diff --git a/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.cpp b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.cpp new file mode 100644 index 0000000..713ba71 --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 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 "WebGeolocationManager.h" + +#include "WebGeolocationManagerProxyMessages.h" +#include "WebPage.h" +#include "WebProcess.h" + +#if ENABLE(CLIENT_BASED_GEOLOCATION) +#include <WebCore/Geolocation.h> +#include <WebCore/GeolocationController.h> +#include <WebCore/GeolocationError.h> +#include <WebCore/GeolocationPosition.h> +#include <WebCore/Page.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +WebGeolocationManager::WebGeolocationManager(WebProcess* process) + : m_process(process) +{ +} + +WebGeolocationManager::~WebGeolocationManager() +{ +} + +void WebGeolocationManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebGeolocationManagerMessage(connection, messageID, arguments); +} + +void WebGeolocationManager::registerWebPage(WebPage* page) +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + bool wasEmpty = m_pageSet.isEmpty(); + + m_pageSet.add(page); + + if (wasEmpty) + m_process->connection()->send(Messages::WebGeolocationManagerProxy::StartUpdating(), 0); +#endif +} + +void WebGeolocationManager::unregisterWebPage(WebPage* page) +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + m_pageSet.remove(page); + + if (m_pageSet.isEmpty()) + m_process->connection()->send(Messages::WebGeolocationManagerProxy::StopUpdating(), 0); +#endif +} + +void WebGeolocationManager::didChangePosition(const WebGeolocationPosition::Data& data) +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + RefPtr<GeolocationPosition> position = GeolocationPosition::create(data.timestamp, data.latitude, data.longitude, data.accuracy); + + HashSet<WebPage*>::const_iterator it = m_pageSet.begin(); + HashSet<WebPage*>::const_iterator end = m_pageSet.end(); + for (; it != end; ++it) { + WebPage* page = *it; + if (page->corePage()) + page->corePage()->geolocationController()->positionChanged(position.get()); + } +#endif +} + +void WebGeolocationManager::didFailToDeterminePosition() +{ +#if ENABLE(CLIENT_BASED_GEOLOCATION) + // FIXME: Add localized error string. + RefPtr<GeolocationError> error = GeolocationError::create(GeolocationError::PositionUnavailable, /* Localized error string */ String("")); + + HashSet<WebPage*>::const_iterator it = m_pageSet.begin(); + HashSet<WebPage*>::const_iterator end = m_pageSet.end(); + for (; it != end; ++it) { + WebPage* page = *it; + if (page->corePage()) + page->corePage()->geolocationController()->errorOccurred(error.get()); + } +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.h b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.h new file mode 100644 index 0000000..78fbd5a --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 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 WebGeolocationManager_h +#define WebGeolocationManager_h + +#include "MessageID.h" +#include "WebGeolocationPosition.h" +#include <wtf/HashSet.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +} + +namespace WebCore { +class Geolocation; +} + +namespace WebKit { + +class WebProcess; +class WebPage; + +class WebGeolocationManager { + WTF_MAKE_NONCOPYABLE(WebGeolocationManager); +public: + explicit WebGeolocationManager(WebProcess*); + ~WebGeolocationManager(); + + void registerWebPage(WebPage*); + void unregisterWebPage(WebPage*); + + void requestPermission(WebCore::Geolocation*); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + // Implemented in generated WebGeolocationManagerMessageReceiver.cpp + void didReceiveWebGeolocationManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void didChangePosition(const WebGeolocationPosition::Data&); + void didFailToDeterminePosition(); + + WebProcess* m_process; + HashSet<WebPage*> m_pageSet; +}; + +} // namespace WebKit + +#endif // WebGeolocationManager_h diff --git a/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.messages.in b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.messages.in new file mode 100644 index 0000000..f2e9a9d --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.messages.in @@ -0,0 +1,26 @@ +# Copyright (C) 2011 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. + +messages -> WebGeolocationManager { + DidChangePosition(WebKit::WebGeolocationPosition::Data position); + DidFailToDeterminePosition(); +} diff --git a/Source/WebKit2/WebProcess/Info.plist b/Source/WebKit2/WebProcess/Info.plist new file mode 100644 index 0000000..1564066 --- /dev/null +++ b/Source/WebKit2/WebProcess/Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>${BUNDLE_VERSION}, Copyright 2003-2011 Apple Inc.</string> + <key>CFBundleIdentifier</key> + <string>com.apple.${PRODUCT_NAME}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>${SHORT_VERSION_STRING}</string> + <key>CFBundleVersion</key> + <string>${BUNDLE_VERSION}</string> + <key>LSMinimumSystemVersion</key> + <string>${MACOSX_DEPLOYMENT_TARGET}</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> + <key>LSUIElement</key> + <true/> +</dict> +</plist> diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp new file mode 100644 index 0000000..5c4b6e9 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp @@ -0,0 +1,133 @@ +/* + * 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 "WKBundle.h" +#include "WKBundlePrivate.h" + +#include "InjectedBundle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleGetTypeID() +{ + return toAPI(InjectedBundle::APIType); +} + +void WKBundleSetClient(WKBundleRef bundleRef, WKBundleClient * wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(bundleRef)->initializeClient(wkClient); +} + +void WKBundlePostMessage(WKBundleRef bundleRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef) +{ + toImpl(bundleRef)->postMessage(toImpl(messageNameRef)->string(), toImpl(messageBodyRef)); +} + +void WKBundlePostSynchronousMessage(WKBundleRef bundleRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef, WKTypeRef* returnDataRef) +{ + RefPtr<APIObject> returnData; + toImpl(bundleRef)->postSynchronousMessage(toImpl(messageNameRef)->string(), toImpl(messageBodyRef), returnData); + if (returnDataRef) + *returnDataRef = toAPI(returnData.release().leakRef()); +} + +void WKBundleSetShouldTrackVisitedLinks(WKBundleRef bundleRef, bool shouldTrackVisitedLinks) +{ + toImpl(bundleRef)->setShouldTrackVisitedLinks(shouldTrackVisitedLinks); +} + +void WKBundleRemoveAllVisitedLinks(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->removeAllVisitedLinks(); +} + +void WKBundleActivateMacFontAscentHack(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->activateMacFontAscentHack(); +} + +void WKBundleGarbageCollectJavaScriptObjects(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->garbageCollectJavaScriptObjects(); +} + +void WKBundleGarbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(WKBundleRef bundleRef, bool waitUntilDone) +{ + toImpl(bundleRef)->garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(waitUntilDone); +} + +size_t WKBundleGetJavaScriptObjectsCount(WKBundleRef bundleRef) +{ + return toImpl(bundleRef)->javaScriptObjectsCount(); +} + +void WKBundleAddUserScript(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, WKBundleScriptWorldRef scriptWorldRef, WKStringRef sourceRef, WKURLRef urlRef, WKArrayRef whitelistRef, WKArrayRef blacklistRef, WKUserScriptInjectionTime injectionTimeRef, WKUserContentInjectedFrames injectedFramesRef) +{ + toImpl(bundleRef)->addUserScript(toImpl(pageGroupRef), toImpl(scriptWorldRef), toWTFString(sourceRef), toWTFString(urlRef), toImpl(whitelistRef), toImpl(blacklistRef), toUserScriptInjectionTime(injectionTimeRef), toUserContentInjectedFrames(injectedFramesRef)); +} + +void WKBundleAddUserStyleSheet(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, WKBundleScriptWorldRef scriptWorldRef, WKStringRef sourceRef, WKURLRef urlRef, WKArrayRef whitelistRef, WKArrayRef blacklistRef, WKUserContentInjectedFrames injectedFramesRef) +{ + toImpl(bundleRef)->addUserStyleSheet(toImpl(pageGroupRef), toImpl(scriptWorldRef), toWTFString(sourceRef), toWTFString(urlRef), toImpl(whitelistRef), toImpl(blacklistRef), toUserContentInjectedFrames(injectedFramesRef)); +} + +void WKBundleRemoveUserScript(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, WKBundleScriptWorldRef scriptWorldRef, WKURLRef urlRef) +{ + toImpl(bundleRef)->removeUserScript(toImpl(pageGroupRef), toImpl(scriptWorldRef), toWTFString(urlRef)); +} + +void WKBundleRemoveUserStyleSheet(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, WKBundleScriptWorldRef scriptWorldRef, WKURLRef urlRef) +{ + toImpl(bundleRef)->removeUserStyleSheet(toImpl(pageGroupRef), toImpl(scriptWorldRef), toWTFString(urlRef)); +} + +void WKBundleRemoveUserScripts(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, WKBundleScriptWorldRef scriptWorldRef) +{ + toImpl(bundleRef)->removeUserScripts(toImpl(pageGroupRef), toImpl(scriptWorldRef)); +} + +void WKBundleRemoveUserStyleSheets(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, WKBundleScriptWorldRef scriptWorldRef) +{ + toImpl(bundleRef)->removeUserStyleSheets(toImpl(pageGroupRef), toImpl(scriptWorldRef)); +} + +void WKBundleRemoveAllUserContent(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef) +{ + toImpl(bundleRef)->removeAllUserContent(toImpl(pageGroupRef)); +} + +void WKBundleOverrideXSSAuditorEnabledForTestRunner(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->overrideXSSAuditorEnabledForTestRunner(toImpl(pageGroupRef), enabled); +} + +void WKBundleReportException(JSContextRef context, JSValueRef exception) +{ + InjectedBundle::reportException(context, exception); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.h new file mode 100644 index 0000000..24c53b4 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef WKBundle_h +#define WKBundle_h + +#include <JavaScriptCore/JavaScript.h> +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// Client +typedef void (*WKBundleDidCreatePageCallback)(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo); +typedef void (*WKBundleWillDestroyPageCallback)(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo); +typedef void (*WKBundleDidInitializePageGroupCallback)(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, const void* clientInfo); +typedef void (*WKBundleDidReceiveMessageCallback)(WKBundleRef bundle, WKStringRef name, WKTypeRef messageBody, const void* clientInfo); + +struct WKBundleClient { + int version; + const void * clientInfo; + WKBundleDidCreatePageCallback didCreatePage; + WKBundleWillDestroyPageCallback willDestroyPage; + WKBundleDidInitializePageGroupCallback didInitializePageGroup; + WKBundleDidReceiveMessageCallback didReceiveMessage; +}; +typedef struct WKBundleClient WKBundleClient; + +WK_EXPORT WKTypeID WKBundleGetTypeID(); + +WK_EXPORT void WKBundleSetClient(WKBundleRef bundle, WKBundleClient * client); + +WK_EXPORT void WKBundlePostMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody); +WK_EXPORT void WKBundlePostSynchronousMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData); + +WK_EXPORT void WKBundleReportException(JSContextRef, JSValueRef exception); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundle_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleAPICast.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleAPICast.h new file mode 100644 index 0000000..47ac2d6 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleAPICast.h @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#ifndef WKBundleAPICast_h +#define WKBundleAPICast_h + +#include "WKSharedAPICast.h" +#include "WKBundlePage.h" +#include "WKBundlePagePrivate.h" +#include "WKBundlePrivate.h" +#include <WebCore/EditorInsertAction.h> +#include <WebCore/TextAffinity.h> +#include <WebCore/UserContentTypes.h> +#include <WebCore/UserScriptTypes.h> + +namespace WebCore { + class CSSStyleDeclaration; +} + +namespace WebKit { + +class InjectedBundle; +class InjectedBundleBackForwardList; +class InjectedBundleBackForwardListItem; +class InjectedBundleHitTestResult; +class InjectedBundleNodeHandle; +class InjectedBundleRangeHandle; +class InjectedBundleScriptWorld; +class PageOverlay; +class WebFrame; +class WebPage; +class WebPageGroupProxy; + +WK_ADD_API_MAPPING(WKBundleBackForwardListItemRef, InjectedBundleBackForwardListItem) +WK_ADD_API_MAPPING(WKBundleBackForwardListRef, InjectedBundleBackForwardList) +WK_ADD_API_MAPPING(WKBundleCSSStyleDeclarationRef, WebCore::CSSStyleDeclaration) +WK_ADD_API_MAPPING(WKBundleFrameRef, WebFrame) +WK_ADD_API_MAPPING(WKBundleHitTestResultRef, InjectedBundleHitTestResult) +WK_ADD_API_MAPPING(WKBundleNodeHandleRef, InjectedBundleNodeHandle) +WK_ADD_API_MAPPING(WKBundlePageGroupRef, WebPageGroupProxy) +WK_ADD_API_MAPPING(WKBundlePageOverlayRef, PageOverlay) +WK_ADD_API_MAPPING(WKBundlePageRef, WebPage) +WK_ADD_API_MAPPING(WKBundleRangeHandleRef, InjectedBundleRangeHandle) +WK_ADD_API_MAPPING(WKBundleRef, InjectedBundle) +WK_ADD_API_MAPPING(WKBundleScriptWorldRef, InjectedBundleScriptWorld) + +inline WKInsertActionType toAPI(WebCore::EditorInsertAction action) +{ + switch (action) { + case WebCore::EditorInsertActionTyped: + return kWKInsertActionTyped; + break; + case WebCore::EditorInsertActionPasted: + return kWKInsertActionPasted; + break; + case WebCore::EditorInsertActionDropped: + return kWKInsertActionDropped; + break; + } + ASSERT_NOT_REACHED(); + return kWKInsertActionTyped; +} + +inline WKAffinityType toAPI(WebCore::EAffinity affinity) +{ + switch (affinity) { + case WebCore::UPSTREAM: + return kWKAffinityUpstream; + break; + case WebCore::DOWNSTREAM: + return kWKAffinityDownstream; + break; + } + ASSERT_NOT_REACHED(); + return kWKAffinityUpstream; +} + +inline WebCore::UserScriptInjectionTime toUserScriptInjectionTime(WKUserScriptInjectionTime wkInjectedTime) +{ + switch (wkInjectedTime) { + case kWKInjectAtDocumentStart: + return WebCore::InjectAtDocumentStart; + case kWKInjectAtDocumentEnd: + return WebCore::InjectAtDocumentEnd; + } + + ASSERT_NOT_REACHED(); + return WebCore::InjectAtDocumentStart; +} + +inline WebCore::UserContentInjectedFrames toUserContentInjectedFrames(WKUserContentInjectedFrames wkInjectedFrames) +{ + switch (wkInjectedFrames) { + case kWKInjectInAllFrames: + return WebCore::InjectInAllFrames; + case kWKInjectInTopFrameOnly: + return WebCore::InjectInTopFrameOnly; + } + + ASSERT_NOT_REACHED(); + return WebCore::InjectInAllFrames; +} + +} // namespace WebKit + +#endif // WKBundleAPICast_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.cpp new file mode 100644 index 0000000..288c676 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.cpp @@ -0,0 +1,57 @@ +/* + * 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 "WKBundleBackForwardList.h" + +#include "InjectedBundleBackForwardList.h" +#include "InjectedBundleBackForwardListItem.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleBackForwardListGetTypeID() +{ + return toAPI(InjectedBundleBackForwardList::APIType); +} + +WKBundleBackForwardListItemRef WKBundleBackForwardListCopyItemAtIndex(WKBundleBackForwardListRef listRef, int index) +{ + return toAPI(toImpl(listRef)->itemAtIndex(index).leakRef()); +} + +unsigned WKBundleBackForwardListGetBackListCount(WKBundleBackForwardListRef listRef) +{ + return toImpl(listRef)->backListCount(); +} + +unsigned WKBundleBackForwardListGetForwardListCount(WKBundleBackForwardListRef listRef) +{ + return toImpl(listRef)->forwardListCount(); +} + +void WKBundleBackForwardListClear(WKBundleBackForwardListRef listRef) +{ + return toImpl(listRef)->clear(); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.h new file mode 100644 index 0000000..7aa573a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#ifndef WKBundleBackForwardList_h +#define WKBundleBackForwardList_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleBackForwardListGetTypeID(); + +WK_EXPORT WKBundleBackForwardListItemRef WKBundleBackForwardListCopyItemAtIndex(WKBundleBackForwardListRef list, int index); + +WK_EXPORT unsigned WKBundleBackForwardListGetBackListCount(WKBundleBackForwardListRef list); +WK_EXPORT unsigned WKBundleBackForwardListGetForwardListCount(WKBundleBackForwardListRef list); + +WK_EXPORT void WKBundleBackForwardListClear(WKBundleBackForwardListRef list); + +#ifdef __cplusplus +} +#endif + +#endif // WKBundleBackForwardList_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.cpp new file mode 100644 index 0000000..cde15c4 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.cpp @@ -0,0 +1,73 @@ +/* + * 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 "WKBundleBackForwardListItem.h" + +#include "ImmutableArray.h" +#include "InjectedBundleBackForwardListItem.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleBackForwardListItemGetTypeID() +{ + return toAPI(InjectedBundleBackForwardListItem::APIType); +} + +bool WKBundleBackForwardListItemIsSame(WKBundleBackForwardListItemRef itemRef1, WKBundleBackForwardListItemRef itemRef2) +{ + return toImpl(itemRef1)->item() == toImpl(itemRef2)->item(); +} + +WKURLRef WKBundleBackForwardListItemCopyOriginalURL(WKBundleBackForwardListItemRef itemRef) +{ + return toCopiedURLAPI(toImpl(itemRef)->originalURL()); +} + +WKURLRef WKBundleBackForwardListItemCopyURL(WKBundleBackForwardListItemRef itemRef) +{ + return toCopiedURLAPI(toImpl(itemRef)->url()); +} + +WKStringRef WKBundleBackForwardListItemCopyTitle(WKBundleBackForwardListItemRef itemRef) +{ + return toCopiedAPI(toImpl(itemRef)->title()); +} + +WKStringRef WKBundleBackForwardListItemCopyTarget(WKBundleBackForwardListItemRef itemRef) +{ + return toCopiedAPI(toImpl(itemRef)->target()); +} + +bool WKBundleBackForwardListItemIsTargetItem(WKBundleBackForwardListItemRef itemRef) +{ + return toImpl(itemRef)->isTargetItem(); +} + +WKArrayRef WKBundleBackForwardListItemCopyChildren(WKBundleBackForwardListItemRef itemRef) +{ + return toAPI(toImpl(itemRef)->children().leakRef()); +} + diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.h new file mode 100644 index 0000000..f256464 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#ifndef WKBundleBackForwardListItem_h +#define WKBundleBackForwardListItem_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleBackForwardListItemGetTypeID(); + +WK_EXPORT bool WKBundleBackForwardListItemIsSame(WKBundleBackForwardListItemRef item1, WKBundleBackForwardListItemRef item2); + +WK_EXPORT WKURLRef WKBundleBackForwardListItemCopyOriginalURL(WKBundleBackForwardListItemRef item); +WK_EXPORT WKURLRef WKBundleBackForwardListItemCopyURL(WKBundleBackForwardListItemRef item); +WK_EXPORT WKStringRef WKBundleBackForwardListItemCopyTitle(WKBundleBackForwardListItemRef item); + +WK_EXPORT WKStringRef WKBundleBackForwardListItemCopyTarget(WKBundleBackForwardListItemRef item); +WK_EXPORT bool WKBundleBackForwardListItemIsTargetItem(WKBundleBackForwardListItemRef item); + +WK_EXPORT WKArrayRef WKBundleBackForwardListItemCopyChildren(WKBundleBackForwardListItemRef item); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleBackForwardListItem_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp new file mode 100644 index 0000000..9410642 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp @@ -0,0 +1,199 @@ +/* + * 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 "WKBundleFrame.h" +#include "WKBundleFramePrivate.h" + +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebFrame.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> + +using namespace WebCore; +using namespace WebKit; + +WKTypeID WKBundleFrameGetTypeID() +{ + return toAPI(WebFrame::APIType); +} + +bool WKBundleFrameIsMainFrame(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->isMainFrame(); +} + +WKURLRef WKBundleFrameCopyURL(WKBundleFrameRef frameRef) +{ + return toCopiedURLAPI(toImpl(frameRef)->url()); +} + +WKURLRef WKBundleFrameCopyProvisionalURL(WKBundleFrameRef frameRef) +{ + return toCopiedURLAPI(toImpl(frameRef)->provisionalURL()); +} + +WKArrayRef WKBundleFrameCopyChildFrames(WKBundleFrameRef frameRef) +{ + return toAPI(toImpl(frameRef)->childFrames().releaseRef()); +} + +unsigned WKBundleFrameGetNumberOfActiveAnimations(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->numberOfActiveAnimations(); +} + +bool WKBundleFramePauseAnimationOnElementWithId(WKBundleFrameRef frameRef, WKStringRef name, WKStringRef elementID, double time) +{ + return toImpl(frameRef)->pauseAnimationOnElementWithId(toImpl(name)->string(), toImpl(elementID)->string(), time); +} + +void WKBundleFrameSuspendAnimations(WKBundleFrameRef frameRef) +{ + toImpl(frameRef)->suspendAnimations(); +} + +void WKBundleFrameResumeAnimations(WKBundleFrameRef frameRef) +{ + toImpl(frameRef)->resumeAnimations(); +} + +JSGlobalContextRef WKBundleFrameGetJavaScriptContext(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->jsContext(); +} + +JSGlobalContextRef WKBundleFrameGetJavaScriptContextForWorld(WKBundleFrameRef frameRef, WKBundleScriptWorldRef worldRef) +{ + return toImpl(frameRef)->jsContextForWorld(toImpl(worldRef)); +} + +JSValueRef WKBundleFrameGetJavaScriptWrapperForNodeForWorld(WKBundleFrameRef frameRef, WKBundleNodeHandleRef nodeHandleRef, WKBundleScriptWorldRef worldRef) +{ + return toImpl(frameRef)->jsWrapperForWorld(toImpl(nodeHandleRef), toImpl(worldRef)); +} + +JSValueRef WKBundleFrameGetJavaScriptWrapperForRangeForWorld(WKBundleFrameRef frameRef, WKBundleRangeHandleRef rangeHandleRef, WKBundleScriptWorldRef worldRef) +{ + return toImpl(frameRef)->jsWrapperForWorld(toImpl(rangeHandleRef), toImpl(worldRef)); +} + +WKStringRef WKBundleFrameCopyName(WKBundleFrameRef frameRef) +{ + return toCopiedAPI(toImpl(frameRef)->name()); +} + +JSValueRef WKBundleFrameGetComputedStyleIncludingVisitedInfo(WKBundleFrameRef frameRef, JSObjectRef element) +{ + return toImpl(frameRef)->computedStyleIncludingVisitedInfo(element); +} + +WKStringRef WKBundleFrameCopyCounterValue(WKBundleFrameRef frameRef, JSObjectRef element) +{ + return toCopiedAPI(toImpl(frameRef)->counterValue(element)); +} + +WKStringRef WKBundleFrameCopyMarkerText(WKBundleFrameRef frameRef, JSObjectRef element) +{ + return toCopiedAPI(toImpl(frameRef)->markerText(element)); +} + +WKStringRef WKBundleFrameCopyInnerText(WKBundleFrameRef frameRef) +{ + return toCopiedAPI(toImpl(frameRef)->innerText()); +} + +unsigned WKBundleFrameGetPendingUnloadCount(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->pendingUnloadCount(); +} + +WKBundlePageRef WKBundleFrameGetPage(WKBundleFrameRef frameRef) +{ + return toAPI(toImpl(frameRef)->page()); +} + +WKStringRef WKBundleFrameCopyLayerTreeAsText(WKBundleFrameRef frameRef) +{ + return toCopiedAPI(toImpl(frameRef)->layerTreeAsText()); +} + +bool WKBundleFrameAllowsFollowingLink(WKBundleFrameRef frameRef, WKURLRef urlRef) +{ + return toImpl(frameRef)->allowsFollowingLink(WebCore::KURL(WebCore::KURL(), toImpl(urlRef)->string())); +} + +WKRect WKBundleFrameGetContentBounds(WKBundleFrameRef frameRef) +{ + WKRect contentBounds = { { 0, 0 }, { 0, 0 } }; + + Frame* coreFrame = toImpl(frameRef)->coreFrame(); + if (!coreFrame) + return contentBounds; + + FrameView* view = coreFrame->view(); + if (!view) + return contentBounds; + + contentBounds.size.width = view->contentsWidth(); + contentBounds.size.height = view->contentsHeight(); + + return contentBounds; +} + +WKRect WKBundleFrameGetVisibleContentBounds(WKBundleFrameRef frameRef) +{ + WKRect visibleContentBounds = { { 0, 0 }, { 0, 0 } }; + + Frame* coreFrame = toImpl(frameRef)->coreFrame(); + if (!coreFrame) + return visibleContentBounds; + + FrameView* view = coreFrame->view(); + if (!view) + return visibleContentBounds; + + FloatRect bounds = view->visibleContentRect(true); + + visibleContentBounds.size.width = bounds.width(); + visibleContentBounds.size.height = bounds.height(); + + return visibleContentBounds; +} + +WK_EXPORT WKSize WKBundleFrameGetScrollOffset(WKBundleFrameRef frameRef) +{ + WKSize scrollOffset = { 0, 0 }; + + Frame* coreFrame = toImpl(frameRef)->coreFrame(); + if (!coreFrame) + return scrollOffset; + + FrameView* view = coreFrame->view(); + if (!view) + return scrollOffset; + + return toAPI(view->scrollOffset()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h new file mode 100644 index 0000000..a6a20b2 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#ifndef WKBundleFrame_h +#define WKBundleFrame_h + +#include <JavaScriptCore/JavaScript.h> +#include <WebKit2/WKBase.h> +#include <WebKit2/WKGeometry.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleFrameGetTypeID(); + +WK_EXPORT bool WKBundleFrameIsMainFrame(WKBundleFrameRef frame); +WK_EXPORT WKArrayRef WKBundleFrameCopyChildFrames(WKBundleFrameRef frame); + +WK_EXPORT WKStringRef WKBundleFrameCopyName(WKBundleFrameRef frame); +WK_EXPORT WKURLRef WKBundleFrameCopyURL(WKBundleFrameRef frame); +WK_EXPORT WKURLRef WKBundleFrameCopyProvisionalURL(WKBundleFrameRef frame); + +WK_EXPORT JSGlobalContextRef WKBundleFrameGetJavaScriptContext(WKBundleFrameRef frame); +WK_EXPORT JSGlobalContextRef WKBundleFrameGetJavaScriptContextForWorld(WKBundleFrameRef frame, WKBundleScriptWorldRef world); + +WK_EXPORT JSValueRef WKBundleFrameGetJavaScriptWrapperForNodeForWorld(WKBundleFrameRef frame, WKBundleNodeHandleRef nodeHandle, WKBundleScriptWorldRef world); +WK_EXPORT JSValueRef WKBundleFrameGetJavaScriptWrapperForRangeForWorld(WKBundleFrameRef frame, WKBundleRangeHandleRef rangeHandle, WKBundleScriptWorldRef world); + +WK_EXPORT WKBundlePageRef WKBundleFrameGetPage(WKBundleFrameRef frame); + +WK_EXPORT bool WKBundleFrameAllowsFollowingLink(WKBundleFrameRef frame, WKURLRef url); + +WK_EXPORT WKRect WKBundleFrameGetContentBounds(WKBundleFrameRef frame); +WK_EXPORT WKRect WKBundleFrameGetVisibleContentBounds(WKBundleFrameRef frame); +WK_EXPORT WKSize WKBundleFrameGetScrollOffset(WKBundleFrameRef frame); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleFrame_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFramePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFramePrivate.h new file mode 100644 index 0000000..3f83a61 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFramePrivate.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#ifndef WKBundleFramePrivate_h +#define WKBundleFramePrivate_h + +#include <JavaScriptCore/JavaScript.h> +#include <WebKit2/WKBase.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKStringRef WKBundleFrameCopyInnerText(WKBundleFrameRef frame); +WK_EXPORT WKStringRef WKBundleFrameCopyCounterValue(WKBundleFrameRef frame, JSObjectRef element); +WK_EXPORT WKStringRef WKBundleFrameCopyMarkerText(WKBundleFrameRef frame, JSObjectRef element); +WK_EXPORT JSValueRef WKBundleFrameGetComputedStyleIncludingVisitedInfo(WKBundleFrameRef frame, JSObjectRef element); +WK_EXPORT unsigned WKBundleFrameGetNumberOfActiveAnimations(WKBundleFrameRef frame); +WK_EXPORT bool WKBundleFramePauseAnimationOnElementWithId(WKBundleFrameRef frame, WKStringRef name, WKStringRef elementID, double time); +WK_EXPORT void WKBundleFrameSuspendAnimations(WKBundleFrameRef frame); +WK_EXPORT void WKBundleFrameResumeAnimations(WKBundleFrameRef frame); +WK_EXPORT unsigned WKBundleFrameGetPendingUnloadCount(WKBundleFrameRef frame); +WK_EXPORT WKStringRef WKBundleFrameCopyLayerTreeAsText(WKBundleFrameRef frame); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleFramePrivate_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp new file mode 100644 index 0000000..7e74262 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp @@ -0,0 +1,89 @@ +/* + * 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 "WKBundleHitTestResult.h" + +#include "InjectedBundleHitTestResult.h" +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleHitTestResultGetTypeID() +{ + return toAPI(InjectedBundleHitTestResult::APIType); +} + +WKBundleNodeHandleRef WKBundleHitTestResultGetNodeHandle(WKBundleHitTestResultRef hitTestResultRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = toImpl(hitTestResultRef)->nodeHandle(); + return toAPI(nodeHandle.get()); +} + +WKBundleFrameRef WKBundleHitTestResultGetFrame(WKBundleHitTestResultRef hitTestResultRef) +{ + return toAPI(toImpl(hitTestResultRef)->frame()); +} + +WKBundleFrameRef WKBundleHitTestResultGetTargetFrame(WKBundleHitTestResultRef hitTestResultRef) +{ + return toAPI(toImpl(hitTestResultRef)->targetFrame()); +} + +WKURLRef WKBundleHitTestResultCopyAbsoluteImageURL(WKBundleHitTestResultRef hitTestResultRef) +{ + return toCopiedURLAPI(toImpl(hitTestResultRef)->absoluteImageURL()); +} + +WKURLRef WKBundleHitTestResultCopyAbsoluteLinkURL(WKBundleHitTestResultRef hitTestResultRef) +{ + return toCopiedURLAPI(toImpl(hitTestResultRef)->absoluteLinkURL()); +} + +WKURLRef WKBundleHitTestResultCopyAbsoluteMediaURL(WKBundleHitTestResultRef hitTestResultRef) +{ + return toCopiedURLAPI(toImpl(hitTestResultRef)->absoluteMediaURL()); +} + +WKRect WKBundleHitTestResultGetImageRect(WKBundleHitTestResultRef hitTestResultRef) +{ + return toAPI(toImpl(hitTestResultRef)->imageRect()); +} + +bool WKBundleHitTestResultGetIsSelected(WKBundleHitTestResultRef hitTestResultRef) +{ + return toImpl(hitTestResultRef)->isSelected(); +} + +WKStringRef WKBundleHitTestResultCopyLinkLabel(WKBundleHitTestResultRef hitTestResultRef) +{ + return toCopiedAPI(toImpl(hitTestResultRef)->linkLabel()); +} + +WKStringRef WKBundleHitTestResultCopyLinkTitle(WKBundleHitTestResultRef hitTestResultRef) +{ + return toCopiedAPI(toImpl(hitTestResultRef)->linkTitle()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.h new file mode 100644 index 0000000..19a6582 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#ifndef WKBundleHitTestResult_h +#define WKBundleHitTestResult_h + +#include <WebKit2/WKBase.h> +#include <WebKit2/WKGeometry.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleHitTestResultGetTypeID(); + +WK_EXPORT WKBundleNodeHandleRef WKBundleHitTestResultGetNodeHandle(WKBundleHitTestResultRef hitTestResult); + +WK_EXPORT WKBundleFrameRef WKBundleHitTestResultGetFrame(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT WKBundleFrameRef WKBundleHitTestResultGetTargetFrame(WKBundleHitTestResultRef hitTestResult); + +WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsoluteImageURL(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsoluteLinkURL(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsoluteMediaURL(WKBundleHitTestResultRef hitTestResult); + +WK_EXPORT WKRect WKBundleHitTestResultGetImageRect(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT bool WKBundleHitTestResultGetIsSelected(WKBundleHitTestResultRef hitTestResult); + +WK_EXPORT WKStringRef WKBundleHitTestResultCopyLinkLabel(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT WKStringRef WKBundleHitTestResultCopyLinkTitle(WKBundleHitTestResultRef hitTestResult); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleHitTestResult_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInitialize.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInitialize.h new file mode 100644 index 0000000..f10b7b4 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInitialize.h @@ -0,0 +1,42 @@ +/* + * 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. + */ + +#ifndef WKBundleInitialize_h +#define WKBundleInitialize_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// NOTE: Must be implemented by InjectedBundle's as a function named "WKBundleInitialize". +typedef void (*WKBundleInitializeFunctionPtr)(WKBundleRef, WKTypeRef); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleInitialize_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp new file mode 100644 index 0000000..86d913b --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp @@ -0,0 +1,89 @@ +/* + * 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 "WKBundleNodeHandle.h" +#include "WKBundleNodeHandlePrivate.h" + +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebFrame.h" + +using namespace WebKit; + +WKTypeID WKBundleNodeHandleGetTypeID() +{ + return toAPI(InjectedBundleNodeHandle::APIType); +} + +WKBundleNodeHandleRef WKBundleNodeHandleCreate(JSContextRef contextRef, JSObjectRef objectRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(contextRef, objectRef); + return toAPI(nodeHandle.release().releaseRef()); +} + +WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef nodeHandleRef) +{ + return toAPI(toImpl(nodeHandleRef)->elementBounds()); +} + +void WKBundleNodeHandleSetHTMLInputElementValueForUser(WKBundleNodeHandleRef htmlInputElementHandleRef, WKStringRef valueRef) +{ + toImpl(htmlInputElementHandleRef)->setHTMLInputElementValueForUser(toWTFString(valueRef)); +} + +bool WKBundleNodeHandleGetHTMLInputElementAutofilled(WKBundleNodeHandleRef htmlInputElementHandleRef) +{ + return toImpl(htmlInputElementHandleRef)->isHTMLInputElementAutofilled(); +} + +void WKBundleNodeHandleSetHTMLInputElementAutofilled(WKBundleNodeHandleRef htmlInputElementHandleRef, bool filled) +{ + toImpl(htmlInputElementHandleRef)->setHTMLInputElementAutofilled(filled); +} + +WKBundleNodeHandleRef WKBundleNodeHandleCopyHTMLTableCellElementCellAbove(WKBundleNodeHandleRef htmlTableCellElementHandleRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = toImpl(htmlTableCellElementHandleRef)->htmlTableCellElementCellAbove(); + return toAPI(nodeHandle.release().releaseRef()); +} + +WKBundleFrameRef WKBundleNodeHandleCopyDocumentFrame(WKBundleNodeHandleRef documentHandleRef) +{ + RefPtr<WebFrame> frame = toImpl(documentHandleRef)->documentFrame(); + return toAPI(frame.release().releaseRef()); +} + +WKBundleFrameRef WKBundleNodeHandleCopyHTMLFrameElementContentFrame(WKBundleNodeHandleRef htmlFrameElementHandleRef) +{ + RefPtr<WebFrame> frame = toImpl(htmlFrameElementHandleRef)->htmlFrameElementContentFrame(); + return toAPI(frame.release().releaseRef()); +} + +WKBundleFrameRef WKBundleNodeHandleCopyHTMLIFrameElementContentFrame(WKBundleNodeHandleRef htmlIFrameElementHandleRef) +{ + RefPtr<WebFrame> frame = toImpl(htmlIFrameElementHandleRef)->htmlIFrameElementContentFrame(); + return toAPI(frame.release().releaseRef()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.h new file mode 100644 index 0000000..3cdad17 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#ifndef WKBundleNodeHandle_h +#define WKBundleNodeHandle_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleNodeHandleGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleNodeHandle_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h new file mode 100644 index 0000000..854677b --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef WKBundleNodeHandlePrivate_h +#define WKBundleNodeHandlePrivate_h + +#include <JavaScriptCore/JavaScript.h> +#include <WebKit2/WKBase.h> +#include <WebKit2/WKGeometry.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKBundleNodeHandleRef WKBundleNodeHandleCreate(JSContextRef context, JSObjectRef object); + + +/* Additional DOM Operations */ + +WK_EXPORT WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef nodeHandle); + +/* HTMLInputElement Specific Operations */ +WK_EXPORT void WKBundleNodeHandleSetHTMLInputElementValueForUser(WKBundleNodeHandleRef htmlInputElementHandle, WKStringRef value); +WK_EXPORT bool WKBundleNodeHandleGetHTMLInputElementAutofilled(WKBundleNodeHandleRef htmlInputElementHandle); +WK_EXPORT void WKBundleNodeHandleSetHTMLInputElementAutofilled(WKBundleNodeHandleRef htmlInputElementHandle, bool filled); + +/* HTMLTableCellElement Specific Operations */ +WK_EXPORT WKBundleNodeHandleRef WKBundleNodeHandleCopyHTMLTableCellElementCellAbove(WKBundleNodeHandleRef htmlTableCellElementHandle); + +/* Document Specific Operations */ +WK_EXPORT WKBundleFrameRef WKBundleNodeHandleCopyDocumentFrame(WKBundleNodeHandleRef documentHandle); + +/* HTMLFrameElement Specific Operations */ +WK_EXPORT WKBundleFrameRef WKBundleNodeHandleCopyHTMLFrameElementContentFrame(WKBundleNodeHandleRef htmlFrameElementHandle); + +/* HTMLIFrameElement Specific Operations */ +WK_EXPORT WKBundleFrameRef WKBundleNodeHandleCopyHTMLIFrameElementContentFrame(WKBundleNodeHandleRef htmlIFrameElementHandle); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleNodeHandlePrivate_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp new file mode 100644 index 0000000..9693b6a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp @@ -0,0 +1,186 @@ +/* + * 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 "WKBundlePage.h" +#include "WKBundlePagePrivate.h" + +#include "InjectedBundleBackForwardList.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebImage.h" +#include "WebPage.h" +#include "WebURL.h" +#include "WebURLRequest.h" + +#include <WebCore/KURL.h> + +using namespace WebKit; + +WKTypeID WKBundlePageGetTypeID() +{ + return toAPI(WebPage::APIType); +} + +void WKBundlePageSetContextMenuClient(WKBundlePageRef pageRef, WKBundlePageContextMenuClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(pageRef)->initializeInjectedBundleContextMenuClient(wkClient); +} + +void WKBundlePageSetEditorClient(WKBundlePageRef pageRef, WKBundlePageEditorClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(pageRef)->initializeInjectedBundleEditorClient(wkClient); +} + +void WKBundlePageSetFormClient(WKBundlePageRef pageRef, WKBundlePageFormClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(pageRef)->initializeInjectedBundleFormClient(wkClient); +} + +void WKBundlePageSetLoaderClient(WKBundlePageRef pageRef, WKBundlePageLoaderClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(pageRef)->initializeInjectedBundleLoaderClient(wkClient); +} + +void WKBundlePageSetUIClient(WKBundlePageRef pageRef, WKBundlePageUIClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(pageRef)->initializeInjectedBundleUIClient(wkClient); +} + +WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->pageGroup()); +} + +WKBundleFrameRef WKBundlePageGetMainFrame(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->mainFrame()); +} + +void WKBundlePageStopLoading(WKBundlePageRef pageRef) +{ + toImpl(pageRef)->stopLoading(); +} + +void WKBundlePageSetDefersLoading(WKBundlePageRef pageRef, bool defersLoading) +{ + toImpl(pageRef)->setDefersLoading(defersLoading); +} + +WKStringRef WKBundlePageCopyRenderTreeExternalRepresentation(WKBundlePageRef pageRef) +{ + return toCopiedAPI(toImpl(pageRef)->renderTreeExternalRepresentation()); +} + +void WKBundlePageExecuteEditingCommand(WKBundlePageRef pageRef, WKStringRef name, WKStringRef argument) +{ + toImpl(pageRef)->executeEditingCommand(toImpl(name)->string(), toImpl(argument)->string()); +} + +bool WKBundlePageIsEditingCommandEnabled(WKBundlePageRef pageRef, WKStringRef name) +{ + return toImpl(pageRef)->isEditingCommandEnabled(toImpl(name)->string()); +} + +void WKBundlePageClearMainFrameName(WKBundlePageRef pageRef) +{ + toImpl(pageRef)->clearMainFrameName(); +} + +void WKBundlePageClose(WKBundlePageRef pageRef) +{ + toImpl(pageRef)->sendClose(); +} + +double WKBundlePageGetTextZoomFactor(WKBundlePageRef pageRef) +{ + return toImpl(pageRef)->textZoomFactor(); +} + +void WKBundlePageSetTextZoomFactor(WKBundlePageRef pageRef, double zoomFactor) +{ + toImpl(pageRef)->setTextZoomFactor(zoomFactor); +} + +double WKBundlePageGetPageZoomFactor(WKBundlePageRef pageRef) +{ + return toImpl(pageRef)->pageZoomFactor(); +} + +void WKBundlePageSetPageZoomFactor(WKBundlePageRef pageRef, double zoomFactor) +{ + toImpl(pageRef)->setPageZoomFactor(zoomFactor); +} + +WKBundleBackForwardListRef WKBundlePageGetBackForwardList(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->backForwardList()); +} + +void WKBundlePageInstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef) +{ + toImpl(pageRef)->installPageOverlay(toImpl(pageOverlayRef)); +} + +void WKBundlePageUninstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef) +{ + toImpl(pageRef)->uninstallPageOverlay(toImpl(pageOverlayRef)); +} + +bool WKBundlePageHasLocalDataForURL(WKBundlePageRef pageRef, WKURLRef urlRef) +{ + return toImpl(pageRef)->hasLocalDataForURL(WebCore::KURL(WebCore::KURL(), toImpl(urlRef)->string())); +} + +bool WKBundlePageCanHandleRequest(WKURLRequestRef requestRef) +{ + return WebPage::canHandleRequest(toImpl(requestRef)->resourceRequest()); +} + +bool WKBundlePageFindString(WKBundlePageRef pageRef, WKStringRef target, WKFindOptions findOptions) +{ + return toImpl(pageRef)->findStringFromInjectedBundle(toImpl(target)->string(), toFindOptions(findOptions)); +} + +WKImageRef WKBundlePageCreateSnapshotInViewCoordinates(WKBundlePageRef pageRef, WKRect rect, WKImageOptions options) +{ + RefPtr<WebImage> webImage = toImpl(pageRef)->snapshotInViewCoordinates(toIntRect(rect), toImageOptions(options)); + return toAPI(webImage.release().leakRef()); +} + +WKImageRef WKBundlePageCreateSnapshotInDocumentCoordinates(WKBundlePageRef pageRef, WKRect rect, WKImageOptions options) +{ + RefPtr<WebImage> webImage = toImpl(pageRef)->snapshotInDocumentCoordinates(toIntRect(rect), toImageOptions(options)); + return toAPI(webImage.release().leakRef()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h new file mode 100644 index 0000000..00db56f --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h @@ -0,0 +1,227 @@ +/* + * 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. + */ + +#ifndef WKBundlePage_h +#define WKBundlePage_h + +#include <WebKit2/WKBase.h> +#include <WebKit2/WKEvent.h> +#include <WebKit2/WKFindOptions.h> +#include <WebKit2/WKImage.h> +#include <WebKit2/WKPageLoadTypes.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + kWKInsertActionTyped = 0, + kWKInsertActionPasted = 1, + kWKInsertActionDropped = 2 +}; +typedef uint32_t WKInsertActionType; + +enum { + kWKAffinityUpstream, + kWKAffinityDownstream +}; +typedef uint32_t WKAffinityType; + +enum { + WKInputFieldActionTypeMoveUp, + WKInputFieldActionTypeMoveDown, + WKInputFieldActionTypeCancel, + WKInputFieldActionTypeInsertTab, + WKInputFieldActionTypeInsertBacktab, + WKInputFieldActionTypeInsertNewline, + WKInputFieldActionTypeInsertDelete +}; +typedef uint32_t WKInputFieldActionType; + +// Loader Client +typedef void (*WKBundlePageDidStartProvisionalLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidReceiveServerRedirectForProvisionalLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFailProvisionalLoadWithErrorForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKErrorRef error, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidCommitLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidDocumentFinishLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFinishLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFinishDocumentLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFailLoadWithErrorForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKErrorRef error, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidSameDocumentNavigationForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidReceiveTitleForFrameCallback)(WKBundlePageRef page, WKStringRef title, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFirstLayoutForFrame)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFirstVisuallyNonEmptyLayoutForFrame)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidRemoveFrameFromHierarchyCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidDisplayInsecureContentForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidRunInsecureContentForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +// FIXME: There are no WKPage equivilent of these functions yet. +typedef void (*WKBundlePageDidClearWindowObjectForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void *clientInfo); +typedef void (*WKBundlePageDidCancelClientRedirectForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo); +typedef void (*WKBundlePageWillPerformClientRedirectForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKURLRef url, double delay, double date, const void *clientInfo); +typedef void (*WKBundlePageDidHandleOnloadEventsForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo); +typedef bool (*WKBundlePageShouldLoadResourceForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKStringRef url, const void *clientInfo); + + +struct WKBundlePageLoaderClient { + int version; + const void * clientInfo; + WKBundlePageDidStartProvisionalLoadForFrameCallback didStartProvisionalLoadForFrame; + WKBundlePageDidReceiveServerRedirectForProvisionalLoadForFrameCallback didReceiveServerRedirectForProvisionalLoadForFrame; + WKBundlePageDidFailProvisionalLoadWithErrorForFrameCallback didFailProvisionalLoadWithErrorForFrame; + WKBundlePageDidCommitLoadForFrameCallback didCommitLoadForFrame; + WKBundlePageDidFinishDocumentLoadForFrameCallback didFinishDocumentLoadForFrame; + WKBundlePageDidFinishLoadForFrameCallback didFinishLoadForFrame; + WKBundlePageDidFailLoadWithErrorForFrameCallback didFailLoadWithErrorForFrame; + WKBundlePageDidSameDocumentNavigationForFrameCallback didSameDocumentNavigationForFrame; + WKBundlePageDidReceiveTitleForFrameCallback didReceiveTitleForFrame; + WKBundlePageDidFirstLayoutForFrame didFirstLayoutForFrame; + WKBundlePageDidFirstVisuallyNonEmptyLayoutForFrame didFirstVisuallyNonEmptyLayoutForFrame; + WKBundlePageDidRemoveFrameFromHierarchyCallback didRemoveFrameFromHierarchy; + WKBundlePageDidDisplayInsecureContentForFrameCallback didDisplayInsecureContentForFrame; + WKBundlePageDidRunInsecureContentForFrameCallback didRunInsecureContentForFrame; + + // FIXME: There are no WKPage equivilent of these functions yet. + WKBundlePageDidClearWindowObjectForFrameCallback didClearWindowObjectForFrame; + WKBundlePageDidCancelClientRedirectForFrameCallback didCancelClientRedirectForFrame; + WKBundlePageWillPerformClientRedirectForFrameCallback willPerformClientRedirectForFrame; + WKBundlePageDidHandleOnloadEventsForFrameCallback didHandleOnloadEventsForFrame; + WKBundlePageShouldLoadResourceForFrameCallback shouldLoadResourceForFrame; +}; +typedef struct WKBundlePageLoaderClient WKBundlePageLoaderClient; + +// UI Client +typedef void (*WKBundlePageWillAddMessageToConsoleCallback)(WKBundlePageRef page, WKStringRef message, uint32_t lineNumber, const void *clientInfo); +typedef void (*WKBundlePageWillSetStatusbarTextCallback)(WKBundlePageRef page, WKStringRef statusbarText, const void *clientInfo); +typedef void (*WKBundlePageWillRunJavaScriptAlertCallback)(WKBundlePageRef page, WKStringRef alertText, WKBundleFrameRef frame, const void *clientInfo); +typedef void (*WKBundlePageWillRunJavaScriptConfirmCallback)(WKBundlePageRef page, WKStringRef message, WKBundleFrameRef frame, const void *clientInfo); +typedef void (*WKBundlePageWillRunJavaScriptPromptCallback)(WKBundlePageRef page, WKStringRef message, WKStringRef defaultValue, WKBundleFrameRef frame, const void *clientInfo); +typedef void (*WKBundlePageMouseDidMoveOverElementCallback)(WKBundlePageRef page, WKBundleHitTestResultRef hitTestResult, WKEventModifiers modifiers, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidScrollCallback)(WKBundlePageRef page, const void *clientInfo); + +struct WKBundlePageUIClient { + int version; + const void * clientInfo; + WKBundlePageWillAddMessageToConsoleCallback willAddMessageToConsole; + WKBundlePageWillSetStatusbarTextCallback willSetStatusbarText; + WKBundlePageWillRunJavaScriptAlertCallback willRunJavaScriptAlert; + WKBundlePageWillRunJavaScriptConfirmCallback willRunJavaScriptConfirm; + WKBundlePageWillRunJavaScriptPromptCallback willRunJavaScriptPrompt; + WKBundlePageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKBundlePageDidScrollCallback pageDidScroll; +}; +typedef struct WKBundlePageUIClient WKBundlePageUIClient; + +// Editor client +typedef bool (*WKBundlePageShouldBeginEditingCallback)(WKBundlePageRef page, WKBundleRangeHandleRef range, const void* clientInfo); +typedef bool (*WKBundlePageShouldEndEditingCallback)(WKBundlePageRef page, WKBundleRangeHandleRef range, const void* clientInfo); +typedef bool (*WKBundlePageShouldInsertNodeCallback)(WKBundlePageRef page, WKBundleNodeHandleRef node, WKBundleRangeHandleRef rangeToReplace, WKInsertActionType action, const void* clientInfo); +typedef bool (*WKBundlePageShouldInsertTextCallback)(WKBundlePageRef page, WKStringRef string, WKBundleRangeHandleRef rangeToReplace, WKInsertActionType action, const void* clientInfo); +typedef bool (*WKBundlePageShouldDeleteRangeCallback)(WKBundlePageRef page, WKBundleRangeHandleRef range, const void* clientInfo); +typedef bool (*WKBundlePageShouldChangeSelectedRange)(WKBundlePageRef page, WKBundleRangeHandleRef fromRange, WKBundleRangeHandleRef toRange, WKAffinityType affinity, bool stillSelecting, const void* clientInfo); +typedef bool (*WKBundlePageShouldApplyStyle)(WKBundlePageRef page, WKBundleCSSStyleDeclarationRef style, WKBundleRangeHandleRef range, const void* clientInfo); +typedef void (*WKBundlePageEditingNotification)(WKBundlePageRef page, WKStringRef notificationName, const void* clientInfo); + +struct WKBundlePageEditorClient { + int version; + const void * clientInfo; + WKBundlePageShouldBeginEditingCallback shouldBeginEditing; + WKBundlePageShouldEndEditingCallback shouldEndEditing; + WKBundlePageShouldInsertNodeCallback shouldInsertNode; + WKBundlePageShouldInsertTextCallback shouldInsertText; + WKBundlePageShouldDeleteRangeCallback shouldDeleteRange; + WKBundlePageShouldChangeSelectedRange shouldChangeSelectedRange; + WKBundlePageShouldApplyStyle shouldApplyStyle; + WKBundlePageEditingNotification didBeginEditing; + WKBundlePageEditingNotification didEndEditing; + WKBundlePageEditingNotification didChange; + WKBundlePageEditingNotification didChangeSelection; +}; +typedef struct WKBundlePageEditorClient WKBundlePageEditorClient; + +// Form client +typedef void (*WKBundlePageTextFieldDidBeginEditingCallback)(WKBundlePageRef page, WKBundleNodeHandleRef htmlInputElementHandle, WKBundleFrameRef frame, const void* clientInfo); +typedef void (*WKBundlePageTextFieldDidEndEditingCallback)(WKBundlePageRef page, WKBundleNodeHandleRef htmlInputElementHandle, WKBundleFrameRef frame, const void* clientInfo); +typedef void (*WKBundlePageTextDidChangeInTextFieldCallback)(WKBundlePageRef page, WKBundleNodeHandleRef htmlInputElementHandle, WKBundleFrameRef frame, const void* clientInfo); +typedef void (*WKBundlePageTextDidChangeInTextAreaCallback)(WKBundlePageRef page, WKBundleNodeHandleRef htmlTextAreaElementHandle, WKBundleFrameRef frame, const void* clientInfo); +typedef bool (*WKBundlePageShouldPerformActionInTextFieldCallback)(WKBundlePageRef page, WKBundleNodeHandleRef htmlInputElementHandle, WKInputFieldActionType actionType, WKBundleFrameRef frame, const void* clientInfo); +typedef void (*WKBundlePageWillSubmitFormCallback)(WKBundlePageRef page, WKBundleNodeHandleRef htmlFormElementHandle, WKBundleFrameRef frame, WKBundleFrameRef sourceFrame, WKDictionaryRef values, WKTypeRef* userData, const void* clientInfo); + +struct WKBundlePageFormClient { + int version; + const void * clientInfo; + WKBundlePageTextFieldDidBeginEditingCallback textFieldDidBeginEditing; + WKBundlePageTextFieldDidEndEditingCallback textFieldDidEndEditing; + WKBundlePageTextDidChangeInTextFieldCallback textDidChangeInTextField; + WKBundlePageTextDidChangeInTextAreaCallback textDidChangeInTextArea; + WKBundlePageShouldPerformActionInTextFieldCallback shouldPerformActionInTextField; + WKBundlePageWillSubmitFormCallback willSubmitForm; +}; +typedef struct WKBundlePageFormClient WKBundlePageFormClient; + +// ContextMenu client +typedef void (*WKBundlePageGetContextMenuFromDefaultContextMenuCallback)(WKBundlePageRef page, WKBundleHitTestResultRef hitTestResult, WKArrayRef defaultMenu, WKArrayRef* newMenu, WKTypeRef* userData, const void* clientInfo); + +struct WKBundlePageContextMenuClient { + int version; + const void * clientInfo; + WKBundlePageGetContextMenuFromDefaultContextMenuCallback getContextMenuFromDefaultMenu; +}; +typedef struct WKBundlePageContextMenuClient WKBundlePageContextMenuClient; + +WK_EXPORT WKTypeID WKBundlePageGetTypeID(); + +WK_EXPORT void WKBundlePageSetContextMenuClient(WKBundlePageRef page, WKBundlePageContextMenuClient* client); +WK_EXPORT void WKBundlePageSetEditorClient(WKBundlePageRef page, WKBundlePageEditorClient* client); +WK_EXPORT void WKBundlePageSetFormClient(WKBundlePageRef page, WKBundlePageFormClient* client); +WK_EXPORT void WKBundlePageSetLoaderClient(WKBundlePageRef page, WKBundlePageLoaderClient* client); +WK_EXPORT void WKBundlePageSetUIClient(WKBundlePageRef page, WKBundlePageUIClient* client); + +WK_EXPORT WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef page); +WK_EXPORT WKBundleFrameRef WKBundlePageGetMainFrame(WKBundlePageRef page); + +WK_EXPORT WKBundleBackForwardListRef WKBundlePageGetBackForwardList(WKBundlePageRef page); + +WK_EXPORT void WKBundlePageInstallPageOverlay(WKBundlePageRef page, WKBundlePageOverlayRef pageOverlay); +WK_EXPORT void WKBundlePageUninstallPageOverlay(WKBundlePageRef page, WKBundlePageOverlayRef pageOverlay); + +WK_EXPORT bool WKBundlePageHasLocalDataForURL(WKBundlePageRef page, WKURLRef url); +WK_EXPORT bool WKBundlePageCanHandleRequest(WKURLRequestRef request); + +WK_EXPORT bool WKBundlePageFindString(WKBundlePageRef page, WKStringRef target, WKFindOptions findOptions); + +WK_EXPORT WKImageRef WKBundlePageCreateSnapshotInViewCoordinates(WKBundlePageRef page, WKRect rect, WKImageOptions options); +WK_EXPORT WKImageRef WKBundlePageCreateSnapshotInDocumentCoordinates(WKBundlePageRef page, WKRect rect, WKImageOptions options); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundlePage_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.cpp new file mode 100644 index 0000000..47d4cf1 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.cpp @@ -0,0 +1,42 @@ +/* + * 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 "WKBundlePageGroup.h" + +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebPageGroupProxy.h" + +using namespace WebKit; + +WKTypeID WKBundlePageGroupGetTypeID() +{ + return toAPI(WebPageGroupProxy::APIType); +} + +WKStringRef WKBundlePageGroupCopyIdentifier(WKBundlePageGroupRef bundlePageGroup) +{ + return toCopiedAPI(toImpl(bundlePageGroup)->identifier()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.h new file mode 100644 index 0000000..e0bf645 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#ifndef WKBundlePageGroup_h +#define WKBundlePageGroup_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundlePageGroupGetTypeID(); + +WK_EXPORT WKStringRef WKBundlePageGroupCopyIdentifier(WKBundlePageGroupRef bundlePageGroup); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundlePageGroup_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp new file mode 100644 index 0000000..48fcab4 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp @@ -0,0 +1,138 @@ +/* + * 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 "WKBundlePageOverlay.h" + +#include "PageOverlay.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include <WebCore/GraphicsContext.h> +#include <wtf/PassOwnPtr.h> + +using namespace WebCore; +using namespace WebKit; + +class PageOverlayClientImpl : public PageOverlay::Client { +public: + static PassOwnPtr<PageOverlayClientImpl> create(WKBundlePageOverlayClient* client) + { + return adoptPtr(new PageOverlayClientImpl(client)); + } + +private: + explicit PageOverlayClientImpl(WKBundlePageOverlayClient* client) + : m_client() + { + if (client) + m_client = *client; + } + + // PageOverlay::Client. + virtual void pageOverlayDestroyed(PageOverlay*) + { + delete this; + } + + virtual void willMoveToWebPage(PageOverlay* pageOverlay, WebPage* page) + { + if (!m_client.willMoveToPage) + return; + + m_client.willMoveToPage(toAPI(pageOverlay), toAPI(page), m_client.clientInfo); + } + + virtual void didMoveToWebPage(PageOverlay* pageOverlay, WebPage* page) + { + if (!m_client.didMoveToPage) + return; + + m_client.didMoveToPage(toAPI(pageOverlay), toAPI(page), m_client.clientInfo); + } + + virtual void drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect) + { + if (!m_client.drawRect) + return; + + m_client.drawRect(toAPI(pageOverlay), graphicsContext.platformContext(), toAPI(dirtyRect), m_client.clientInfo); + } + + virtual bool mouseEvent(PageOverlay* pageOverlay, const WebMouseEvent& event) + { + switch (event.type()) { + case WebEvent::MouseDown: { + if (!m_client.mouseDown) + return false; + + return m_client.mouseDown(toAPI(pageOverlay), toAPI(event.position()), toAPI(event.button()), m_client.clientInfo); + } + case WebEvent::MouseUp: { + if (!m_client.mouseUp) + return false; + + return m_client.mouseUp(toAPI(pageOverlay), toAPI(event.position()), toAPI(event.button()), m_client.clientInfo); + } + case WebEvent::MouseMove: { + if (event.button() == WebMouseEvent::NoButton) { + if (!m_client.mouseMoved) + return false; + + return m_client.mouseMoved(toAPI(pageOverlay), toAPI(event.position()), m_client.clientInfo); + } + + // This is a MouseMove event with a mouse button pressed. Call mouseDragged. + if (!m_client.mouseDragged) + return false; + + return m_client.mouseDragged(toAPI(pageOverlay), toAPI(event.position()), toAPI(event.button()), m_client.clientInfo); + } + + default: + return false; + } + } + + WKBundlePageOverlayClient m_client; +}; + +WKTypeID WKBundlePageOverlayGetTypeID() +{ + return toAPI(PageOverlay::APIType); +} + +WKBundlePageOverlayRef WKBundlePageOverlayCreate(WKBundlePageOverlayClient* wkClient) +{ + if (wkClient && wkClient->version) + return 0; + + OwnPtr<PageOverlayClientImpl> clientImpl = PageOverlayClientImpl::create(wkClient); + + return toAPI(PageOverlay::create(clientImpl.leakPtr()).leakRef()); +} + +void WKBundlePageOverlaySetNeedsDisplay(WKBundlePageOverlayRef bundlePageOverlayRef, WKRect rect) +{ + toImpl(bundlePageOverlayRef)->setNeedsDisplay(enclosingIntRect(toFloatRect(rect))); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h new file mode 100644 index 0000000..3b4f950 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#ifndef WKBundlePageOverlay_h +#define WKBundlePageOverlay_h + +#include <WebKit2/WKBase.h> +#include <WebKit2/WKEvent.h> +#include <WebKit2/WKGeometry.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// Page overlay client. +typedef void (*WKBundlePageOverlayWillMoveToPageCallback)(WKBundlePageOverlayRef pageOverlay, WKBundlePageRef page, const void* clientInfo); +typedef void (*WKBundlePageOverlayDidMoveToPageCallback)(WKBundlePageOverlayRef pageOverlay, WKBundlePageRef page, const void* clientInfo); +typedef void (*WKBundlePageOverlayDrawRectCallback)(WKBundlePageOverlayRef pageOverlay, void* graphicsContext, WKRect dirtyRect, const void* clientInfo); +typedef bool (*WKBundlePageOverlayMouseDownCallback)(WKBundlePageOverlayRef pageOverlay, WKPoint position, WKEventMouseButton mouseButton, const void* clientInfo); +typedef bool (*WKBundlePageOverlayMouseUpCallback)(WKBundlePageOverlayRef pageOverlay, WKPoint position, WKEventMouseButton mouseButton, const void* clientInfo); +typedef bool (*WKBundlePageOverlayMouseMovedCallback)(WKBundlePageOverlayRef pageOverlay, WKPoint position, const void* clientInfo); +typedef bool (*WKBundlePageOverlayMouseDraggedCallback)(WKBundlePageOverlayRef pageOverlay, WKPoint position, WKEventMouseButton mouseButton, const void* clientInfo); + +struct WKBundlePageOverlayClient { + int version; + const void * clientInfo; + WKBundlePageOverlayWillMoveToPageCallback willMoveToPage; + WKBundlePageOverlayDidMoveToPageCallback didMoveToPage; + WKBundlePageOverlayDrawRectCallback drawRect; + WKBundlePageOverlayMouseDownCallback mouseDown; + WKBundlePageOverlayMouseUpCallback mouseUp; + WKBundlePageOverlayMouseMovedCallback mouseMoved; + WKBundlePageOverlayMouseDraggedCallback mouseDragged; +}; +typedef struct WKBundlePageOverlayClient WKBundlePageOverlayClient; + +WK_EXPORT WKTypeID WKBundlePageOverlayGetTypeID(); + +WK_EXPORT WKBundlePageOverlayRef WKBundlePageOverlayCreate(WKBundlePageOverlayClient* client); +WK_EXPORT void WKBundlePageOverlaySetNeedsDisplay(WKBundlePageOverlayRef bundlePageOverlay, WKRect rect); + +#ifdef __cplusplus +} +#endif + +#endif // WKBundlePageOverlay_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h new file mode 100644 index 0000000..4bc8fed --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#ifndef WKBundlePagePrivate_h +#define WKBundlePagePrivate_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT void WKBundlePageStopLoading(WKBundlePageRef page); +WK_EXPORT void WKBundlePageSetDefersLoading(WKBundlePageRef page, bool defersLoading); +WK_EXPORT bool WKBundlePageIsEditingCommandEnabled(WKBundlePageRef page, WKStringRef commandName); +WK_EXPORT void WKBundlePageClearMainFrameName(WKBundlePageRef page); +WK_EXPORT void WKBundlePageClose(WKBundlePageRef page); +WK_EXPORT WKStringRef WKBundlePageCopyRenderTreeExternalRepresentation(WKBundlePageRef page); +WK_EXPORT void WKBundlePageExecuteEditingCommand(WKBundlePageRef page, WKStringRef commandName, WKStringRef argument); + +WK_EXPORT double WKBundlePageGetTextZoomFactor(WKBundlePageRef page); +WK_EXPORT void WKBundlePageSetTextZoomFactor(WKBundlePageRef page, double zoomFactor); +WK_EXPORT double WKBundlePageGetPageZoomFactor(WKBundlePageRef page); +WK_EXPORT void WKBundlePageSetPageZoomFactor(WKBundlePageRef page, double zoomFactor); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundlePagePrivate_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h new file mode 100644 index 0000000..bb0bd9f --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#ifndef WKBundlePrivate_h +#define WKBundlePrivate_h + +#include <WebKit2/WKBase.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT void WKBundleSetShouldTrackVisitedLinks(WKBundleRef bundle, bool shouldTrackVisitedLinks); +WK_EXPORT void WKBundleRemoveAllVisitedLinks(WKBundleRef bundle); +WK_EXPORT void WKBundleActivateMacFontAscentHack(WKBundleRef bundle); +WK_EXPORT void WKBundleGarbageCollectJavaScriptObjects(WKBundleRef bundle); +WK_EXPORT void WKBundleGarbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(WKBundleRef bundle, bool waitUntilDone); +WK_EXPORT size_t WKBundleGetJavaScriptObjectsCount(WKBundleRef bundle); + +enum WKUserScriptInjectionTime { + kWKInjectAtDocumentStart, + kWKInjectAtDocumentEnd +}; +typedef enum WKUserScriptInjectionTime WKUserScriptInjectionTime; + +enum WKUserContentInjectedFrames { + kWKInjectInAllFrames, + kWKInjectInTopFrameOnly +}; +typedef enum WKUserContentInjectedFrames WKUserContentInjectedFrames; + +WK_EXPORT void WKBundleAddUserScript(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, WKBundleScriptWorldRef scriptWorld, WKStringRef source, WKURLRef url, WKArrayRef whitelist, WKArrayRef blacklist, WKUserScriptInjectionTime injectionTime, WKUserContentInjectedFrames injectedFrames); +WK_EXPORT void WKBundleAddUserStyleSheet(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, WKBundleScriptWorldRef scriptWorld, WKStringRef source, WKURLRef url, WKArrayRef whitelist, WKArrayRef blacklist, WKUserContentInjectedFrames injectedFrames); +WK_EXPORT void WKBundleRemoveUserScript(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, WKBundleScriptWorldRef scriptWorld, WKURLRef url); +WK_EXPORT void WKBundleRemoveUserStyleSheet(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, WKBundleScriptWorldRef scriptWorld, WKURLRef url); +WK_EXPORT void WKBundleRemoveUserScripts(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, WKBundleScriptWorldRef scriptWorld); +WK_EXPORT void WKBundleRemoveUserStyleSheets(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, WKBundleScriptWorldRef scriptWorld); +WK_EXPORT void WKBundleRemoveAllUserContent(WKBundleRef bundle, WKBundlePageGroupRef pageGroup); + +// Will make WebProcess ignore this preference until a preferences change notification, only for WebKitTestRunner use. +WK_EXPORT void WKBundleOverrideXSSAuditorEnabledForTestRunner(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundlePrivate_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.cpp new file mode 100644 index 0000000..78047af --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.cpp @@ -0,0 +1,37 @@ +/* + * 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 "WKBundleRangeHandle.h" + +#include "InjectedBundleRangeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleRangeHandleGetTypeID() +{ + return toAPI(InjectedBundleRangeHandle::APIType); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.h new file mode 100644 index 0000000..8d1d359 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#ifndef WKBundleRangeHandle_h +#define WKBundleRangeHandle_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleRangeHandleGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleRangeHandle_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.cpp new file mode 100644 index 0000000..a7a4a8d --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.cpp @@ -0,0 +1,48 @@ +/* + * 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 "WKBundleScriptWorld.h" + +#include "InjectedBundleScriptWorld.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleScriptWorldGetTypeID() +{ + return toAPI(InjectedBundleScriptWorld::APIType); +} + +WKBundleScriptWorldRef WKBundleScriptWorldCreateWorld() +{ + RefPtr<InjectedBundleScriptWorld> world = InjectedBundleScriptWorld::create(); + return toAPI(world.release().releaseRef()); +} + +WKBundleScriptWorldRef WKBundleScriptWorldNormalWorld() +{ + return toAPI(InjectedBundleScriptWorld::normalWorld()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.h new file mode 100644 index 0000000..0763efa --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef WKBundleScriptWorld_h +#define WKBundleScriptWorld_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleScriptWorldGetTypeID(); + +WK_EXPORT WKBundleScriptWorldRef WKBundleScriptWorldCreateWorld(); +WK_EXPORT WKBundleScriptWorldRef WKBundleScriptWorldNormalWorld(); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleScriptWorld_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp new file mode 100644 index 0000000..e9370c6 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp @@ -0,0 +1,177 @@ +/* + * 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 "InjectedBundleNodeHandle.h" + +#include "WebFrame.h" +#include "WebFrameLoaderClient.h" +#include <JavaScriptCore/APICast.h> +#include <WebCore/Document.h> +#include <WebCore/HTMLFrameElement.h> +#include <WebCore/HTMLIFrameElement.h> +#include <WebCore/Frame.h> +#include <WebCore/HTMLInputElement.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLTableCellElement.h> +#include <WebCore/IntRect.h> +#include <WebCore/JSNode.h> +#include <WebCore/Node.h> +#include <wtf/HashMap.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; +using namespace HTMLNames; + +namespace WebKit { + +typedef HashMap<Node*, InjectedBundleNodeHandle*> DOMHandleCache; + +static DOMHandleCache& domHandleCache() +{ + DEFINE_STATIC_LOCAL(DOMHandleCache, cache, ()); + return cache; +} + +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(JSContextRef, JSObjectRef object) +{ + Node* node = toNode(toJS(object)); + return getOrCreate(node); +} + +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(Node* node) +{ + if (!node) + return 0; + + std::pair<DOMHandleCache::iterator, bool> result = domHandleCache().add(node, 0); + if (!result.second) + return PassRefPtr<InjectedBundleNodeHandle>(result.first->second); + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::create(node); + result.first->second = nodeHandle.get(); + return nodeHandle.release(); +} + +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::create(Node* node) +{ + return adoptRef(new InjectedBundleNodeHandle(node)); +} + +InjectedBundleNodeHandle::InjectedBundleNodeHandle(Node* node) + : m_node(node) +{ +} + +InjectedBundleNodeHandle::~InjectedBundleNodeHandle() +{ + domHandleCache().remove(m_node.get()); +} + +Node* InjectedBundleNodeHandle::coreNode() const +{ + return m_node.get(); +} + +// Additional DOM Operations +// Note: These should only be operations that are not exposed to JavaScript. + +IntRect InjectedBundleNodeHandle::elementBounds() const +{ + if (!m_node->isElementNode()) + return IntRect(); + + return static_cast<Element*>(m_node.get())->boundsInWindowSpace(); +} + +void InjectedBundleNodeHandle::setHTMLInputElementValueForUser(const String& value) +{ + if (!m_node->hasTagName(inputTag)) + return; + + static_cast<HTMLInputElement*>(m_node.get())->setValueForUser(value); +} + +bool InjectedBundleNodeHandle::isHTMLInputElementAutofilled() const +{ + if (!m_node->hasTagName(inputTag)) + return false; + + return static_cast<HTMLInputElement*>(m_node.get())->isAutofilled(); +} + + +void InjectedBundleNodeHandle::setHTMLInputElementAutofilled(bool filled) +{ + if (!m_node->hasTagName(inputTag)) + return; + + static_cast<HTMLInputElement*>(m_node.get())->setAutofilled(filled); +} + +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::htmlTableCellElementCellAbove() +{ + if (!m_node->hasTagName(tdTag)) + return 0; + + return getOrCreate(static_cast<HTMLTableCellElement*>(m_node.get())->cellAbove()); +} + +PassRefPtr<WebFrame> InjectedBundleNodeHandle::documentFrame() +{ + if (!m_node->isDocumentNode()) + return 0; + + Frame* frame = static_cast<Document*>(m_node.get())->frame(); + if (!frame) + return 0; + + return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); +} + +PassRefPtr<WebFrame> InjectedBundleNodeHandle::htmlFrameElementContentFrame() +{ + if (!m_node->hasTagName(frameTag)) + return 0; + + Frame* frame = static_cast<HTMLFrameElement*>(m_node.get())->contentFrame(); + if (!frame) + return 0; + + return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); +} + +PassRefPtr<WebFrame> InjectedBundleNodeHandle::htmlIFrameElementContentFrame() +{ + if (!m_node->hasTagName(iframeTag)) + return 0; + + Frame* frame = static_cast<HTMLIFrameElement*>(m_node.get())->contentFrame(); + if (!frame) + return 0; + + return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h new file mode 100644 index 0000000..eff4600 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#ifndef InjectedBundleNodeHandle_h +#define InjectedBundleNodeHandle_h + +#include "APIObject.h" +#include <JavaScriptCore/JSBase.h> +#include <wtf/Forward.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + class IntRect; + class Node; +} + +namespace WebKit { + +class InjectedBundleScriptWorld; +class WebFrame; + +class InjectedBundleNodeHandle : public APIObject { +public: + static const Type APIType = TypeBundleNodeHandle; + + static PassRefPtr<InjectedBundleNodeHandle> getOrCreate(JSContextRef, JSObjectRef); + static PassRefPtr<InjectedBundleNodeHandle> getOrCreate(WebCore::Node*); + + virtual ~InjectedBundleNodeHandle(); + + WebCore::Node* coreNode() const; + + // Additional DOM Operations + // Note: These should only be operations that are not exposed to JavaScript. + WebCore::IntRect elementBounds() const; + void setHTMLInputElementValueForUser(const String&); + bool isHTMLInputElementAutofilled() const; + void setHTMLInputElementAutofilled(bool); + PassRefPtr<InjectedBundleNodeHandle> htmlTableCellElementCellAbove(); + + PassRefPtr<WebFrame> documentFrame(); + PassRefPtr<WebFrame> htmlFrameElementContentFrame(); + PassRefPtr<WebFrame> htmlIFrameElementContentFrame(); + +private: + static PassRefPtr<InjectedBundleNodeHandle> create(WebCore::Node*); + InjectedBundleNodeHandle(WebCore::Node*); + + virtual Type type() const { return APIType; } + + RefPtr<WebCore::Node> m_node; +}; + +} // namespace WebKit + +#endif // InjectedBundleNodeHandle_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp new file mode 100644 index 0000000..9186637 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp @@ -0,0 +1,77 @@ +/* + * 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 "InjectedBundleRangeHandle.h" + +#include <WebCore/Range.h> +#include <wtf/HashMap.h> + +using namespace WebCore; + +namespace WebKit { + +typedef HashMap<Range*, InjectedBundleRangeHandle*> DOMHandleCache; + +static DOMHandleCache& domHandleCache() +{ + DEFINE_STATIC_LOCAL(DOMHandleCache, cache, ()); + return cache; +} + +PassRefPtr<InjectedBundleRangeHandle> InjectedBundleRangeHandle::getOrCreate(Range* range) +{ + if (!range) + return 0; + + std::pair<DOMHandleCache::iterator, bool> result = domHandleCache().add(range, 0); + if (!result.second) + return PassRefPtr<InjectedBundleRangeHandle>(result.first->second); + + RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::create(range); + result.first->second = rangeHandle.get(); + return rangeHandle.release(); +} + +PassRefPtr<InjectedBundleRangeHandle> InjectedBundleRangeHandle::create(Range* range) +{ + return adoptRef(new InjectedBundleRangeHandle(range)); +} + +InjectedBundleRangeHandle::InjectedBundleRangeHandle(Range* range) + : m_range(range) +{ +} + +InjectedBundleRangeHandle::~InjectedBundleRangeHandle() +{ + domHandleCache().remove(m_range.get()); +} + +Range* InjectedBundleRangeHandle::coreRange() const +{ + return m_range.get(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h new file mode 100644 index 0000000..4d6789a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#ifndef InjectedBundleRangeHandle_h +#define InjectedBundleRangeHandle_h + +#include "APIObject.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + class Range; +} + +namespace WebKit { + +class InjectedBundleScriptWorld; + +class InjectedBundleRangeHandle : public APIObject { +public: + static const Type APIType = TypeBundleRangeHandle; + + static PassRefPtr<InjectedBundleRangeHandle> getOrCreate(WebCore::Range*); + + virtual ~InjectedBundleRangeHandle(); + + WebCore::Range* coreRange() const; + +private: + static PassRefPtr<InjectedBundleRangeHandle> create(WebCore::Range*); + InjectedBundleRangeHandle(WebCore::Range*); + + virtual Type type() const { return APIType; } + + RefPtr<WebCore::Range> m_range; +}; + +} // namespace WebKit + +#endif // InjectedBundleRangeHandle_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp new file mode 100644 index 0000000..c9f1a6d --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp @@ -0,0 +1,238 @@ +/* + * 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 "InjectedBundle.h" + +#include "Arguments.h" +#include "ImmutableArray.h" +#include "InjectedBundleMessageKinds.h" +#include "InjectedBundleScriptWorld.h" +#include "InjectedBundleUserMessageCoders.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebContextMessageKinds.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSLock.h> +#include <WebCore/GCController.h> +#include <WebCore/JSDOMWindow.h> +#include <WebCore/Page.h> +#include <WebCore/PageGroup.h> +#include <WebCore/Settings.h> +#include <wtf/OwnArrayPtr.h> +#include <wtf/PassOwnArrayPtr.h> + +using namespace WebCore; +using namespace JSC; + +namespace WebKit { + +InjectedBundle::InjectedBundle(const String& path) + : m_path(path) + , m_platformBundle(0) +{ + initializeClient(0); +} + +InjectedBundle::~InjectedBundle() +{ +} + +void InjectedBundle::initializeClient(WKBundleClient* client) +{ + m_client.initialize(client); +} + +void InjectedBundle::postMessage(const String& messageName, APIObject* messageBody) +{ + WebProcess::shared().connection()->send(WebContextLegacyMessage::PostMessage, 0, CoreIPC::In(messageName, InjectedBundleUserMessageEncoder(messageBody))); +} + +void InjectedBundle::postSynchronousMessage(const String& messageName, APIObject* messageBody, RefPtr<APIObject>& returnData) +{ + RefPtr<APIObject> returnDataTmp; + InjectedBundleUserMessageDecoder messageDecoder(returnDataTmp); + + bool succeeded = WebProcess::shared().connection()->sendSync(WebContextLegacyMessage::PostSynchronousMessage, 0, CoreIPC::In(messageName, InjectedBundleUserMessageEncoder(messageBody)), CoreIPC::Out(messageDecoder)); + + if (!succeeded) + return; + + returnData = returnDataTmp; +} + +void InjectedBundle::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks) +{ + PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks); +} + +void InjectedBundle::removeAllVisitedLinks() +{ + PageGroup::removeAllVisitedLinks(); +} + +void InjectedBundle::overrideXSSAuditorEnabledForTestRunner(WebPageGroupProxy* pageGroup, bool enabled) +{ + // Override the preference for all future pages. + WebPreferencesStore::overrideXSSAuditorEnabledForTestRunner(enabled); + + // Change the setting for existing ones. + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setXSSAuditorEnabled(enabled); +} + + +static PassOwnPtr<Vector<String> > toStringVector(ImmutableArray* patterns) +{ + if (!patterns) + return 0; + + size_t size = patterns->size(); + if (!size) + return 0; + + Vector<String>* patternsVector = new Vector<String>; + patternsVector->reserveInitialCapacity(size); + for (size_t i = 0; i < size; ++i) { + WebString* entry = patterns->at<WebString>(i); + if (entry) + patternsVector->uncheckedAppend(entry->string()); + } + return patternsVector; +} + +void InjectedBundle::addUserScript(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& source, const String& url, ImmutableArray* whitelist, ImmutableArray* blacklist, WebCore::UserScriptInjectionTime injectionTime, WebCore::UserContentInjectedFrames injectedFrames) +{ + // url is not from KURL::string(), i.e. it has not already been parsed by KURL, so we have to use the relative URL constructor for KURL instead of the ParsedURLStringTag version. + PageGroup::pageGroup(pageGroup->identifier())->addUserScriptToWorld(scriptWorld->coreWorld(), source, KURL(KURL(), url), toStringVector(whitelist), toStringVector(blacklist), injectionTime, injectedFrames); +} + +void InjectedBundle::addUserStyleSheet(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& source, const String& url, ImmutableArray* whitelist, ImmutableArray* blacklist, WebCore::UserContentInjectedFrames injectedFrames) +{ + // url is not from KURL::string(), i.e. it has not already been parsed by KURL, so we have to use the relative URL constructor for KURL instead of the ParsedURLStringTag version. + PageGroup::pageGroup(pageGroup->identifier())->addUserStyleSheetToWorld(scriptWorld->coreWorld(), source, KURL(KURL(), url), toStringVector(whitelist), toStringVector(blacklist), injectedFrames); +} + +void InjectedBundle::removeUserScript(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& url) +{ + // url is not from KURL::string(), i.e. it has not already been parsed by KURL, so we have to use the relative URL constructor for KURL instead of the ParsedURLStringTag version. + PageGroup::pageGroup(pageGroup->identifier())->removeUserScriptFromWorld(scriptWorld->coreWorld(), KURL(KURL(), url)); +} + +void InjectedBundle::removeUserStyleSheet(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld, const String& url) +{ + // url is not from KURL::string(), i.e. it has not already been parsed by KURL, so we have to use the relative URL constructor for KURL instead of the ParsedURLStringTag version. + PageGroup::pageGroup(pageGroup->identifier())->removeUserStyleSheetFromWorld(scriptWorld->coreWorld(), KURL(KURL(), url)); +} + +void InjectedBundle::removeUserScripts(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld) +{ + PageGroup::pageGroup(pageGroup->identifier())->removeUserScriptsFromWorld(scriptWorld->coreWorld()); +} + +void InjectedBundle::removeUserStyleSheets(WebPageGroupProxy* pageGroup, InjectedBundleScriptWorld* scriptWorld) +{ + PageGroup::pageGroup(pageGroup->identifier())->removeUserStyleSheetsFromWorld(scriptWorld->coreWorld()); +} + +void InjectedBundle::removeAllUserContent(WebPageGroupProxy* pageGroup) +{ + PageGroup::pageGroup(pageGroup->identifier())->removeAllUserContent(); +} + +void InjectedBundle::garbageCollectJavaScriptObjects() +{ + gcController().garbageCollectNow(); +} + +void InjectedBundle::garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(bool waitUntilDone) +{ + gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); +} + +size_t InjectedBundle::javaScriptObjectsCount() +{ + JSLock lock(SilenceAssertionsOnly); + return JSDOMWindow::commonJSGlobalData()->heap.objectCount(); +} + +void InjectedBundle::reportException(JSContextRef context, JSValueRef exception) +{ + if (!context || !exception) + return; + + JSLock lock(JSC::SilenceAssertionsOnly); + JSC::ExecState* execState = toJS(context); + + // Make sure the context has a DOMWindow global object, otherwise this context didn't originate from a Page. + if (!toJSDOMWindow(execState->lexicalGlobalObject())) + return; + + WebCore::reportException(execState, toJS(execState, exception)); +} + +void InjectedBundle::didCreatePage(WebPage* page) +{ + m_client.didCreatePage(this, page); +} + +void InjectedBundle::willDestroyPage(WebPage* page) +{ + m_client.willDestroyPage(this, page); +} + +void InjectedBundle::didInitializePageGroup(WebPageGroupProxy* pageGroup) +{ + m_client.didInitializePageGroup(this, pageGroup); +} + +void InjectedBundle::didReceiveMessage(const String& messageName, APIObject* messageBody) +{ + m_client.didReceiveMessage(this, messageName, messageBody); +} + +void InjectedBundle::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + switch (messageID.get<InjectedBundleMessage::Kind>()) { + case InjectedBundleMessage::PostMessage: { + String messageName; + RefPtr<APIObject> messageBody; + InjectedBundleUserMessageDecoder messageDecoder(messageBody); + if (!arguments->decode(CoreIPC::Out(messageName, messageDecoder))) + return; + + didReceiveMessage(messageName, messageBody.get()); + return; + } + } + + ASSERT_NOT_REACHED(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h new file mode 100644 index 0000000..cf844c9 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#ifndef InjectedBundle_h +#define InjectedBundle_h + +#include "APIObject.h" +#include "InjectedBundleClient.h" +#include "SandboxExtension.h" +#include "WKBundle.h" +#include <WebCore/UserContentTypes.h> +#include <WebCore/UserScriptTypes.h> +#include <wtf/PassRefPtr.h> +#include <wtf/text/WTFString.h> + +#if PLATFORM(QT) +#include <QLibrary> +#endif + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebKit { + +#if PLATFORM(MAC) +typedef CFBundleRef PlatformBundle; +#elif PLATFORM(WIN) +typedef HMODULE PlatformBundle; +#elif PLATFORM(QT) +typedef QLibrary PlatformBundle; +#elif PLATFORM(GTK) +typedef void* PlatformBundle; +#endif + +class ImmutableArray; +class InjectedBundleScriptWorld; +class WebPage; +class WebPageGroupProxy; + +class InjectedBundle : public APIObject { +public: + static const Type APIType = TypeBundle; + + static PassRefPtr<InjectedBundle> create(const String& path) + { + return adoptRef(new InjectedBundle(path)); + } + ~InjectedBundle(); + + bool load(APIObject* initializationUserData); + void setSandboxExtension(PassRefPtr<SandboxExtension> sandboxExtension) { m_sandboxExtension = sandboxExtension; } + + // API + void initializeClient(WKBundleClient*); + void postMessage(const String&, APIObject*); + void postSynchronousMessage(const String&, APIObject*, RefPtr<APIObject>& returnData); + + // TestRunner only SPI + void setShouldTrackVisitedLinks(bool); + void removeAllVisitedLinks(); + void activateMacFontAscentHack(); + void overrideXSSAuditorEnabledForTestRunner(WebPageGroupProxy* pageGroup, bool enabled); + + // UserContent API + void addUserScript(WebPageGroupProxy*, InjectedBundleScriptWorld*, const String& source, const String& url, ImmutableArray* whitelist, ImmutableArray* blacklist, WebCore::UserScriptInjectionTime, WebCore::UserContentInjectedFrames); + void addUserStyleSheet(WebPageGroupProxy*, InjectedBundleScriptWorld*, const String& source, const String& url, ImmutableArray* whitelist, ImmutableArray* blacklist, WebCore::UserContentInjectedFrames); + void removeUserScript(WebPageGroupProxy*, InjectedBundleScriptWorld*, const String& url); + void removeUserStyleSheet(WebPageGroupProxy*, InjectedBundleScriptWorld*, const String& url); + void removeUserScripts(WebPageGroupProxy*, InjectedBundleScriptWorld*); + void removeUserStyleSheets(WebPageGroupProxy*, InjectedBundleScriptWorld*); + void removeAllUserContent(WebPageGroupProxy*); + + // Garbage collection API + void garbageCollectJavaScriptObjects(); + void garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(bool waitUntilDone); + size_t javaScriptObjectsCount(); + + // Callback hooks + void didCreatePage(WebPage*); + void willDestroyPage(WebPage*); + void didInitializePageGroup(WebPageGroupProxy*); + void didReceiveMessage(const String&, APIObject*); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + static void reportException(JSContextRef, JSValueRef exception); + +private: + InjectedBundle(const String&); + + virtual Type type() const { return APIType; } + + String m_path; + PlatformBundle m_platformBundle; // This is leaked right now, since we never unload the bundle/module. + + RefPtr<SandboxExtension> m_sandboxExtension; + + InjectedBundleClient m_client; +}; + +} // namespace WebKit + +#endif // InjectedBundle_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.cpp new file mode 100644 index 0000000..9f50942 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.cpp @@ -0,0 +1,78 @@ +/* + * 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 "InjectedBundleBackForwardList.h" + +#include "InjectedBundleBackForwardListItem.h" +#include "WebBackForwardListProxy.h" +#include "WebPage.h" +#include <WebCore/BackForwardController.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<InjectedBundleBackForwardListItem> InjectedBundleBackForwardList::itemAtIndex(int index) const +{ + if (!m_page) + return 0; + Page* page = m_page->corePage(); + if (!page) + return 0; + return InjectedBundleBackForwardListItem::create(page->backForward()->itemAtIndex(index)); +} + +int InjectedBundleBackForwardList::backListCount() const +{ + if (!m_page) + return 0; + Page* page = m_page->corePage(); + if (!page) + return 0; + return page->backForward()->backCount(); +} + +int InjectedBundleBackForwardList::forwardListCount() const +{ + if (!m_page) + return 0; + Page* page = m_page->corePage(); + if (!page) + return 0; + return page->backForward()->forwardCount(); +} + +void InjectedBundleBackForwardList::clear() +{ + if (!m_page) + return; + Page* page = m_page->corePage(); + if (!page) + return; + static_cast<WebBackForwardListProxy*>(page->backForward()->client())->clear(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.h new file mode 100644 index 0000000..952bdb6 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef InjectedBundleBackForwardList_h +#define InjectedBundleBackForwardList_h + +#include "APIObject.h" +#include <wtf/PassRefPtr.h> + +namespace WebKit { + +class WebPage; + +class InjectedBundleBackForwardListItem; + +class InjectedBundleBackForwardList : public APIObject { +public: + static const Type APIType = TypeBundleBackForwardList; + + static PassRefPtr<InjectedBundleBackForwardList> create(WebPage* page) + { + return adoptRef(new InjectedBundleBackForwardList(page)); + } + + void detach() { m_page = 0; } + + void clear(); + + PassRefPtr<InjectedBundleBackForwardListItem> itemAtIndex(int) const; + int backListCount() const; + int forwardListCount() const; + +private: + InjectedBundleBackForwardList(WebPage* page) : m_page(page) { } + + virtual Type type() const { return APIType; } + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // InjectedBundleBackForwardList_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.cpp new file mode 100644 index 0000000..222dfa3 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.cpp @@ -0,0 +1,44 @@ +/* + * 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 "InjectedBundleBackForwardListItem.h" + +#include "ImmutableArray.h" + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<ImmutableArray> InjectedBundleBackForwardListItem::children() const +{ + const HistoryItemVector& children = m_item->children(); + size_t size = children.size(); + Vector<RefPtr<APIObject> > vector(size); + for (size_t i = 0; i < size; ++i) + vector[i] = InjectedBundleBackForwardListItem::create(children[i]); + return ImmutableArray::adopt(vector); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.h new file mode 100644 index 0000000..6cd9ec6 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.h @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#ifndef InjectedBundleBackForwardListItem_h +#define InjectedBundleBackForwardListItem_h + +#include "APIObject.h" +#include <WebCore/HistoryItem.h> + +namespace WebKit { + +class ImmutableArray; +class WebPageProxy; + +class InjectedBundleBackForwardListItem : public APIObject { +public: + static const Type APIType = TypeBundleBackForwardListItem; + + static PassRefPtr<InjectedBundleBackForwardListItem> create(PassRefPtr<WebCore::HistoryItem> item) + { + if (!item) + return 0; + return adoptRef(new InjectedBundleBackForwardListItem(item)); + } + + WebCore::HistoryItem* item() const { return m_item.get(); } + + const String& originalURL() const { return m_item->originalURLString(); } + const String& url() const { return m_item->urlString(); } + const String& title() const { return m_item->title(); } + + const String& target() const { return m_item->target(); } + bool isTargetItem() const { return m_item->isTargetItem(); } + + PassRefPtr<ImmutableArray> children() const; + +private: + InjectedBundleBackForwardListItem(PassRefPtr<WebCore::HistoryItem> item) : m_item(item) { } + + virtual Type type() const { return APIType; } + + RefPtr<WebCore::HistoryItem> m_item; +}; + +} // namespace WebKit + +#endif // InjectedBundleBackForwardListItem_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.cpp new file mode 100644 index 0000000..de572d0 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.cpp @@ -0,0 +1,64 @@ +/* + * 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 "InjectedBundleClient.h" + +#include "WKBundleAPICast.h" + +namespace WebKit { + +void InjectedBundleClient::didCreatePage(InjectedBundle* bundle, WebPage* page) +{ + if (!m_client.didCreatePage) + return; + + m_client.didCreatePage(toAPI(bundle), toAPI(page), m_client.clientInfo); +} + +void InjectedBundleClient::willDestroyPage(InjectedBundle* bundle, WebPage* page) +{ + if (!m_client.willDestroyPage) + return; + + m_client.willDestroyPage(toAPI(bundle), toAPI(page), m_client.clientInfo); +} + +void InjectedBundleClient::didInitializePageGroup(InjectedBundle* bundle, WebPageGroupProxy* pageGroup) +{ + if (!m_client.didInitializePageGroup) + return; + + m_client.didInitializePageGroup(toAPI(bundle), toAPI(pageGroup), m_client.clientInfo); +} + +void InjectedBundleClient::didReceiveMessage(InjectedBundle* bundle, const String& messageName, APIObject* messageBody) +{ + if (!m_client.didReceiveMessage) + return; + + m_client.didReceiveMessage(toAPI(bundle), toAPI(messageName.impl()), toAPI(messageBody), m_client.clientInfo); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.h new file mode 100644 index 0000000..36bb60a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#ifndef InjectedBundleClient_h +#define InjectedBundleClient_h + +#include "APIClient.h" +#include "WKBundle.h" +#include <wtf/Forward.h> + +namespace WebKit { + +class APIObject; +class InjectedBundle; +class WebPage; +class WebPageGroupProxy; + +class InjectedBundleClient : public APIClient<WKBundleClient> { +public: + void didCreatePage(InjectedBundle*, WebPage*); + void willDestroyPage(InjectedBundle*, WebPage*); + void didInitializePageGroup(InjectedBundle*, WebPageGroupProxy*); + void didReceiveMessage(InjectedBundle*, const String& messageName, APIObject* messageBody); +}; + +} // namespace WebKit + + +#endif // InjectedBundleClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp new file mode 100644 index 0000000..ab59226 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp @@ -0,0 +1,112 @@ +/* + * 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 "InjectedBundleHitTestResult.h" + +#include "InjectedBundleNodeHandle.h" +#include "WebFrame.h" +#include "WebFrameLoaderClient.h" +#include <WebCore/Document.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoader.h> +#include <WebCore/KURL.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<InjectedBundleHitTestResult> InjectedBundleHitTestResult::create(const WebCore::HitTestResult& hitTestResult) +{ + return adoptRef(new InjectedBundleHitTestResult(hitTestResult)); +} + +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleHitTestResult::nodeHandle() const +{ + return InjectedBundleNodeHandle::getOrCreate(m_hitTestResult.innerNonSharedNode()); +} + +WebFrame* InjectedBundleHitTestResult::frame() const +{ + Node* node = m_hitTestResult.innerNonSharedNode(); + if (!node) + return 0; + + Document* document = node->document(); + if (!document) + return 0; + + Frame* frame = document->frame(); + if (!frame) + return 0; + + return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); +} + +WebFrame* InjectedBundleHitTestResult::targetFrame() const +{ + Frame* frame = m_hitTestResult.targetFrame(); + if (!frame) + return 0; + + return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); +} + +String InjectedBundleHitTestResult::absoluteImageURL() const +{ + return m_hitTestResult.absoluteImageURL().string(); +} + +String InjectedBundleHitTestResult::absoluteLinkURL() const +{ + return m_hitTestResult.absoluteLinkURL().string(); +} + +String InjectedBundleHitTestResult::absoluteMediaURL() const +{ + return m_hitTestResult.absoluteMediaURL().string(); +} + +String InjectedBundleHitTestResult::linkLabel() const +{ + return m_hitTestResult.textContent(); +} + +String InjectedBundleHitTestResult::linkTitle() const +{ + return m_hitTestResult.titleDisplayString(); +} + +WebCore::IntRect InjectedBundleHitTestResult::imageRect() const +{ + return m_hitTestResult.imageRect(); +} + +bool InjectedBundleHitTestResult::isSelected() const +{ + return m_hitTestResult.isSelected(); +} + +} // WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.h new file mode 100644 index 0000000..b09da1c --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.h @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#ifndef InjectedBundleHitTestResult_h +#define InjectedBundleHitTestResult_h + +#include "APIObject.h" +#include <WebCore/HitTestResult.h> +#include <wtf/Forward.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebKit { + +class InjectedBundleNodeHandle; +class WebFrame; + +class InjectedBundleHitTestResult : public APIObject { +public: + static const Type APIType = TypeBundleHitTestResult; + + static PassRefPtr<InjectedBundleHitTestResult> create(const WebCore::HitTestResult&); + + const WebCore::HitTestResult& coreHitTestResult() const { return m_hitTestResult; } + + PassRefPtr<InjectedBundleNodeHandle> nodeHandle() const; + WebFrame* frame() const; + WebFrame* targetFrame() const; + + String absoluteImageURL() const; + String absoluteLinkURL() const; + String absoluteMediaURL() const; + + String linkLabel() const; + String linkTitle() const; + + WebCore::IntRect imageRect() const; + + bool isSelected() const; + +private: + explicit InjectedBundleHitTestResult(const WebCore::HitTestResult& hitTestResult) + : m_hitTestResult(hitTestResult) + { + } + + virtual Type type() const { return APIType; } + + WebCore::HitTestResult m_hitTestResult; +}; + +} // namespace WebKit + +#endif // InjectedBundleHitTestResult_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp new file mode 100644 index 0000000..a2d16cb --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp @@ -0,0 +1,76 @@ +/* + * 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 "InjectedBundlePageContextMenuClient.h" + +#include "ImmutableArray.h" +#include "InjectedBundleHitTestResult.h" +#include "Logging.h" +#include "MutableArray.h" +#include "WebContextMenuItem.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include <WebCore/ContextMenu.h> + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundlePageContextMenuClient::getCustomMenuFromDefaultItems(WebPage* page, InjectedBundleHitTestResult* hitTestResult, const Vector<WebContextMenuItemData>& defaultMenu, Vector<WebContextMenuItemData>& newMenu, RefPtr<APIObject>& userData) +{ + if (!m_client.getContextMenuFromDefaultMenu) + return false; + + RefPtr<MutableArray> defaultMenuArray = MutableArray::create(); + defaultMenuArray->reserveCapacity(defaultMenu.size()); + for (unsigned i = 0; i < defaultMenu.size(); ++i) + defaultMenuArray->append(WebContextMenuItem::create(defaultMenu[i]).get()); + + WKArrayRef newMenuWK = 0; + WKTypeRef userDataToPass = 0; + m_client.getContextMenuFromDefaultMenu(toAPI(page), toAPI(hitTestResult), toAPI(defaultMenuArray.get()), &newMenuWK, &userDataToPass, m_client.clientInfo); + RefPtr<ImmutableArray> array = adoptRef(toImpl(newMenuWK)); + userData = adoptRef(toImpl(userDataToPass)); + + newMenu.clear(); + + if (!array || !array->size()) + return true; + + size_t size = array->size(); + for (size_t i = 0; i < size; ++i) { + WebContextMenuItem* item = array->at<WebContextMenuItem>(i); + if (!item) { + LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i); + continue; + } + + newMenu.append(*item->data()); + } + + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h new file mode 100644 index 0000000..1d17a8a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#ifndef InjectedBundlePageContextMenuClient_h +#define InjectedBundlePageContextMenuClient_h + +#include "APIClient.h" +#include "WKBundlePage.h" +#include <wtf/Vector.h> + +namespace WebCore { + class ContextMenu; +} + +namespace WebKit { + +class APIObject; +class InjectedBundleHitTestResult; +class WebContextMenuItemData; +class WebPage; + +class InjectedBundlePageContextMenuClient : public APIClient<WKBundlePageContextMenuClient> { +public: + bool getCustomMenuFromDefaultItems(WebPage*, InjectedBundleHitTestResult*, const Vector<WebContextMenuItemData>& defaultMenu, Vector<WebContextMenuItemData>& newMenu, RefPtr<APIObject>& userData); +}; + +} // namespace WebKit + +#endif // InjectedBundlePageEditorClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp new file mode 100644 index 0000000..40996c2 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp @@ -0,0 +1,127 @@ +/* + * 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 "InjectedBundlePageEditorClient.h" + +#include "InjectedBundleNodeHandle.h" +#include "InjectedBundleRangeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundlePageEditorClient::shouldBeginEditing(WebPage* page, Range* range) +{ + if (m_client.shouldBeginEditing) { + RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); + return m_client.shouldBeginEditing(toAPI(page), toAPI(rangeHandle.get()), m_client.clientInfo); + } + return true; +} + +bool InjectedBundlePageEditorClient::shouldEndEditing(WebPage* page, Range* range) +{ + if (m_client.shouldEndEditing) { + RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); + return m_client.shouldEndEditing(toAPI(page), toAPI(rangeHandle.get()), m_client.clientInfo); + } + return true; +} + +bool InjectedBundlePageEditorClient::shouldInsertNode(WebPage* page, Node* node, Range* rangeToReplace, EditorInsertAction action) +{ + if (m_client.shouldInsertNode) { + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(node); + RefPtr<InjectedBundleRangeHandle> rangeToReplaceHandle = InjectedBundleRangeHandle::getOrCreate(rangeToReplace); + return m_client.shouldInsertNode(toAPI(page), toAPI(nodeHandle.get()), toAPI(rangeToReplaceHandle.get()), toAPI(action), m_client.clientInfo); + } + return true; +} + +bool InjectedBundlePageEditorClient::shouldInsertText(WebPage* page, StringImpl* text, Range* rangeToReplace, EditorInsertAction action) +{ + if (m_client.shouldInsertText) { + RefPtr<InjectedBundleRangeHandle> rangeToReplaceHandle = InjectedBundleRangeHandle::getOrCreate(rangeToReplace); + return m_client.shouldInsertText(toAPI(page), toAPI(text), toAPI(rangeToReplaceHandle.get()), toAPI(action), m_client.clientInfo); + } + return true; +} + +bool InjectedBundlePageEditorClient::shouldDeleteRange(WebPage* page, Range* range) +{ + if (m_client.shouldDeleteRange) { + RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); + return m_client.shouldDeleteRange(toAPI(page), toAPI(rangeHandle.get()), m_client.clientInfo); + } + return true; +} + +bool InjectedBundlePageEditorClient::shouldChangeSelectedRange(WebPage* page, Range* fromRange, Range* toRange, EAffinity affinity, bool stillSelecting) +{ + if (m_client.shouldChangeSelectedRange) { + RefPtr<InjectedBundleRangeHandle> fromRangeHandle = InjectedBundleRangeHandle::getOrCreate(fromRange); + RefPtr<InjectedBundleRangeHandle> toRangeHandle = InjectedBundleRangeHandle::getOrCreate(toRange); + return m_client.shouldChangeSelectedRange(toAPI(page), toAPI(fromRangeHandle.get()), toAPI(toRangeHandle.get()), toAPI(affinity), stillSelecting, m_client.clientInfo); + } + return true; +} + +bool InjectedBundlePageEditorClient::shouldApplyStyle(WebPage* page, CSSStyleDeclaration* style, Range* range) +{ + if (m_client.shouldApplyStyle) { + RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); + return m_client.shouldApplyStyle(toAPI(page), toAPI(style), toAPI(rangeHandle.get()), m_client.clientInfo); + } + return true; +} + +void InjectedBundlePageEditorClient::didBeginEditing(WebPage* page, StringImpl* notificationName) +{ + if (m_client.didBeginEditing) + m_client.didBeginEditing(toAPI(page), toAPI(notificationName), m_client.clientInfo); +} + +void InjectedBundlePageEditorClient::didEndEditing(WebPage* page, StringImpl* notificationName) +{ + if (m_client.didEndEditing) + m_client.didEndEditing(toAPI(page), toAPI(notificationName), m_client.clientInfo); +} + +void InjectedBundlePageEditorClient::didChange(WebPage* page, StringImpl* notificationName) +{ + if (m_client.didChange) + m_client.didChange(toAPI(page), toAPI(notificationName), m_client.clientInfo); +} + +void InjectedBundlePageEditorClient::didChangeSelection(WebPage* page, StringImpl* notificationName) +{ + if (m_client.didChangeSelection) + m_client.didChangeSelection(toAPI(page), toAPI(notificationName), m_client.clientInfo); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h new file mode 100644 index 0000000..c1a5aab --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#ifndef InjectedBundlePageEditorClient_h +#define InjectedBundlePageEditorClient_h + +#include "APIClient.h" +#include "WKBundlePage.h" +#include <WebCore/EditorInsertAction.h> +#include <WebCore/TextAffinity.h> +#include <wtf/Forward.h> + +namespace WebCore { + class CSSStyleDeclaration; + class Node; + class Range; +} + +namespace WebKit { + +class WebFrame; +class WebPage; + +class InjectedBundlePageEditorClient : public APIClient<WKBundlePageEditorClient> { +public: + bool shouldBeginEditing(WebPage*, WebCore::Range*); + bool shouldEndEditing(WebPage*, WebCore::Range*); + bool shouldInsertNode(WebPage*, WebCore::Node*, WebCore::Range* rangeToReplace, WebCore::EditorInsertAction); + bool shouldInsertText(WebPage*, StringImpl*, WebCore::Range* rangeToReplace, WebCore::EditorInsertAction); + bool shouldDeleteRange(WebPage*, WebCore::Range*); + bool shouldChangeSelectedRange(WebPage*, WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity affinity, bool stillSelecting); + bool shouldApplyStyle(WebPage*, WebCore::CSSStyleDeclaration*, WebCore::Range*); + void didBeginEditing(WebPage*, StringImpl* notificationName); + void didEndEditing(WebPage*, StringImpl* notificationName); + void didChange(WebPage*, StringImpl* notificationName); + void didChangeSelection(WebPage*, StringImpl* notificationName); +}; + +} // namespace WebKit + +#endif // InjectedBundlePageEditorClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.cpp new file mode 100644 index 0000000..4d210f2 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.cpp @@ -0,0 +1,102 @@ +/* + * 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 "InjectedBundlePageFormClient.h" + +#include "ImmutableDictionary.h" +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include <WebCore/HTMLFormElement.h> +#include <WebCore/HTMLInputElement.h> +#include <WebCore/HTMLTextAreaElement.h> + +using namespace WebCore; + +namespace WebKit { + +void InjectedBundlePageFormClient::textFieldDidBeginEditing(WebPage* page, HTMLInputElement* inputElement, WebFrame* frame) +{ + if (!m_client.textFieldDidBeginEditing) + return; + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement); + m_client.textFieldDidBeginEditing(toAPI(page), toAPI(nodeHandle.get()), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageFormClient::textFieldDidEndEditing(WebPage* page, HTMLInputElement* inputElement, WebFrame* frame) +{ + if (!m_client.textFieldDidEndEditing) + return; + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement); + m_client.textFieldDidEndEditing(toAPI(page), toAPI(nodeHandle.get()), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageFormClient::textDidChangeInTextField(WebPage* page, HTMLInputElement* inputElement, WebFrame* frame) +{ + if (!m_client.textDidChangeInTextField) + return; + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement); + m_client.textDidChangeInTextField(toAPI(page), toAPI(nodeHandle.get()), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageFormClient::textDidChangeInTextArea(WebPage* page, HTMLTextAreaElement* textAreaElement, WebFrame* frame) +{ + if (!m_client.textDidChangeInTextArea) + return; + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(textAreaElement); + m_client.textDidChangeInTextArea(toAPI(page), toAPI(nodeHandle.get()), toAPI(frame), m_client.clientInfo); +} + +bool InjectedBundlePageFormClient::shouldPerformActionInTextField(WebPage* page, HTMLInputElement* inputElement, WKInputFieldActionType actionType, WebFrame* frame) +{ + if (!m_client.shouldPerformActionInTextField) + return false; + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(inputElement); + return m_client.shouldPerformActionInTextField(toAPI(page), toAPI(nodeHandle.get()), actionType, toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageFormClient::willSubmitForm(WebPage* page, HTMLFormElement* formElement, WebFrame* frame, WebFrame* sourceFrame, const Vector<std::pair<String, String> >& values, RefPtr<APIObject>& userData) +{ + if (!m_client.willSubmitForm) + return; + + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(formElement); + + ImmutableDictionary::MapType map; + for (size_t i = 0; i < values.size(); ++i) + map.set(values[i].first, WebString::create(values[i].second)); + RefPtr<ImmutableDictionary> textFieldsMap = ImmutableDictionary::adopt(map); + + WKTypeRef userDataToPass = 0; + m_client.willSubmitForm(toAPI(page), toAPI(nodeHandle.get()), toAPI(frame), toAPI(sourceFrame), toAPI(textFieldsMap.get()), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.h new file mode 100644 index 0000000..23f4cb2 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.h @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#ifndef InjectedBundlePageFormClient_h +#define InjectedBundlePageFormClient_h + +#include "APIClient.h" +#include "WKBundlePage.h" +#include <algorithm> +#include <wtf/Forward.h> +#include <wtf/Vector.h> + +namespace WebCore { + class HTMLFormElement; + class HTMLInputElement; + class HTMLTextAreaElement; +} + +namespace WebKit { + +class APIObject; +class ImmutableDictionary; +class WebFrame; +class WebPage; + +class InjectedBundlePageFormClient : public APIClient<WKBundlePageFormClient> { +public: + void textFieldDidBeginEditing(WebPage*, WebCore::HTMLInputElement*, WebFrame*); + void textFieldDidEndEditing(WebPage*, WebCore::HTMLInputElement*, WebFrame*); + void textDidChangeInTextField(WebPage*, WebCore::HTMLInputElement*, WebFrame*); + void textDidChangeInTextArea(WebPage*, WebCore::HTMLTextAreaElement*, WebFrame*); + bool shouldPerformActionInTextField(WebPage*, WebCore::HTMLInputElement*, WKInputFieldActionType, WebFrame*); + void willSubmitForm(WebPage*, WebCore::HTMLFormElement*, WebFrame*, WebFrame* sourceFrame, const Vector<std::pair<String, String> >&, RefPtr<APIObject>& userData); +}; + +} // namespace WebKit + +#endif // InjectedBundlePageFormClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp new file mode 100644 index 0000000..23341c5 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp @@ -0,0 +1,218 @@ +/* + * 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 "InjectedBundlePageLoaderClient.h" + +#include "InjectedBundleScriptWorld.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebError.h" +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +void InjectedBundlePageLoaderClient::didStartProvisionalLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didStartProvisionalLoadForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didStartProvisionalLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didReceiveServerRedirectForProvisionalLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didReceiveServerRedirectForProvisionalLoadForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didFailProvisionalLoadWithErrorForFrame(WebPage* page, WebFrame* frame, const ResourceError& error, RefPtr<APIObject>& userData) +{ + if (!m_client.didFailProvisionalLoadWithErrorForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didCommitLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didCommitLoadForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didCommitLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didFinishDocumentLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didFinishDocumentLoadForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didFinishDocumentLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didFinishLoadForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didFinishLoadForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didFinishLoadForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didFailLoadWithErrorForFrame(WebPage* page, WebFrame* frame, const ResourceError& error, RefPtr<APIObject>& userData) +{ + if (!m_client.didFailLoadWithErrorForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didFailLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didSameDocumentNavigationForFrame(WebPage* page, WebFrame* frame, SameDocumentNavigationType type, RefPtr<APIObject>& userData) +{ + if (!m_client.didSameDocumentNavigationForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didSameDocumentNavigationForFrame(toAPI(page), toAPI(frame), toAPI(type), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didReceiveTitleForFrame(WebPage* page, const String& title, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didReceiveTitleForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didReceiveTitleForFrame(toAPI(page), toAPI(title.impl()), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didFirstLayoutForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didFirstLayoutForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didFirstLayoutForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didFirstVisuallyNonEmptyLayoutForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didFirstVisuallyNonEmptyLayoutForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didRemoveFrameFromHierarchy(WebPage* page , WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didRemoveFrameFromHierarchy) + return; + + WKTypeRef userDataToPass = 0; + m_client.didRemoveFrameFromHierarchy(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didDisplayInsecureContentForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didDisplayInsecureContentForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didDisplayInsecureContentForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageLoaderClient::didRunInsecureContentForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didRunInsecureContentForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didRunInsecureContentForFrame(toAPI(page), toAPI(frame), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +bool InjectedBundlePageLoaderClient::shouldLoadResourceForFrame(WebPage* page, WebFrame* frame, const String& resourceURL) +{ + if (!m_client.shouldLoadResourceForFrame) + return true; + + return m_client.shouldLoadResourceForFrame(toAPI(page), toAPI(frame), toAPI(resourceURL.impl()), m_client.clientInfo); +} + +void InjectedBundlePageLoaderClient::didClearWindowObjectForFrame(WebPage* page, WebFrame* frame, DOMWrapperWorld* world) +{ + if (!m_client.didClearWindowObjectForFrame) + return; + + m_client.didClearWindowObjectForFrame(toAPI(page), toAPI(frame), toAPI(InjectedBundleScriptWorld::getOrCreate(world).get()), m_client.clientInfo); +} + +void InjectedBundlePageLoaderClient::didCancelClientRedirectForFrame(WebPage* page, WebFrame* frame) +{ + if (!m_client.didCancelClientRedirectForFrame) + return; + + m_client.didCancelClientRedirectForFrame(toAPI(page), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageLoaderClient::willPerformClientRedirectForFrame(WebPage* page, WebFrame* frame, const String& url, double delay, double date) +{ + if (!m_client.willPerformClientRedirectForFrame) + return; + + m_client.willPerformClientRedirectForFrame(toAPI(page), toAPI(frame), toURLRef(url.impl()), delay, date, m_client.clientInfo); +} + +void InjectedBundlePageLoaderClient::didHandleOnloadEventsForFrame(WebPage* page, WebFrame* frame) +{ + if (!m_client.didHandleOnloadEventsForFrame) + return; + + m_client.didHandleOnloadEventsForFrame(toAPI(page), toAPI(frame), m_client.clientInfo); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h new file mode 100644 index 0000000..e983b48 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#ifndef InjectedBundlePageLoaderClient_h +#define InjectedBundlePageLoaderClient_h + +#include "APIClient.h" +#include "SameDocumentNavigationType.h" +#include "WKBundlePage.h" +#include <JavaScriptCore/JSBase.h> +#include <wtf/Forward.h> + +namespace WebCore { +class DOMWrapperWorld; +class ResourceError; +} + +namespace WebKit { + +class APIObject; +class WebPage; +class WebFrame; + +class InjectedBundlePageLoaderClient : public APIClient<WKBundlePageLoaderClient> { +public: + void didStartProvisionalLoadForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didReceiveServerRedirectForProvisionalLoadForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didFailProvisionalLoadWithErrorForFrame(WebPage*, WebFrame*, const WebCore::ResourceError&, RefPtr<APIObject>& userData); + void didCommitLoadForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didFinishDocumentLoadForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didFinishLoadForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didFailLoadWithErrorForFrame(WebPage*, WebFrame*, const WebCore::ResourceError&, RefPtr<APIObject>& userData); + void didSameDocumentNavigationForFrame(WebPage*, WebFrame*, SameDocumentNavigationType, RefPtr<APIObject>& userData); + void didReceiveTitleForFrame(WebPage*, const String&, WebFrame*, RefPtr<APIObject>& userData); + void didFirstLayoutForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didFirstVisuallyNonEmptyLayoutForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didRemoveFrameFromHierarchy(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didDisplayInsecureContentForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didRunInsecureContentForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + + bool shouldLoadResourceForFrame(WebPage*, WebFrame*, const String&); + + void didClearWindowObjectForFrame(WebPage*, WebFrame*, WebCore::DOMWrapperWorld*); + void didCancelClientRedirectForFrame(WebPage*, WebFrame*); + void willPerformClientRedirectForFrame(WebPage*, WebFrame*, const String& url, double delay, double date); + void didHandleOnloadEventsForFrame(WebPage*, WebFrame*); +}; + +} // namespace WebKit + +#endif // InjectedBundlePageLoaderClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp new file mode 100644 index 0000000..56e4434 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp @@ -0,0 +1,85 @@ +/* + * 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 "InjectedBundlePageUIClient.h" + +#include "InjectedBundleHitTestResult.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +void InjectedBundlePageUIClient::willAddMessageToConsole(WebPage* page, const String& message, int32_t lineNumber) +{ + if (m_client.willAddMessageToConsole) + m_client.willAddMessageToConsole(toAPI(page), toAPI(message.impl()), lineNumber, m_client.clientInfo); +} + +void InjectedBundlePageUIClient::willSetStatusbarText(WebPage* page, const String& statusbarText) +{ + if (m_client.willSetStatusbarText) + m_client.willSetStatusbarText(toAPI(page), toAPI(statusbarText.impl()), m_client.clientInfo); +} + +void InjectedBundlePageUIClient::willRunJavaScriptAlert(WebPage* page, const String& alertText, WebFrame* frame) +{ + if (m_client.willRunJavaScriptAlert) + m_client.willRunJavaScriptAlert(toAPI(page), toAPI(alertText.impl()), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageUIClient::willRunJavaScriptConfirm(WebPage* page, const String& message, WebFrame* frame) +{ + if (m_client.willRunJavaScriptConfirm) + m_client.willRunJavaScriptConfirm(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageUIClient::willRunJavaScriptPrompt(WebPage* page, const String& message, const String& defaultValue, WebFrame* frame) +{ + if (m_client.willRunJavaScriptPrompt) + m_client.willRunJavaScriptPrompt(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), m_client.clientInfo); +} + +void InjectedBundlePageUIClient::mouseDidMoveOverElement(WebPage* page, const HitTestResult& coreHitTestResult, WebEvent::Modifiers modifiers, RefPtr<APIObject>& userData) +{ + if (!m_client.mouseDidMoveOverElement) + return; + + RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(coreHitTestResult); + + WKTypeRef userDataToPass = 0; + m_client.mouseDidMoveOverElement(toAPI(page), toAPI(hitTestResult.get()), toAPI(modifiers), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +void InjectedBundlePageUIClient::pageDidScroll(WebPage* page) +{ + if (m_client.pageDidScroll) + m_client.pageDidScroll(toAPI(page), m_client.clientInfo); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.h new file mode 100644 index 0000000..93c19e9 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#ifndef InjectedBundlePageUIClient_h +#define InjectedBundlePageUIClient_h + +#include "APIClient.h" +#include "WKBundlePage.h" +#include "WebEvent.h" +#include <wtf/Forward.h> + +namespace WebCore { + class HitTestResult; +} + +namespace WebKit { + +class APIObject; +class WebFrame; +class WebPage; + +class InjectedBundlePageUIClient : public APIClient<WKBundlePageUIClient> { +public: + void willAddMessageToConsole(WebPage*, const String& message, int32_t lineNumber); + void willSetStatusbarText(WebPage*, const String&); + void willRunJavaScriptAlert(WebPage*, const String&, WebFrame*); + void willRunJavaScriptConfirm(WebPage*, const String&, WebFrame*); + void willRunJavaScriptPrompt(WebPage*, const String&, const String&, WebFrame*); + void mouseDidMoveOverElement(WebPage*, const WebCore::HitTestResult&, WebEvent::Modifiers, RefPtr<APIObject>& userData); + void pageDidScroll(WebPage*); +}; + +} // namespace WebKit + +#endif // InjectedBundlePageUIClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp new file mode 100644 index 0000000..d764cf2 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp @@ -0,0 +1,84 @@ +/* + * 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 "InjectedBundleScriptWorld.h" + +#include <WebCore/DOMWrapperWorld.h> +#include <WebCore/ScriptController.h> +#include <wtf/HashMap.h> + +using namespace WebCore; + +namespace WebKit { + +typedef HashMap<DOMWrapperWorld*, InjectedBundleScriptWorld*> WorldMap; + +static WorldMap& allWorlds() +{ + DEFINE_STATIC_LOCAL(WorldMap, map, ()); + return map; +} + +PassRefPtr<InjectedBundleScriptWorld> InjectedBundleScriptWorld::create() +{ + return adoptRef(new InjectedBundleScriptWorld(ScriptController::createWorld())); +} + +PassRefPtr<InjectedBundleScriptWorld> InjectedBundleScriptWorld::getOrCreate(DOMWrapperWorld* world) +{ + if (world == mainThreadNormalWorld()) + return normalWorld(); + + if (InjectedBundleScriptWorld* existingWorld = allWorlds().get(world)) + return existingWorld; + + return adoptRef(new InjectedBundleScriptWorld(world)); +} + +InjectedBundleScriptWorld* InjectedBundleScriptWorld::normalWorld() +{ + static InjectedBundleScriptWorld* world = adoptRef(new InjectedBundleScriptWorld(mainThreadNormalWorld())).leakRef(); + return world; +} + +InjectedBundleScriptWorld::InjectedBundleScriptWorld(PassRefPtr<DOMWrapperWorld> world) + : m_world(world) +{ + ASSERT(!allWorlds().contains(m_world.get())); + allWorlds().add(m_world.get(), this); +} + +InjectedBundleScriptWorld::~InjectedBundleScriptWorld() +{ + ASSERT(allWorlds().contains(m_world.get())); + allWorlds().remove(m_world.get()); +} + +DOMWrapperWorld* InjectedBundleScriptWorld::coreWorld() const +{ + return m_world.get(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.h new file mode 100644 index 0000000..00dd14a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#ifndef InjectedBundleScriptWorld_h +#define InjectedBundleScriptWorld_h + +#include "APIObject.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + class DOMWrapperWorld; +} + +namespace WebKit { + +class InjectedBundleScriptWorld : public APIObject { +public: + static const Type APIType = TypeBundleScriptWorld; + + static PassRefPtr<InjectedBundleScriptWorld> create(); + static PassRefPtr<InjectedBundleScriptWorld> getOrCreate(WebCore::DOMWrapperWorld*); + static InjectedBundleScriptWorld* normalWorld(); + + virtual ~InjectedBundleScriptWorld(); + + WebCore::DOMWrapperWorld* coreWorld() const; + +private: + InjectedBundleScriptWorld(PassRefPtr<WebCore::DOMWrapperWorld>); + + virtual Type type() const { return APIType; } + + RefPtr<WebCore::DOMWrapperWorld> m_world; +}; + +} // namespace WebKit + +#endif // InjectedBundleScriptWorld_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleUserMessageCoders.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleUserMessageCoders.h new file mode 100644 index 0000000..49d6696 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleUserMessageCoders.h @@ -0,0 +1,141 @@ +/* + * 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. + */ + +#ifndef InjectedBundleUserMessageCoders_h +#define InjectedBundleUserMessageCoders_h + +#include "UserMessageCoders.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebPageGroupData.h" +#include "WebPageGroupProxy.h" +#include "WebProcess.h" + +namespace WebKit { + +// Adds +// - BundlePage -> Page +// - BundleFrame -> Frame +// - BundlePageGroup -> PageGroup + +class InjectedBundleUserMessageEncoder : public UserMessageEncoder<InjectedBundleUserMessageEncoder> { +public: + typedef UserMessageEncoder<InjectedBundleUserMessageEncoder> Base; + + InjectedBundleUserMessageEncoder(APIObject* root) + : Base(root) + { + } + + void encode(CoreIPC::ArgumentEncoder* encoder) const + { + APIObject::Type type = APIObject::TypeNull; + if (baseEncode(encoder, type)) + return; + + switch (type) { + case APIObject::TypeBundlePage: { + WebPage* page = static_cast<WebPage*>(m_root); + encoder->encode(page->pageID()); + break; + } + case APIObject::TypeBundleFrame: { + WebFrame* frame = static_cast<WebFrame*>(m_root); + encoder->encode(frame->frameID()); + break; + } + case APIObject::TypeBundlePageGroup: { + WebPageGroupProxy* pageGroup = static_cast<WebPageGroupProxy*>(m_root); + encoder->encode(pageGroup->pageGroupID()); + break; + } + default: + ASSERT_NOT_REACHED(); + break; + } + } +}; + +// Adds +// - Page -> BundlePage +// - Frame -> BundleFrame +// - PageGroup -> BundlePageGroup + +class InjectedBundleUserMessageDecoder : public UserMessageDecoder<InjectedBundleUserMessageDecoder> { +public: + typedef UserMessageDecoder<InjectedBundleUserMessageDecoder> Base; + + InjectedBundleUserMessageDecoder(RefPtr<APIObject>& root) + : Base(root) + { + } + + InjectedBundleUserMessageDecoder(InjectedBundleUserMessageDecoder&, RefPtr<APIObject>& root) + : Base(root) + { + } + + static bool decode(CoreIPC::ArgumentDecoder* decoder, InjectedBundleUserMessageDecoder& coder) + { + APIObject::Type type = APIObject::TypeNull; + if (!Base::baseDecode(decoder, coder, type)) + return false; + + if (coder.m_root || type == APIObject::TypeNull) + return true; + + switch (type) { + case APIObject::TypePage: { + uint64_t pageID; + if (!decoder->decode(pageID)) + return false; + coder.m_root = WebProcess::shared().webPage(pageID); + break; + } + case APIObject::TypeFrame: { + uint64_t frameID; + if (!decoder->decode(frameID)) + return false; + coder.m_root = WebProcess::shared().webFrame(frameID); + break; + } + case APIObject::TypePageGroup: { + WebPageGroupData pageGroupData; + if (!decoder->decode(pageGroupData)) + return false; + coder.m_root = WebProcess::shared().webPageGroup(pageGroupData); + break; + } + default: + return false; + } + + return true; + } +}; + +} // namespace WebKit + +#endif // InjectedBundleUserMessageCoders_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/gtk/InjectedBundleGtk.cpp b/Source/WebKit2/WebProcess/InjectedBundle/gtk/InjectedBundleGtk.cpp new file mode 100644 index 0000000..f992af2 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/gtk/InjectedBundleGtk.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "InjectedBundle.h" + +#include "NotImplemented.h" +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundle::load(APIObject*) +{ + return false; +} + +void InjectedBundle::activateMacFontAscentHack() +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/mac/InjectedBundleMac.cpp b/Source/WebKit2/WebProcess/InjectedBundle/mac/InjectedBundleMac.cpp new file mode 100644 index 0000000..f278ea9 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/mac/InjectedBundleMac.cpp @@ -0,0 +1,86 @@ +/* + * 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 "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" +#include <wtf/RetainPtr.h> +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundle::load(APIObject* initializationUserData) +{ + if (m_sandboxExtension) { + if (!m_sandboxExtension->consume()) { + fprintf(stderr, "InjectedBundle::load failed - Could not consume bundle sandbox extension for [%s].\n", m_path.utf8().data()); + return false; + } + + m_sandboxExtension = 0; + } + + RetainPtr<CFStringRef> injectedBundlePathStr(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(m_path.characters()), m_path.length())); + if (!injectedBundlePathStr) { + fprintf(stderr, "InjectedBundle::load failed - Could not create the path string.\n"); + return false; + } + + RetainPtr<CFURLRef> bundleURL(AdoptCF, CFURLCreateWithFileSystemPath(0, injectedBundlePathStr.get(), kCFURLPOSIXPathStyle, false)); + if (!bundleURL) { + fprintf(stderr, "InjectedBundle::load failed - Could not create the url from the path string.\n"); + return false; + } + + m_platformBundle = CFBundleCreate(0, bundleURL.get()); + if (!m_platformBundle) { + fprintf(stderr, "InjectedBundle::load failed - Could not create the bundle.\n"); + return false; + } + + if (!CFBundleLoadExecutable(m_platformBundle)) { + fprintf(stderr, "InjectedBundle::load failed - Could not load the executable from the bundle.\n"); + return false; + } + + WKBundleInitializeFunctionPtr initializeFunction = reinterpret_cast<WKBundleInitializeFunctionPtr>(CFBundleGetFunctionPointerForName(m_platformBundle, CFSTR("WKBundleInitialize"))); + if (!initializeFunction) { + fprintf(stderr, "InjectedBundle::load failed - Could not find the initialize function in the bundle executable.\n"); + return false; + } + + initializeFunction(toAPI(this), toAPI(initializationUserData)); + return true; +} + +void InjectedBundle::activateMacFontAscentHack() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/qt/InjectedBundleQt.cpp b/Source/WebKit2/WebProcess/InjectedBundle/qt/InjectedBundleQt.cpp new file mode 100644 index 0000000..9d397e8 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/qt/InjectedBundleQt.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 University of Szeged. + * + * 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 "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundle::load(APIObject* initializationUserData) +{ + m_platformBundle.setFileName(static_cast<QString>(m_path)); + if (!m_platformBundle.load()) { + qWarning("Error loading the injected bundle: %s", qPrintable(m_platformBundle.errorString())); + return false; + } + + WKBundleInitializeFunctionPtr initializeFunction = + reinterpret_cast<WKBundleInitializeFunctionPtr>(m_platformBundle.resolve("WKBundleInitialize")); + + if (!initializeFunction) { + qWarning("Error resolving WKBundleInitialize: %s", qPrintable(m_platformBundle.errorString())); + return false; + } + + initializeFunction(toAPI(this), toAPI(initializationUserData)); + return true; +} + +void InjectedBundle::activateMacFontAscentHack() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp b/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp new file mode 100644 index 0000000..3fd3333 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp @@ -0,0 +1,88 @@ +/* + * 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 "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" +#include <WebCore/SimpleFontData.h> + +#include <windows.h> +#include <winbase.h> +#include <shlobj.h> +#include <shlwapi.h> + +using namespace WebCore; + +namespace WebKit { + +// FIXME: This should try and use <WebCore/FileSystem.h>. + +static String pathGetFileName(const String& path) +{ + return String(::PathFindFileName(String(path).charactersWithNullTermination())); +} + +static String directoryName(const String& path) +{ + String fileName = pathGetFileName(path); + String dirName = String(path); + dirName.truncate(dirName.length() - pathGetFileName(path).length()); + return dirName; +} + +bool InjectedBundle::load(APIObject* initializationUserData) +{ + WCHAR currentPath[MAX_PATH]; + if (!::GetCurrentDirectoryW(MAX_PATH, currentPath)) + return false; + + String directorBundleResidesIn = directoryName(m_path); + if (!::SetCurrentDirectoryW(directorBundleResidesIn.charactersWithNullTermination())) + return false; + + m_platformBundle = ::LoadLibraryExW(m_path.charactersWithNullTermination(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!m_platformBundle) + return false; + + // Reset the current directory. + if (!::SetCurrentDirectoryW(currentPath)) { + return false; + } + + WKBundleInitializeFunctionPtr initializeFunction = reinterpret_cast<WKBundleInitializeFunctionPtr>(::GetProcAddress(m_platformBundle, "WKBundleInitialize")); + if (!initializeFunction) + return false; + + initializeFunction(toAPI(this), toAPI(initializationUserData)); + return true; +} + +void InjectedBundle::activateMacFontAscentHack() +{ + SimpleFontData::setShouldApplyMacAscentHack(true); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp new file mode 100644 index 0000000..c094505 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp @@ -0,0 +1,79 @@ +/* + * 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 "JSNPMethod.h" + +#include "JSNPObject.h" +#include "NotImplemented.h" +#include <JavaScriptCore/Error.h> +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSGlobalObject.h> +#include <WebCore/JSHTMLElement.h> +#include <WebCore/JSPluginElementFunctions.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::info, 0, 0 }; + +JSNPMethod::JSNPMethod(ExecState* exec, JSGlobalObject* globalObject, const Identifier& name, NPIdentifier npIdentifier) + : InternalFunction(&exec->globalData(), globalObject, createStructure(globalObject->functionPrototype()), name) + , m_npIdentifier(npIdentifier) +{ +} + +static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) +{ + JSNPMethod* jsNPMethod = static_cast<JSNPMethod*>(exec->callee()); + + JSValue thisValue = exec->hostThisValue(); + + // Check if we're calling a method on the plug-in script object. + if (thisValue.inherits(&JSHTMLElement::s_info)) { + JSHTMLElement* element = static_cast<JSHTMLElement*>(asObject(thisValue)); + + // Try to get the script object from the element + if (JSObject* scriptObject = pluginScriptObject(exec, element)) + thisValue = scriptObject; + } + + if (thisValue.inherits(&JSNPObject::s_info)) { + JSNPObject* jsNPObject = static_cast<JSNPObject*>(asObject(thisValue)); + + return JSValue::encode(jsNPObject->callMethod(exec, jsNPMethod->npIdentifier())); + } + + return throwVMTypeError(exec); +} + +CallType JSNPMethod::getCallData(CallData& callData) +{ + callData.native.function = callMethod; + return CallTypeHost; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h new file mode 100644 index 0000000..9a8578c --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef JSNPMethod_h +#define JSNPMethod_h + +#include <JavaScriptCore/InternalFunction.h> + +typedef void* NPIdentifier; + +namespace WebKit { + +// A JSObject that wraps an NPMethod. +class JSNPMethod : public JSC::InternalFunction { +public: + JSNPMethod(JSC::ExecState*, JSC::JSGlobalObject*, const JSC::Identifier&, NPIdentifier); + + static const JSC::ClassInfo s_info; + + NPIdentifier npIdentifier() const { return m_npIdentifier; } + +private: + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) + { + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); + } + + virtual JSC::CallType getCallData(JSC::CallData&); + virtual const JSC::ClassInfo* classInfo() const { return &s_info; } + + NPIdentifier m_npIdentifier; +}; + + +} // namespace WebKit + +#endif // JSNPMethod_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp new file mode 100644 index 0000000..d7d626f --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp @@ -0,0 +1,412 @@ +/* + * 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 "JSNPObject.h" + +#include "JSNPMethod.h" +#include "NPJSObject.h" +#include "NPRuntimeObjectMap.h" +#include "NPRuntimeUtilities.h" +#include <JavaScriptCore/Error.h> +#include <JavaScriptCore/JSGlobalObject.h> +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/ObjectPrototype.h> +#include <WebCore/IdentifierRep.h> +#include <wtf/text/WTFString.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +static NPIdentifier npIdentifierFromIdentifier(const Identifier& identifier) +{ + return static_cast<NPIdentifier>(IdentifierRep::get(identifier.ustring().utf8().data())); +} + +const ClassInfo JSNPObject::s_info = { "NPObject", 0, 0, 0 }; + +JSNPObject::JSNPObject(JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject) + : JSObjectWithGlobalObject(globalObject, createStructure(globalObject->objectPrototype())) + , m_objectMap(objectMap) + , m_npObject(npObject) +{ + // We should never have an NPJSObject inside a JSNPObject. + ASSERT(!NPJSObject::isNPJSObject(m_npObject)); + + retainNPObject(m_npObject); +} + +JSNPObject::~JSNPObject() +{ + if (!m_npObject) + return; + + m_objectMap->jsNPObjectDestroyed(this); + releaseNPObject(m_npObject); +} + +void JSNPObject::invalidate() +{ + ASSERT(m_npObject); + + releaseNPObject(m_npObject); + m_npObject = 0; +} + +JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) +{ + if (!m_npObject) + return throwInvalidAccessError(exec); + + size_t argumentCount = exec->argumentCount(); + Vector<NPVariant, 8> arguments(argumentCount); + + // Convert all arguments to NPVariants. + for (size_t i = 0; i < argumentCount; ++i) + m_objectMap->convertJSValueToNPVariant(exec, exec->argument(i), arguments[i]); + + // Calling NPClass::invoke will call into plug-in code, and there's no telling what the plug-in can do. + // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until + // the call has finished. + NPRuntimeObjectMap::PluginProtector protector(m_objectMap); + + bool returnValue; + NPVariant result; + VOID_TO_NPVARIANT(result); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + returnValue = m_npObject->_class->invoke(m_npObject, methodName, arguments.data(), argumentCount, &result); + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + } + + // Release all arguments; + for (size_t i = 0; i < argumentCount; ++i) + releaseNPVariantValue(&arguments[i]); + + if (!returnValue) + throwError(exec, createError(exec, "Error calling method on NPObject.")); + + JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); + releaseNPVariantValue(&result); + return propertyValue; +} + +JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) +{ + if (!m_npObject) + return throwInvalidAccessError(exec); + + size_t argumentCount = exec->argumentCount(); + Vector<NPVariant, 8> arguments(argumentCount); + + // Convert all arguments to NPVariants. + for (size_t i = 0; i < argumentCount; ++i) + m_objectMap->convertJSValueToNPVariant(exec, exec->argument(i), arguments[i]); + + // Calling NPClass::invokeDefault will call into plug-in code, and there's no telling what the plug-in can do. + // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until + // the call has finished. + NPRuntimeObjectMap::PluginProtector protector(m_objectMap); + + bool returnValue; + NPVariant result; + VOID_TO_NPVARIANT(result); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), argumentCount, &result); + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + } + + // Release all arguments; + for (size_t i = 0; i < argumentCount; ++i) + releaseNPVariantValue(&arguments[i]); + + if (!returnValue) + throwError(exec, createError(exec, "Error calling method on NPObject.")); + + JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); + releaseNPVariantValue(&result); + return propertyValue; +} + +JSValue JSNPObject::callConstructor(ExecState* exec) +{ + if (!m_npObject) + return throwInvalidAccessError(exec); + + size_t argumentCount = exec->argumentCount(); + Vector<NPVariant, 8> arguments(argumentCount); + + // Convert all arguments to NPVariants. + for (size_t i = 0; i < argumentCount; ++i) + m_objectMap->convertJSValueToNPVariant(exec, exec->argument(i), arguments[i]); + + // Calling NPClass::construct will call into plug-in code, and there's no telling what the plug-in can do. + // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until + // the call has finished. + NPRuntimeObjectMap::PluginProtector protector(m_objectMap); + + bool returnValue; + NPVariant result; + VOID_TO_NPVARIANT(result); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), argumentCount, &result); + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + } + + if (!returnValue) + throwError(exec, createError(exec, "Error calling method on NPObject.")); + + JSValue value = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); + releaseNPVariantValue(&result); + return value; +} + +static EncodedJSValue JSC_HOST_CALL callNPJSObject(ExecState* exec) +{ + JSObject* object = exec->callee(); + ASSERT(object->inherits(&JSNPObject::s_info)); + + return JSValue::encode(static_cast<JSNPObject*>(object)->callObject(exec)); +} + +JSC::CallType JSNPObject::getCallData(JSC::CallData& callData) +{ + if (!m_npObject || !m_npObject->_class->invokeDefault) + return CallTypeNone; + + callData.native.function = callNPJSObject; + return CallTypeHost; +} + +static EncodedJSValue JSC_HOST_CALL constructWithConstructor(ExecState* exec) +{ + JSObject* constructor = exec->callee(); + ASSERT(constructor->inherits(&JSNPObject::s_info)); + + return JSValue::encode(static_cast<JSNPObject*>(constructor)->callConstructor(exec)); +} + +ConstructType JSNPObject::getConstructData(ConstructData& constructData) +{ + if (!m_npObject || !m_npObject->_class->construct) + return ConstructTypeNone; + + constructData.native.function = constructWithConstructor; + return ConstructTypeHost; +} + +bool JSNPObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + if (!m_npObject) { + throwInvalidAccessError(exec); + return false; + } + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + + // First, check if the NPObject has a property with this name. + if (m_npObject->_class->hasProperty && m_npObject->_class->hasProperty(m_npObject, npIdentifier)) { + slot.setCustom(this, propertyGetter); + return true; + } + + // Second, check if the NPObject has a method with this name. + if (m_npObject->_class->hasMethod && m_npObject->_class->hasMethod(m_npObject, npIdentifier)) { + slot.setCustom(this, methodGetter); + return true; + } + + return false; +} + +bool JSNPObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + if (!m_npObject) { + throwInvalidAccessError(exec); + return false; + } + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + + // First, check if the NPObject has a property with this name. + if (m_npObject->_class->hasProperty && m_npObject->_class->hasProperty(m_npObject, npIdentifier)) { + PropertySlot slot; + slot.setCustom(this, propertyGetter); + descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete); + return true; + } + + // Second, check if the NPObject has a method with this name. + if (m_npObject->_class->hasMethod && m_npObject->_class->hasMethod(m_npObject, npIdentifier)) { + PropertySlot slot; + slot.setCustom(this, methodGetter); + descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly); + return true; + } + + return false; +} + +void JSNPObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) +{ + if (!m_npObject) { + throwInvalidAccessError(exec); + return; + } + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + + if (!m_npObject->_class->hasProperty || !m_npObject->_class->hasProperty(m_npObject, npIdentifier)) { + // FIXME: Should we throw an exception here? + return; + } + + if (!m_npObject->_class->setProperty) + return; + + NPVariant variant; + m_objectMap->convertJSValueToNPVariant(exec, value, variant); + + // Calling NPClass::setProperty will call into plug-in code, and there's no telling what the plug-in can do. + // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until + // the call has finished. + NPRuntimeObjectMap::PluginProtector protector(m_objectMap); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + m_npObject->_class->setProperty(m_npObject, npIdentifier, &variant); + + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + + // FIXME: Should we throw an exception if setProperty returns false? + } + + releaseNPVariantValue(&variant); +} + +void JSNPObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNameArray, EnumerationMode mode) +{ + if (!m_npObject) { + throwInvalidAccessError(exec); + return; + } + + if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(m_npObject->_class) || !m_npObject->_class->enumerate) + return; + + NPIdentifier* identifiers = 0; + uint32_t identifierCount = 0; + + // Calling NPClass::enumerate will call into plug-in code, and there's no telling what the plug-in can do. + // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until + // the call has finished. + NPRuntimeObjectMap::PluginProtector protector(m_objectMap); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + + // FIXME: Should we throw an exception if enumerate returns false? + if (!m_npObject->_class->enumerate(m_npObject, &identifiers, &identifierCount)) + return; + + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + } + + for (uint32_t i = 0; i < identifierCount; ++i) { + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(identifiers[i]); + + Identifier identifier; + if (identifierRep->isString()) { + const char* string = identifierRep->string(); + int length = strlen(string); + + identifier = Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl()); + } else + identifier = Identifier::from(exec, identifierRep->number()); + + propertyNameArray.add(identifier); + } + + npnMemFree(identifiers); +} + +JSValue JSNPObject::propertyGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) +{ + JSNPObject* thisObj = static_cast<JSNPObject*>(asObject(slotBase)); + + if (!thisObj->m_npObject) + return throwInvalidAccessError(exec); + + if (!thisObj->m_npObject->_class->getProperty) + return jsUndefined(); + + NPVariant result; + VOID_TO_NPVARIANT(result); + + // Calling NPClass::getProperty will call into plug-in code, and there's no telling what the plug-in can do. + // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until + // the call has finished. + NPRuntimeObjectMap::PluginProtector protector(thisObj->m_objectMap); + + bool returnValue; + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + returnValue = thisObj->m_npObject->_class->getProperty(thisObj->m_npObject, npIdentifier, &result); + + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + } + + if (!returnValue) + return jsUndefined(); + + JSValue propertyValue = thisObj->m_objectMap->convertNPVariantToJSValue(exec, thisObj->globalObject(), result); + releaseNPVariantValue(&result); + return propertyValue; +} + +JSValue JSNPObject::methodGetter(ExecState* exec, JSValue slotBase, const Identifier& methodName) +{ + JSNPObject* thisObj = static_cast<JSNPObject*>(asObject(slotBase)); + + if (!thisObj->m_npObject) + return throwInvalidAccessError(exec); + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(methodName); + return new (exec) JSNPMethod(exec, thisObj->globalObject(), methodName, npIdentifier); +} + +JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec) +{ + return throwError(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h new file mode 100644 index 0000000..af1369a --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h @@ -0,0 +1,84 @@ +/* + * 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. + */ + +#ifndef JSNPObject_h +#define JSNPObject_h + +#include <JavaScriptCore/JSObjectWithGlobalObject.h> + +typedef void* NPIdentifier; +struct NPObject; + +namespace WebKit { + +class NPRuntimeObjectMap; + +// JSNPObject is a JSObject that wraps an NPObject. + +class JSNPObject : public JSC::JSObjectWithGlobalObject { +public: + JSNPObject(JSC::JSGlobalObject*, NPRuntimeObjectMap* objectMap, NPObject* npObject); + ~JSNPObject(); + + void invalidate(); + + JSC::JSValue callMethod(JSC::ExecState*, NPIdentifier methodName); + JSC::JSValue callObject(JSC::ExecState*); + JSC::JSValue callConstructor(JSC::ExecState*); + + static const JSC::ClassInfo s_info; + + NPObject* npObject() const { return m_npObject; } + +private: + static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSObject::StructureFlags; + + static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) + { + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); + } + + virtual JSC::CallType getCallData(JSC::CallData&); + virtual JSC::ConstructType getConstructData(JSC::ConstructData&); + + virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&); + virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); + + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); + + static JSC::JSValue propertyGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&); + static JSC::JSValue methodGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&); + static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*); + + virtual const JSC::ClassInfo* classInfo() const { return &s_info; } + + NPRuntimeObjectMap* m_objectMap; + NPObject* m_npObject; +}; + +} // namespace WebKit + +#endif // JSNPObject_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp new file mode 100644 index 0000000..45c1e6e --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp @@ -0,0 +1,383 @@ +/* + * 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 "NPJSObject.h" + +#include "JSNPObject.h" +#include "NPRuntimeObjectMap.h" +#include "NPRuntimeUtilities.h" +#include "NotImplemented.h" +#include "PluginView.h" +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/JSObject.h> +#include <WebCore/Frame.h> +#include <WebCore/IdentifierRep.h> +#include <wtf/text/WTFString.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +NPJSObject* NPJSObject::create(NPRuntimeObjectMap* objectMap, JSObject* jsObject) +{ + // We should never have a JSNPObject inside an NPJSObject. + ASSERT(!jsObject->inherits(&JSNPObject::s_info)); + + NPJSObject* npJSObject = toNPJSObject(createNPObject(0, npClass())); + npJSObject->initialize(objectMap, jsObject); + + return npJSObject; +} + +NPJSObject::NPJSObject() + : m_objectMap(0) +{ +} + +NPJSObject::~NPJSObject() +{ + m_objectMap->npJSObjectDestroyed(this); +} + +bool NPJSObject::isNPJSObject(NPObject* npObject) +{ + return npObject->_class == npClass(); +} + +void NPJSObject::initialize(NPRuntimeObjectMap* objectMap, JSObject* jsObject) +{ + ASSERT(!m_objectMap); + ASSERT(!m_jsObject); + + m_objectMap = objectMap; + m_jsObject = jsObject; +} + +static Identifier identifierFromIdentifierRep(ExecState* exec, IdentifierRep* identifierRep) +{ + ASSERT(identifierRep->isString()); + + const char* string = identifierRep->string(); + int length = strlen(string); + + return Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl()); +} + +bool NPJSObject::hasMethod(NPIdentifier methodName) +{ + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName); + + if (!identifierRep->isString()) + return false; + + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + JSValue value = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); + exec->clearException(); + + CallData callData; + return getCallData(value, callData) != CallTypeNone; +} + +bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(methodName); + + if (!identifierRep->isString()) + return false; + + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + JSValue function = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); + return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result); +} + +bool NPJSObject::invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + JSValue function = m_jsObject; + return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result); +} + +bool NPJSObject::hasProperty(NPIdentifier identifier) +{ + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(identifier); + + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + bool result; + if (identifierRep->isString()) + result = m_jsObject->hasProperty(exec, identifierFromIdentifierRep(exec, identifierRep)); + else + result = m_jsObject->hasProperty(exec, identifierRep->number()); + + exec->clearException(); + return result; +} + +bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result) +{ + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName); + + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + JSValue jsResult; + if (identifierRep->isString()) + jsResult = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); + else + jsResult = m_jsObject->get(exec, identifierRep->number()); + + m_objectMap->convertJSValueToNPVariant(exec, jsResult, *result); + exec->clearException(); + return true; +} + +bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value) +{ + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName); + + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + JSValue jsValue = m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), *value); + if (identifierRep->isString()) { + PutPropertySlot slot; + m_jsObject->put(exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot); + } else + m_jsObject->put(exec, identifierRep->number(), jsValue); + exec->clearException(); + + return true; +} + +bool NPJSObject::removeProperty(NPIdentifier propertyName) +{ + IdentifierRep* identifierRep = static_cast<IdentifierRep*>(propertyName); + + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + if (identifierRep->isString()) { + Identifier identifier = identifierFromIdentifierRep(exec, identifierRep); + + if (!m_jsObject->hasProperty(exec, identifier)) { + exec->clearException(); + return false; + } + + m_jsObject->deleteProperty(exec, identifier); + } else { + if (!m_jsObject->hasProperty(exec, identifierRep->number())) { + exec->clearException(); + return false; + } + + m_jsObject->deleteProperty(exec, identifierRep->number()); + } + + exec->clearException(); + return true; +} + +bool NPJSObject::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount) +{ + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + PropertyNameArray propertyNames(exec); + m_jsObject->getPropertyNames(exec, propertyNames); + + NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(propertyNames.size()); + + for (size_t i = 0; i < propertyNames.size(); ++i) + nameIdentifiers[i] = static_cast<NPIdentifier>(IdentifierRep::get(propertyNames[i].ustring().utf8().data())); + + *identifiers = nameIdentifiers; + *identifierCount = propertyNames.size(); + + return true; +} + +bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + ExecState* exec = m_objectMap->globalExec(); + if (!exec) + return false; + + JSLock lock(SilenceAssertionsOnly); + + ConstructData constructData; + ConstructType constructType = getConstructData(m_jsObject, constructData); + if (constructType == ConstructTypeNone) + return false; + + // Convert the passed in arguments. + MarkedArgumentBuffer argumentList; + for (uint32_t i = 0; i < argumentCount; ++i) + argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), arguments[i])); + + exec->globalData().timeoutChecker.start(); + JSValue value = JSC::construct(exec, m_jsObject, constructType, constructData, argumentList); + exec->globalData().timeoutChecker.stop(); + + // Convert and return the new object. + m_objectMap->convertJSValueToNPVariant(exec, value, *result); + exec->clearException(); + + return true; +} + +bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + CallData callData; + CallType callType = getCallData(function, callData); + if (callType == CallTypeNone) + return false; + + // Convert the passed in arguments. + MarkedArgumentBuffer argumentList; + for (uint32_t i = 0; i < argumentCount; ++i) + argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, globalObject, arguments[i])); + + exec->globalData().timeoutChecker.start(); + JSValue value = JSC::call(exec, function, callType, callData, m_jsObject, argumentList); + exec->globalData().timeoutChecker.stop(); + + // Convert and return the result of the function call. + m_objectMap->convertJSValueToNPVariant(exec, value, *result); + exec->clearException(); + + return true; +} + +NPClass* NPJSObject::npClass() +{ + static NPClass npClass = { + NP_CLASS_STRUCT_VERSION, + NP_Allocate, + NP_Deallocate, + 0, + NP_HasMethod, + NP_Invoke, + NP_InvokeDefault, + NP_HasProperty, + NP_GetProperty, + NP_SetProperty, + NP_RemoveProperty, + NP_Enumerate, + NP_Construct + }; + + return &npClass; +} + +NPObject* NPJSObject::NP_Allocate(NPP npp, NPClass*) +{ + ASSERT_UNUSED(npp, !npp); + + return new NPJSObject; +} + +void NPJSObject::NP_Deallocate(NPObject* npObject) +{ + NPJSObject* npJSObject = toNPJSObject(npObject); + delete npJSObject; +} + +bool NPJSObject::NP_HasMethod(NPObject* npObject, NPIdentifier methodName) +{ + return toNPJSObject(npObject)->hasMethod(methodName); +} + +bool NPJSObject::NP_Invoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + return toNPJSObject(npObject)->invoke(methodName, arguments, argumentCount, result); +} + +bool NPJSObject::NP_InvokeDefault(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + return toNPJSObject(npObject)->invokeDefault(arguments, argumentCount, result); +} + +bool NPJSObject::NP_HasProperty(NPObject* npObject, NPIdentifier propertyName) +{ + return toNPJSObject(npObject)->hasProperty(propertyName); +} + +bool NPJSObject::NP_GetProperty(NPObject* npObject, NPIdentifier propertyName, NPVariant* result) +{ + return toNPJSObject(npObject)->getProperty(propertyName, result); +} + +bool NPJSObject::NP_SetProperty(NPObject* npObject, NPIdentifier propertyName, const NPVariant* value) +{ + return toNPJSObject(npObject)->setProperty(propertyName, value); +} + +bool NPJSObject::NP_RemoveProperty(NPObject* npObject, NPIdentifier propertyName) +{ + return toNPJSObject(npObject)->removeProperty(propertyName); +} + +bool NPJSObject::NP_Enumerate(NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount) +{ + return toNPJSObject(npObject)->enumerate(identifiers, identifierCount); +} + +bool NPJSObject::NP_Construct(NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + return toNPJSObject(npObject)->construct(arguments, argumentCount, result); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h new file mode 100644 index 0000000..6737bd4 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h @@ -0,0 +1,94 @@ +/* + * 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. + */ + +#ifndef NPJSObject_h +#define NPJSObject_h + +#include <JavaScriptCore/Protect.h> +#include <WebCore/npruntime_internal.h> +#include <wtf/Noncopyable.h> + +namespace JSC { + class JSGlobalObject; + class JSObject; +} + +namespace WebKit { + +class NPRuntimeObjectMap; + +// NPJSObject is an NPObject that wraps a JSObject. +class NPJSObject : public NPObject, Noncopyable { +public: + static NPJSObject* create(NPRuntimeObjectMap* objectMap, JSC::JSObject* jsObject); + + JSC::JSObject* jsObject() const { return m_jsObject.get(); } + + static bool isNPJSObject(NPObject*); + + static NPJSObject* toNPJSObject(NPObject* npObject) + { + ASSERT(isNPJSObject(npObject)); + return static_cast<NPJSObject*>(npObject); + } + +private: + NPJSObject(); + ~NPJSObject(); + + void initialize(NPRuntimeObjectMap*, JSC::JSObject* jsObject); + + bool hasMethod(NPIdentifier methodName); + bool invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + bool invokeDefault(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + bool hasProperty(NPIdentifier propertyName); + bool getProperty(NPIdentifier propertyName, NPVariant* result); + bool setProperty(NPIdentifier propertyName, const NPVariant* value); + bool removeProperty(NPIdentifier propertyName); + bool enumerate(NPIdentifier** identifiers, uint32_t* identifierCount); + bool construct(const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + + bool invoke(JSC::ExecState*, JSC::JSGlobalObject*, JSC::JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + + static NPClass* npClass(); + static NPObject* NP_Allocate(NPP, NPClass*); + static void NP_Deallocate(NPObject*); + static bool NP_HasMethod(NPObject*, NPIdentifier methodName); + static bool NP_Invoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + static bool NP_InvokeDefault(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + static bool NP_HasProperty(NPObject*, NPIdentifier propertyName); + static bool NP_GetProperty(NPObject*, NPIdentifier propertyName, NPVariant* result); + static bool NP_SetProperty(NPObject*, NPIdentifier propertyName, const NPVariant* value); + static bool NP_RemoveProperty(NPObject*, NPIdentifier propertyName); + static bool NP_Enumerate(NPObject*, NPIdentifier** identifiers, uint32_t* identifierCount); + static bool NP_Construct(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); + + NPRuntimeObjectMap* m_objectMap; + JSC::ProtectedPtr<JSC::JSObject> m_jsObject; +}; + +} // namespace WebKit + +#endif // NPJSObject_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp new file mode 100644 index 0000000..4fa37c1 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @@ -0,0 +1,277 @@ +/* + * 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 "NPRuntimeObjectMap.h" + +#include "JSNPObject.h" +#include "NPJSObject.h" +#include "NPRuntimeUtilities.h" +#include "NotImplemented.h" +#include "PluginView.h" +#include <JavaScriptCore/Error.h> +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/SourceCode.h> +#include <WebCore/Frame.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + + +NPRuntimeObjectMap::NPRuntimeObjectMap(PluginView* pluginView) + : m_pluginView(pluginView) +{ +} + +NPRuntimeObjectMap::PluginProtector::PluginProtector(NPRuntimeObjectMap* npRuntimeObjectMap) +{ + // If we're already in the plug-in view destructor, we shouldn't try to keep it alive. + if (!npRuntimeObjectMap->m_pluginView->isBeingDestroyed()) + m_pluginView = npRuntimeObjectMap->m_pluginView; +} + +NPRuntimeObjectMap::PluginProtector::~PluginProtector() +{ +} + +NPObject* NPRuntimeObjectMap::getOrCreateNPObject(JSObject* jsObject) +{ + // If this is a JSNPObject, we can just get its underlying NPObject. + if (jsObject->classInfo() == &JSNPObject::s_info) { + JSNPObject* jsNPObject = static_cast<JSNPObject*>(jsObject); + NPObject* npObject = jsNPObject->npObject(); + + retainNPObject(npObject); + return npObject; + } + + // First, check if we already know about this object. + if (NPJSObject* npJSObject = m_npJSObjects.get(jsObject)) { + retainNPObject(npJSObject); + return npJSObject; + } + + NPJSObject* npJSObject = NPJSObject::create(this, jsObject); + m_npJSObjects.set(jsObject, npJSObject); + + return npJSObject; +} + +void NPRuntimeObjectMap::npJSObjectDestroyed(NPJSObject* npJSObject) +{ + // Remove the object from the map. + ASSERT(m_npJSObjects.contains(npJSObject->jsObject())); + m_npJSObjects.remove(npJSObject->jsObject()); +} + +JSObject* NPRuntimeObjectMap::getOrCreateJSObject(JSGlobalObject* globalObject, NPObject* npObject) +{ + // If this is an NPJSObject, we can just get the JSObject that it's wrapping. + if (NPJSObject::isNPJSObject(npObject)) + return NPJSObject::toNPJSObject(npObject)->jsObject(); + + if (JSNPObject* jsNPObject = m_jsNPObjects.get(npObject)) + return jsNPObject; + + JSNPObject* jsNPObject = new (&globalObject->globalData()) JSNPObject(globalObject, this, npObject); + m_jsNPObjects.set(npObject, jsNPObject); + + return jsNPObject; +} + +void NPRuntimeObjectMap::jsNPObjectDestroyed(JSNPObject* jsNPObject) +{ + // Remove the object from the map. + ASSERT(m_jsNPObjects.contains(jsNPObject->npObject())); + m_jsNPObjects.remove(jsNPObject->npObject()); +} + +JSValue NPRuntimeObjectMap::convertNPVariantToJSValue(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject, const NPVariant& variant) +{ + switch (variant.type) { + case NPVariantType_Void: + return jsUndefined(); + + case NPVariantType_Null: + return jsNull(); + + case NPVariantType_Bool: + return jsBoolean(variant.value.boolValue); + + case NPVariantType_Int32: + return jsNumber(variant.value.intValue); + + case NPVariantType_Double: + return jsNumber(variant.value.doubleValue); + + case NPVariantType_String: + return jsString(exec, String::fromUTF8WithLatin1Fallback(variant.value.stringValue.UTF8Characters, + variant.value.stringValue.UTF8Length)); + case NPVariantType_Object: + return getOrCreateJSObject(globalObject, variant.value.objectValue); + } + + ASSERT_NOT_REACHED(); + return jsUndefined(); +} + +void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue value, NPVariant& variant) +{ + JSLock lock(SilenceAssertionsOnly); + + VOID_TO_NPVARIANT(variant); + + if (value.isNull()) { + NULL_TO_NPVARIANT(variant); + return; + } + + if (value.isUndefined()) { + VOID_TO_NPVARIANT(variant); + return; + } + + if (value.isBoolean()) { + BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), variant); + return; + } + + if (value.isNumber()) { + DOUBLE_TO_NPVARIANT(value.toNumber(exec), variant); + return; + } + + if (value.isString()) { + NPString npString = createNPString(value.toString(exec).utf8()); + STRINGN_TO_NPVARIANT(npString.UTF8Characters, npString.UTF8Length, variant); + return; + } + + if (value.isObject()) { + NPObject* npObject = getOrCreateNPObject(asObject(value)); + OBJECT_TO_NPVARIANT(npObject, variant); + return; + } + + ASSERT_NOT_REACHED(); +} + +bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String&scriptString, NPVariant* result) +{ + ProtectedPtr<JSGlobalObject> globalObject = this->globalObject(); + if (!globalObject) + return false; + + ExecState* exec = globalObject->globalExec(); + + JSLock lock(SilenceAssertionsOnly); + JSValue thisValue = getOrCreateJSObject(globalObject, npObject); + + globalObject->globalData().timeoutChecker.start(); + Completion completion = JSC::evaluate(exec, globalObject->globalScopeChain(), makeSource(UString(scriptString.impl())), thisValue); + globalObject->globalData().timeoutChecker.stop(); + + ComplType completionType = completion.complType(); + + JSValue resultValue; + if (completionType == Normal) { + resultValue = completion.value(); + if (!resultValue) + resultValue = jsUndefined(); + } else + resultValue = jsUndefined(); + + exec->clearException(); + + convertJSValueToNPVariant(exec, resultValue, *result); + return true; +} + +void NPRuntimeObjectMap::invalidate() +{ + Vector<NPJSObject*> npJSObjects; + copyValuesToVector(m_npJSObjects, npJSObjects); + + // Deallocate all the object wrappers so we won't leak any JavaScript objects. + for (size_t i = 0; i < npJSObjects.size(); ++i) + deallocateNPObject(npJSObjects[i]); + + // We shouldn't have any NPJSObjects left now. + ASSERT(m_npJSObjects.isEmpty()); + + Vector<JSNPObject*> jsNPObjects; + copyValuesToVector(m_jsNPObjects, jsNPObjects); + + // Invalidate all the JSObjects that wrap NPObjects. + for (size_t i = 0; i < jsNPObjects.size(); ++i) + jsNPObjects[i]->invalidate(); + + m_jsNPObjects.clear(); +} + +JSGlobalObject* NPRuntimeObjectMap::globalObject() const +{ + Frame* frame = m_pluginView->frame(); + if (!frame) + return 0; + + return frame->script()->globalObject(pluginWorld()); +} + +ExecState* NPRuntimeObjectMap::globalExec() const +{ + JSGlobalObject* globalObject = this->globalObject(); + if (!globalObject) + return 0; + + return globalObject->globalExec(); +} + +static String& globalExceptionString() +{ + DEFINE_STATIC_LOCAL(String, exceptionString, ()); + return exceptionString; +} + +void NPRuntimeObjectMap::setGlobalException(const String& exceptionString) +{ + globalExceptionString() = exceptionString; +} + +void NPRuntimeObjectMap::moveGlobalExceptionToExecState(ExecState* exec) +{ + if (globalExceptionString().isNull()) + return; + + { + JSLock lock(SilenceAssertionsOnly); + throwError(exec, createError(exec, stringToUString(globalExceptionString()))); + } + + globalExceptionString() = String(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h new file mode 100644 index 0000000..a11c354 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h @@ -0,0 +1,94 @@ +/* + * 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. + */ + +#ifndef NPJSObjectWrapperMap_h +#define NPJSObjectWrapperMap_h + +#include <wtf/Forward.h> +#include <wtf/HashMap.h> + +struct NPObject; +typedef struct _NPVariant NPVariant; + +namespace JSC { + class ExecState; + class JSGlobalObject; + class JSObject; + class JSValue; +} + +namespace WebKit { + +class JSNPObject; +class NPJSObject; +class PluginView; + +// A per plug-in map of NPObjects that wrap JavaScript objects. +class NPRuntimeObjectMap { +public: + explicit NPRuntimeObjectMap(PluginView*); + + class PluginProtector { + public: + explicit PluginProtector(NPRuntimeObjectMap* npRuntimeObjectMap); + ~PluginProtector(); + + private: + RefPtr<PluginView> m_pluginView; + }; + + // Returns an NPObject that wraps the given JSObject object. If there is already an NPObject that wraps this JSObject, it will + // retain it and return it. + NPObject* getOrCreateNPObject(JSC::JSObject*); + void npJSObjectDestroyed(NPJSObject*); + + // Returns a JSObject object that wraps the given NPObject. + JSC::JSObject* getOrCreateJSObject(JSC::JSGlobalObject*, NPObject*); + void jsNPObjectDestroyed(JSNPObject*); + + void convertJSValueToNPVariant(JSC::ExecState*, JSC::JSValue, NPVariant&); + JSC::JSValue convertNPVariantToJSValue(JSC::ExecState*, JSC::JSGlobalObject*, const NPVariant&); + + bool evaluate(NPObject*, const String& scriptString, NPVariant* result); + + // Called when the plug-in is destroyed. Will invalidate all the NPObjects. + void invalidate(); + + JSC::JSGlobalObject* globalObject() const; + JSC::ExecState* globalExec() const; + + static void setGlobalException(const String& exceptionString); + static void moveGlobalExceptionToExecState(JSC::ExecState*); + +private: + PluginView* m_pluginView; + + HashMap<JSC::JSObject*, NPJSObject*> m_npJSObjects; + HashMap<NPObject*, JSNPObject*> m_jsNPObjects; +}; + +} // namespace WebKit + +#endif // NPJSObjectWrapperMap_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp new file mode 100644 index 0000000..20ff478 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp @@ -0,0 +1,134 @@ +/* + * 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 "NPRuntimeUtilities.h" + +#include <wtf/text/CString.h> + +namespace WebKit { + +void* npnMemAlloc(uint32_t size) +{ + // We could use fastMalloc here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free, + // so having them be equivalent seems like a good idea. + return malloc(size); +} + +void npnMemFree(void* ptr) +{ + // We could use fastFree here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free, + // so having them be equivalent seems like a good idea. + free(ptr); +} + +NPString createNPString(const CString& string) +{ + char* utf8Characters = npnMemNewArray<char>(string.length()); + memcpy(utf8Characters, string.data(), string.length()); + + NPString npString; + npString.UTF8Characters = utf8Characters; + npString.UTF8Length = string.length(); + + return npString; +} + +NPObject* createNPObject(NPP npp, NPClass* npClass) +{ + ASSERT(npClass); + + NPObject* npObject; + if (npClass->allocate) + npObject = npClass->allocate(npp, npClass); + else + npObject = npnMemNew<NPObject>(); + + npObject->_class = npClass; + npObject->referenceCount = 1; + + return npObject; +} + +void deallocateNPObject(NPObject* npObject) +{ + ASSERT(npObject); + if (!npObject) + return; + + if (npObject->_class->deallocate) + npObject->_class->deallocate(npObject); + else + npnMemFree(npObject); +} + +void retainNPObject(NPObject* npObject) +{ + ASSERT(npObject); + if (!npObject) + return; + + npObject->referenceCount++; +} + +void releaseNPObject(NPObject* npObject) +{ + ASSERT(npObject); + if (!npObject) + return; + + ASSERT(npObject->referenceCount >= 1); + npObject->referenceCount--; + if (!npObject->referenceCount) + deallocateNPObject(npObject); +} + +void releaseNPVariantValue(NPVariant* variant) +{ + ASSERT(variant); + + switch (variant->type) { + case NPVariantType_Void: + case NPVariantType_Null: + case NPVariantType_Bool: + case NPVariantType_Int32: + case NPVariantType_Double: + // Nothing to do. + break; + + case NPVariantType_String: + npnMemFree(const_cast<NPUTF8*>(variant->value.stringValue.UTF8Characters)); + variant->value.stringValue.UTF8Characters = 0; + variant->value.stringValue.UTF8Length = 0; + break; + case NPVariantType_Object: + releaseNPObject(variant->value.objectValue); + variant->value.objectValue = 0; + break; + } + + variant->type = NPVariantType_Void; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h new file mode 100644 index 0000000..7309fd4 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#ifndef NPRuntimeUtilities_h +#define NPRuntimeUtilities_h + +#include <WebCore/npruntime_internal.h> +#include <wtf/Forward.h> + +struct NPClass; +struct NPObject; + +namespace WebKit { + +void* npnMemAlloc(uint32_t); +void npnMemFree(void*); + +template<typename T> T* npnMemNew() +{ + return static_cast<T*>(npnMemAlloc(sizeof(T))); +} + +template<typename T> T* npnMemNewArray(size_t count) +{ + return static_cast<T*>(npnMemAlloc(sizeof(T) * count)); +} + +NPString createNPString(const CString&); + +NPObject* createNPObject(NPP, NPClass*); +void deallocateNPObject(NPObject*); + +void retainNPObject(NPObject*); +void releaseNPObject(NPObject*); + +void releaseNPVariantValue(NPVariant*); + +} + +#endif // NPRuntimeUtilities_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp new file mode 100644 index 0000000..566d48d --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp @@ -0,0 +1,871 @@ +/* + * 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 "NetscapeBrowserFuncs.h" + +#include "NPRuntimeUtilities.h" +#include "NetscapePlugin.h" +#include "NotImplemented.h" +#include <WebCore/HTTPHeaderMap.h> +#include <WebCore/IdentifierRep.h> +#include <WebCore/SharedBuffer.h> +#include <utility> + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +static bool startsWithBlankLine(const char* bytes, unsigned length) +{ + return length > 0 && bytes[0] == '\n'; +} + +static int locationAfterFirstBlankLine(const char* bytes, unsigned length) +{ + for (unsigned i = 0; i < length - 4; i++) { + // Support for Acrobat. It sends "\n\n". + if (bytes[i] == '\n' && bytes[i + 1] == '\n') + return i + 2; + + // Returns the position after 2 CRLF's or 1 CRLF if it is the first line. + if (bytes[i] == '\r' && bytes[i + 1] == '\n') { + i += 2; + if (i == 2) + return i; + + if (bytes[i] == '\n') { + // Support for Director. It sends "\r\n\n" (3880387). + return i + 1; + } + + if (bytes[i] == '\r' && bytes[i + 1] == '\n') { + // Support for Flash. It sends "\r\n\r\n" (3758113). + return i + 2; + } + } + } + + return -1; +} + +static const char* findEndOfLine(const char* bytes, unsigned length) +{ + // According to the HTTP specification EOL is defined as + // a CRLF pair. Unfortunately, some servers will use LF + // instead. Worse yet, some servers will use a combination + // of both (e.g. <header>CRLFLF<body>), so findEOL needs + // to be more forgiving. It will now accept CRLF, LF or + // CR. + // + // It returns 0 if EOLF is not found or it will return + // a pointer to the first terminating character. + for (unsigned i = 0; i < length; i++) { + if (bytes[i] == '\n') + return bytes + i; + if (bytes[i] == '\r') { + // Check to see if spanning buffer bounds + // (CRLF is across reads). If so, wait for + // next read. + if (i + 1 == length) + break; + + return bytes + i; + } + } + + return 0; +} + +static String capitalizeRFC822HeaderFieldName(const String& name) +{ + bool capitalizeCharacter = true; + String result; + + for (unsigned i = 0; i < name.length(); i++) { + UChar c; + + if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z') + c = toASCIIUpper(name[i]); + else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z') + c = toASCIILower(name[i]); + else + c = name[i]; + + if (name[i] == '-') + capitalizeCharacter = true; + else + capitalizeCharacter = false; + + result.append(c); + } + + return result; +} + +static HTTPHeaderMap parseRFC822HeaderFields(const char* bytes, unsigned length) +{ + String lastHeaderKey; + HTTPHeaderMap headerFields; + + // Loop over lines until we're past the header, or we can't find any more end-of-lines + while (const char* endOfLine = findEndOfLine(bytes, length)) { + const char* line = bytes; + int lineLength = endOfLine - bytes; + + // Move bytes to the character after the terminator as returned by findEndOfLine. + bytes = endOfLine + 1; + if ((*endOfLine == '\r') && (*bytes == '\n')) + bytes++; // Safe since findEndOfLine won't return a spanning CRLF. + + length -= (bytes - line); + if (!lineLength) { + // Blank line; we're at the end of the header + break; + } + + if (*line == ' ' || *line == '\t') { + // Continuation of the previous header + if (lastHeaderKey.isNull()) { + // malformed header; ignore it and continue + continue; + } + + // Merge the continuation of the previous header + String currentValue = headerFields.get(lastHeaderKey); + String newValue(line, lineLength); + + headerFields.set(lastHeaderKey, currentValue + newValue); + } else { + // Brand new header + const char* colon = line; + while (*colon != ':' && colon != endOfLine) + colon++; + + if (colon == endOfLine) { + // malformed header; ignore it and continue + continue; + } + + lastHeaderKey = capitalizeRFC822HeaderFieldName(String(line, colon - line)); + String value; + + for (colon++; colon != endOfLine; colon++) { + if (*colon != ' ' && *colon != '\t') + break; + } + if (colon == endOfLine) + value = ""; + else + value = String(colon, endOfLine - colon); + + String oldValue = headerFields.get(lastHeaderKey); + if (!oldValue.isNull()) { + String tmp = oldValue; + tmp += ", "; + tmp += value; + value = tmp; + } + + headerFields.set(lastHeaderKey, value); + } + } + + return headerFields; +} + +static NPError parsePostBuffer(bool isFile, const char *buffer, uint32_t length, bool parseHeaders, HTTPHeaderMap& headerFields, Vector<uint8_t>& bodyData) +{ + RefPtr<SharedBuffer> fileContents; + const char* postBuffer = 0; + uint32_t postBufferSize = 0; + + if (isFile) { + fileContents = SharedBuffer::createWithContentsOfFile(String::fromUTF8(buffer)); + if (!fileContents) + return NPERR_FILE_NOT_FOUND; + + postBuffer = fileContents->data(); + postBufferSize = fileContents->size(); + + // FIXME: The NPAPI spec states that the file should be deleted here. + } else { + postBuffer = buffer; + postBufferSize = length; + } + + if (parseHeaders) { + if (startsWithBlankLine(postBuffer, postBufferSize)) { + postBuffer++; + postBufferSize--; + } else { + int location = locationAfterFirstBlankLine(postBuffer, postBufferSize); + if (location != -1) { + // If the blank line is somewhere in the middle of the buffer, everything before is the header + headerFields = parseRFC822HeaderFields(postBuffer, location); + unsigned dataLength = postBufferSize - location; + + // Sometimes plugins like to set Content-Length themselves when they post, + // but WebFoundation does not like that. So we will remove the header + // and instead truncate the data to the requested length. + String contentLength = headerFields.get("Content-Length"); + + if (!contentLength.isNull()) + dataLength = min(contentLength.toInt(), (int)dataLength); + headerFields.remove("Content-Length"); + + postBuffer += location; + postBufferSize = dataLength; + + } + } + } + + ASSERT(bodyData.isEmpty()); + bodyData.append(postBuffer, postBufferSize); + + return NPERR_NO_ERROR; +} + +static String makeURLString(const char* url) +{ + String urlString(url); + + // Strip return characters. + urlString.replace('\r', ""); + urlString.replace('\n', ""); + + return urlString; +} + +static NPError NPN_GetURL(NPP npp, const char* url, const char* target) +{ + if (!url) + return NPERR_GENERIC_ERROR; + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<uint8_t>(), false, 0); + + return NPERR_GENERIC_ERROR; +} + +static NPError NPN_PostURL(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file) +{ + HTTPHeaderMap headerFields; + Vector<uint8_t> postData; + + // NPN_PostURL only allows headers if the post buffer points to a file. + bool parseHeaders = file; + + NPError error = parsePostBuffer(file, buf, len, parseHeaders, headerFields, postData); + if (error != NPERR_NO_ERROR) + return error; + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, false, 0); + return NPERR_NO_ERROR; +} + +static NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) +{ + notImplemented(); + return NPERR_GENERIC_ERROR; +} + +static NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream) +{ + notImplemented(); + return NPERR_GENERIC_ERROR; +} + +static int32_t NPN_Write(NPP instance, NPStream* stream, int32_t len, void* buffer) +{ + notImplemented(); + return -1; +} + +static NPError NPN_DestroyStream(NPP npp, NPStream* stream, NPReason reason) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + return plugin->destroyStream(stream, reason); +} + +static void NPN_Status(NPP npp, const char* message) +{ + String statusbarText; + if (!message) + statusbarText = ""; + else + statusbarText = String::fromUTF8WithLatin1Fallback(message, strlen(message)); + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->setStatusbarText(statusbarText); +} + +static const char* NPN_UserAgent(NPP npp) +{ + return NetscapePlugin::userAgent(npp); +} + +static void* NPN_MemAlloc(uint32_t size) +{ + return npnMemAlloc(size); +} + +static void NPN_MemFree(void* ptr) +{ + npnMemFree(ptr); +} + +static uint32_t NPN_MemFlush(uint32_t size) +{ + return 0; +} + +static void NPN_ReloadPlugins(NPBool reloadPages) +{ + notImplemented(); +} + +static JRIEnv* NPN_GetJavaEnv(void) +{ + notImplemented(); + return 0; +} + +static jref NPN_GetJavaPeer(NPP instance) +{ + notImplemented(); + return 0; +} + +static NPError NPN_GetURLNotify(NPP npp, const char* url, const char* target, void* notifyData) +{ + if (!url) + return NPERR_GENERIC_ERROR; + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<uint8_t>(), true, notifyData); + + return NPERR_NO_ERROR; +} + +static NPError NPN_PostURLNotify(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData) +{ + HTTPHeaderMap headerFields; + Vector<uint8_t> postData; + NPError error = parsePostBuffer(file, buf, len, true, headerFields, postData); + if (error != NPERR_NO_ERROR) + return error; + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, true, notifyData); + return NPERR_NO_ERROR; +} + +#if PLATFORM(MAC) +/* TRUE if the browser supports hardware compositing of Core Animation plug-ins */ +static const unsigned WKNVSupportsCompositingCoreAnimationPluginsBool = 74656; +#endif + +static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) +{ + switch (variable) { + case NPNVWindowNPObject: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + NPObject* windowNPObject = plugin->windowScriptNPObject(); + *(NPObject**)value = windowNPObject; + break; + } + case NPNVPluginElementNPObject: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + NPObject* pluginElementNPObject = plugin->pluginElementNPObject(); + *(NPObject**)value = pluginElementNPObject; + break; + } + case NPNVprivateModeBool: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + *(NPBool*)value = plugin->isPrivateBrowsingEnabled(); + break; + } +#if PLATFORM(MAC) + case NPNVsupportsCoreGraphicsBool: + // Always claim to support the Core Graphics drawing model. + *(NPBool*)value = true; + break; + + case WKNVSupportsCompositingCoreAnimationPluginsBool: + case NPNVsupportsCoreAnimationBool: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + *(NPBool*)value = plugin->isAcceleratedCompositingEnabled(); + break; + } + case NPNVsupportsCocoaBool: + // Always claim to support the Cocoa event model. + *(NPBool*)value = true; + break; + +#ifndef NP_NO_QUICKDRAW + case NPNVsupportsQuickDrawBool: + // We don't support the QuickDraw drawing model. + *(NPBool*)value = false; + break; +#endif +#ifndef NP_NO_CARBON + case NPNVsupportsCarbonBool: + // FIXME: We should support the Carbon event model. + *(NPBool*)value = false; + break; +#endif +#elif PLATFORM(WIN) + case NPNVnetscapeWindow: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + *reinterpret_cast<HWND*>(value) = plugin->containingWindow(); + break; + } + case NPNVSupportsWindowless: + *(NPBool*)value = true; + break; +#endif + default: + notImplemented(); + return NPERR_GENERIC_ERROR; + } + + return NPERR_NO_ERROR; +} + +static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value) +{ + switch (variable) { +#if PLATFORM(MAC) + case NPPVpluginDrawingModel: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + NPDrawingModel drawingModel = static_cast<NPDrawingModel>(reinterpret_cast<uintptr_t>(value)); + return plugin->setDrawingModel(drawingModel); + } + + case NPPVpluginEventModel: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + NPEventModel eventModel = static_cast<NPEventModel>(reinterpret_cast<uintptr_t>(value)); + return plugin->setEventModel(eventModel); + } +#endif + + case NPPVpluginWindowBool: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->setIsWindowed(value); + return NPERR_NO_ERROR; + } + + case NPPVpluginTransparentBool: + default: + notImplemented(); + return NPERR_GENERIC_ERROR; + } +} + +static void NPN_InvalidateRect(NPP npp, NPRect* invalidRect) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->invalidate(invalidRect); +} + +static void NPN_InvalidateRegion(NPP npp, NPRegion invalidRegion) +{ + // FIXME: We could at least figure out the bounding rectangle of the invalid region. + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->invalidate(0); +} + +static void NPN_ForceRedraw(NPP instance) +{ + notImplemented(); +} + +static NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) +{ + return static_cast<NPIdentifier>(IdentifierRep::get(name)); +} + +static void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers) +{ + ASSERT(names); + ASSERT(identifiers); + + if (!names || !identifiers) + return; + + for (int32_t i = 0; i < nameCount; ++i) + identifiers[i] = NPN_GetStringIdentifier(names[i]); +} + +static NPIdentifier NPN_GetIntIdentifier(int32_t intid) +{ + return static_cast<NPIdentifier>(IdentifierRep::get(intid)); +} + +static bool NPN_IdentifierIsString(NPIdentifier identifier) +{ + return static_cast<IdentifierRep*>(identifier)->isString(); +} + +static NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) +{ + const char* string = static_cast<IdentifierRep*>(identifier)->string(); + if (!string) + return 0; + + uint32_t stringLength = strlen(string); + char* utf8String = npnMemNewArray<char>(stringLength + 1); + memcpy(utf8String, string, stringLength); + utf8String[stringLength] = '\0'; + + return utf8String; +} + +static int32_t NPN_IntFromIdentifier(NPIdentifier identifier) +{ + return static_cast<IdentifierRep*>(identifier)->number(); +} + +static NPObject* NPN_CreateObject(NPP npp, NPClass *npClass) +{ + return createNPObject(npp, npClass); +} + +static NPObject *NPN_RetainObject(NPObject *npObject) +{ + retainNPObject(npObject); + return npObject; +} + +static void NPN_ReleaseObject(NPObject *npObject) +{ + releaseNPObject(npObject); +} + +static bool NPN_Invoke(NPP, NPObject *npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + if (npObject->_class->invoke) + return npObject->_class->invoke(npObject, methodName, arguments, argumentCount, result); + + return false; +} + +static bool NPN_InvokeDefault(NPP, NPObject *npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + if (npObject->_class->invokeDefault) + return npObject->_class->invokeDefault(npObject, arguments, argumentCount, result); + + return false; +} + +static bool NPN_Evaluate(NPP npp, NPObject *npObject, NPString *script, NPVariant* result) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + String scriptString = String::fromUTF8WithLatin1Fallback(script->UTF8Characters, script->UTF8Length); + + return plugin->evaluate(npObject, scriptString, result); +} + +static bool NPN_GetProperty(NPP, NPObject* npObject, NPIdentifier propertyName, NPVariant* result) +{ + if (npObject->_class->getProperty) + return npObject->_class->getProperty(npObject, propertyName, result); + + return false; +} + +static bool NPN_SetProperty(NPP, NPObject* npObject, NPIdentifier propertyName, const NPVariant* value) +{ + if (npObject->_class->setProperty) + return npObject->_class->setProperty(npObject, propertyName, value); + + return false; +} + +static bool NPN_RemoveProperty(NPP, NPObject* npObject, NPIdentifier propertyName) +{ + if (npObject->_class->removeProperty) + return npObject->_class->removeProperty(npObject, propertyName); + + return false; +} + +static bool NPN_HasProperty(NPP, NPObject* npObject, NPIdentifier propertyName) +{ + if (npObject->_class->hasProperty) + return npObject->_class->hasProperty(npObject, propertyName); + + return false; +} + +static bool NPN_HasMethod(NPP, NPObject* npObject, NPIdentifier methodName) +{ + if (npObject->_class->hasMethod) + return npObject->_class->hasMethod(npObject, methodName); + + return false; +} + +static void NPN_ReleaseVariantValue(NPVariant* variant) +{ + releaseNPVariantValue(variant); +} + +static void NPN_SetException(NPObject*, const NPUTF8* message) +{ + NetscapePlugin::setException(message); +} + +static void NPN_PushPopupsEnabledState(NPP npp, NPBool enabled) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->pushPopupsEnabledState(enabled); +} + +static void NPN_PopPopupsEnabledState(NPP npp) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->popPopupsEnabledState(); +} + +static bool NPN_Enumerate(NPP, NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount) +{ + if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) + return npObject->_class->enumerate(npObject, identifiers, identifierCount); + + return false; +} + +static void NPN_PluginThreadAsyncCall(NPP instance, void (*func) (void*), void* userData) +{ + notImplemented(); +} + +static bool NPN_Construct(NPP, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npObject->_class) && npObject->_class->construct) + return npObject->_class->construct(npObject, arguments, argumentCount, result); + + return false; +} + +static NPError copyCString(const CString& string, char** value, uint32_t* len) +{ + ASSERT(!string.isNull()); + ASSERT(value); + ASSERT(len); + + *value = npnMemNewArray<char>(string.length()); + if (!*value) + return NPERR_GENERIC_ERROR; + + memcpy(*value, string.data(), string.length()); + *len = string.length(); + return NPERR_NO_ERROR; +} + +static NPError NPN_GetValueForURL(NPP npp, NPNURLVariable variable, const char* url, char** value, uint32_t* len) +{ + if (!value || !len) + return NPERR_GENERIC_ERROR; + + switch (variable) { + case NPNURLVCookie: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + String cookies = plugin->cookiesForURL(makeURLString(url)); + if (cookies.isNull()) + return NPERR_GENERIC_ERROR; + + return copyCString(cookies.utf8(), value, len); + } + + case NPNURLVProxy: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + String proxies = plugin->proxiesForURL(makeURLString(url)); + if (proxies.isNull()) + return NPERR_GENERIC_ERROR; + + return copyCString(proxies.utf8(), value, len); + } + default: + notImplemented(); + return NPERR_GENERIC_ERROR; + } +} + +static NPError NPN_SetValueForURL(NPP npp, NPNURLVariable variable, const char* url, const char* value, uint32_t len) +{ + switch (variable) { + case NPNURLVCookie: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + plugin->setCookiesForURL(makeURLString(url), String(value, len)); + return NPERR_NO_ERROR; + } + + case NPNURLVProxy: + // Can't set the proxy for a URL. + return NPERR_GENERIC_ERROR; + + default: + notImplemented(); + return NPERR_GENERIC_ERROR; + } +} + +static NPError NPN_GetAuthenticationInfo(NPP instance, const char* protocol, const char* host, int32_t port, const char* scheme, + const char* realm, char** username, uint32_t* ulen, char** password, uint32_t* plen) +{ + notImplemented(); + return NPERR_GENERIC_ERROR; +} + +static uint32_t NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)) +{ + notImplemented(); + return NPERR_GENERIC_ERROR; +} + +static void NPN_UnscheduleTimer(NPP instance, uint32_t timerID) +{ + notImplemented(); +} + +#if PLATFORM(MAC) +static NPError NPN_PopUpContextMenu(NPP instance, NPMenu* menu) +{ + notImplemented(); + return NPERR_GENERIC_ERROR; +} + +static NPBool NPN_ConvertPoint(NPP npp, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double* destX, double* destY, NPCoordinateSpace destSpace) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + double destinationX; + double destinationY; + + bool returnValue = plugin->convertPoint(sourceX, sourceY, sourceSpace, destinationX, destinationY, destSpace); + + if (destX) + *destX = destinationX; + if (destY) + *destY = destinationY; + + return returnValue; +} +#endif + +static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs) +{ + netscapeFuncs.size = sizeof(NPNetscapeFuncs); + netscapeFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + + netscapeFuncs.geturl = NPN_GetURL; + netscapeFuncs.posturl = NPN_PostURL; + netscapeFuncs.requestread = NPN_RequestRead; + netscapeFuncs.newstream = NPN_NewStream; + netscapeFuncs.write = NPN_Write; + netscapeFuncs.destroystream = NPN_DestroyStream; + netscapeFuncs.status = NPN_Status; + netscapeFuncs.uagent = NPN_UserAgent; + netscapeFuncs.memalloc = NPN_MemAlloc; + netscapeFuncs.memfree = NPN_MemFree; + netscapeFuncs.memflush = NPN_MemFlush; + netscapeFuncs.reloadplugins = NPN_ReloadPlugins; + netscapeFuncs.getJavaEnv = NPN_GetJavaEnv; + netscapeFuncs.getJavaPeer = NPN_GetJavaPeer; + netscapeFuncs.geturlnotify = NPN_GetURLNotify; + netscapeFuncs.posturlnotify = NPN_PostURLNotify; + netscapeFuncs.getvalue = NPN_GetValue; + netscapeFuncs.setvalue = NPN_SetValue; + netscapeFuncs.invalidaterect = NPN_InvalidateRect; + netscapeFuncs.invalidateregion = NPN_InvalidateRegion; + netscapeFuncs.forceredraw = NPN_ForceRedraw; + + netscapeFuncs.getstringidentifier = NPN_GetStringIdentifier; + netscapeFuncs.getstringidentifiers = NPN_GetStringIdentifiers; + netscapeFuncs.getintidentifier = NPN_GetIntIdentifier; + netscapeFuncs.identifierisstring = NPN_IdentifierIsString; + netscapeFuncs.utf8fromidentifier = NPN_UTF8FromIdentifier; + netscapeFuncs.intfromidentifier = NPN_IntFromIdentifier; + netscapeFuncs.createobject = NPN_CreateObject; + netscapeFuncs.retainobject = NPN_RetainObject; + netscapeFuncs.releaseobject = NPN_ReleaseObject; + netscapeFuncs.invoke = NPN_Invoke; + netscapeFuncs.invokeDefault = NPN_InvokeDefault; + netscapeFuncs.evaluate = NPN_Evaluate; + netscapeFuncs.getproperty = NPN_GetProperty; + netscapeFuncs.setproperty = NPN_SetProperty; + netscapeFuncs.removeproperty = NPN_RemoveProperty; + netscapeFuncs.hasproperty = NPN_HasProperty; + netscapeFuncs.hasmethod = NPN_HasMethod; + netscapeFuncs.releasevariantvalue = NPN_ReleaseVariantValue; + netscapeFuncs.setexception = NPN_SetException; + netscapeFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState; + netscapeFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState; + netscapeFuncs.enumerate = NPN_Enumerate; + netscapeFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall; + netscapeFuncs.construct = NPN_Construct; + netscapeFuncs.getvalueforurl = NPN_GetValueForURL; + netscapeFuncs.setvalueforurl = NPN_SetValueForURL; + netscapeFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo; + netscapeFuncs.scheduletimer = NPN_ScheduleTimer; + netscapeFuncs.unscheduletimer = NPN_UnscheduleTimer; +#if PLATFORM(MAC) + netscapeFuncs.popupcontextmenu = NPN_PopUpContextMenu; + netscapeFuncs.convertpoint = NPN_ConvertPoint; +#else + netscapeFuncs.popupcontextmenu = 0; + netscapeFuncs.convertpoint = 0; +#endif +} + +NPNetscapeFuncs* netscapeBrowserFuncs() +{ + static NPNetscapeFuncs netscapeFuncs; + static bool initialized = false; + + if (!initialized) { + initializeBrowserFuncs(netscapeFuncs); + initialized = true; + } + + return &netscapeFuncs; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h new file mode 100644 index 0000000..49a7f3a --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h @@ -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. + */ + +#ifndef NetscapeBrowserFuncs_h +#define NetscapeBrowserFuncs_h + +#include <WebCore/npfunctions.h> + +namespace WebKit { + +NPNetscapeFuncs* netscapeBrowserFuncs(); + +} // namespace WebKit + + +#endif // NetscapeBrowserFuncs_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp new file mode 100644 index 0000000..0beade2 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -0,0 +1,678 @@ +/* + * 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 "NetscapePlugin.h" + +#include "NPRuntimeObjectMap.h" +#include "NetscapePluginStream.h" +#include "PluginController.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/HTTPHeaderMap.h> +#include <WebCore/IntRect.h> +#include <WebCore/KURL.h> +#include <utility> +#include <wtf/text/CString.h> + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +// The plug-in that we're currently calling NPP_New for. +static NetscapePlugin* currentNPPNewPlugin; + +PassRefPtr<NetscapePlugin> NetscapePlugin::create(PassRefPtr<NetscapePluginModule> pluginModule) +{ + if (!pluginModule) + return 0; + + return adoptRef(new NetscapePlugin(pluginModule)); +} + +NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) + : m_pluginController(0) + , m_nextRequestID(0) + , m_pluginModule(pluginModule) + , m_npWindow() + , m_isStarted(false) +#if PLATFORM(MAC) + , m_isWindowed(false) +#else + , m_isWindowed(true) +#endif + , m_inNPPNew(false) + , m_loadManually(false) +#if PLATFORM(MAC) + , m_drawingModel(static_cast<NPDrawingModel>(-1)) + , m_eventModel(static_cast<NPEventModel>(-1)) + , m_pluginHasFocus(false) + , m_windowHasFocus(false) +#ifndef NP_NO_CARBON + , m_nullEventTimer(RunLoop::main(), this, &NetscapePlugin::nullEventTimerFired) + , m_npCGContext() +#endif +#endif +{ + m_npp.ndata = this; + m_npp.pdata = 0; + + m_pluginModule->pluginCreated(); +} + +NetscapePlugin::~NetscapePlugin() +{ + ASSERT(!m_isStarted); + + m_pluginModule->pluginDestroyed(); +} + +PassRefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp) +{ + if (npp) + return static_cast<NetscapePlugin*>(npp->ndata); + + // FIXME: Return the current NetscapePlugin here. + ASSERT_NOT_REACHED(); + return 0; +} + +void NetscapePlugin::invalidate(const NPRect* invalidRect) +{ + IntRect rect; + + if (!invalidRect) + rect = IntRect(0, 0, m_frameRect.width(), m_frameRect.height()); + else + rect = IntRect(invalidRect->left, invalidRect->top, + invalidRect->right - invalidRect->left, invalidRect->bottom - invalidRect->top); + + if (platformInvalidate(rect)) + return; + + m_pluginController->invalidate(rect); +} + +const char* NetscapePlugin::userAgent(NPP npp) +{ + if (npp) + return fromNPP(npp)->userAgent(); + + if (currentNPPNewPlugin) + return currentNPPNewPlugin->userAgent(); + + return 0; +} + +const char* NetscapePlugin::userAgent() +{ + if (m_userAgent.isNull()) { + m_userAgent = m_pluginController->userAgent().utf8(); + ASSERT(!m_userAgent.isNull()); + } + return m_userAgent.data(); +} + +void NetscapePlugin::loadURL(const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, + bool sendNotification, void* notificationData) +{ + uint64_t requestID = ++m_nextRequestID; + + m_pluginController->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups()); + + if (target.isNull()) { + // The browser is going to send the data in a stream, create a plug-in stream. + RefPtr<NetscapePluginStream> pluginStream = NetscapePluginStream::create(this, requestID, sendNotification, notificationData); + ASSERT(!m_streams.contains(requestID)); + + m_streams.set(requestID, pluginStream.release()); + return; + } + + if (sendNotification) { + // Eventually we are going to get a frameDidFinishLoading or frameDidFail call for this request. + // Keep track of the notification data so we can call NPP_URLNotify. + ASSERT(!m_pendingURLNotifications.contains(requestID)); + m_pendingURLNotifications.set(requestID, make_pair(urlString, notificationData)); + } +} + +NPError NetscapePlugin::destroyStream(NPStream* stream, NPReason reason) +{ + NetscapePluginStream* pluginStream = 0; + + for (StreamsMap::const_iterator it = m_streams.begin(), end = m_streams.end(); it != end; ++it) { + if (it->second->npStream() == stream) { + pluginStream = it->second.get(); + break; + } + } + + if (!pluginStream) + return NPERR_INVALID_INSTANCE_ERROR; + + return pluginStream->destroy(reason); +} + +void NetscapePlugin::setIsWindowed(bool isWindowed) +{ + // Once the plugin has started, it's too late to change whether the plugin is windowed or not. + // (This is true in Firefox and Chrome, too.) Disallow setting m_isWindowed in that case to + // keep our internal state consistent. + if (m_isStarted) + return; + + m_isWindowed = isWindowed; +} + +void NetscapePlugin::setStatusbarText(const String& statusbarText) +{ + m_pluginController->setStatusbarText(statusbarText); +} + +void NetscapePlugin::setException(const String& exceptionString) +{ + // FIXME: If the plug-in is running in its own process, this needs to send a CoreIPC message instead of + // calling the runtime object map directly. + NPRuntimeObjectMap::setGlobalException(exceptionString); +} + +bool NetscapePlugin::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result) +{ + return m_pluginController->evaluate(npObject, scriptString, result, allowPopups()); +} + +bool NetscapePlugin::isPrivateBrowsingEnabled() +{ + return m_pluginController->isPrivateBrowsingEnabled(); +} + +NPObject* NetscapePlugin::windowScriptNPObject() +{ + return m_pluginController->windowScriptNPObject(); +} + +NPObject* NetscapePlugin::pluginElementNPObject() +{ + return m_pluginController->pluginElementNPObject(); +} + +void NetscapePlugin::cancelStreamLoad(NetscapePluginStream* pluginStream) +{ + if (pluginStream == m_manualStream) { + m_pluginController->cancelManualStreamLoad(); + return; + } + + // Ask the plug-in controller to cancel this stream load. + m_pluginController->cancelStreamLoad(pluginStream->streamID()); +} + +void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream) +{ + if (pluginStream == m_manualStream) { + m_manualStream = 0; + return; + } + + ASSERT(m_streams.get(pluginStream->streamID()) == pluginStream); + m_streams.remove(pluginStream->streamID()); +} + +bool NetscapePlugin::isAcceleratedCompositingEnabled() +{ +#if USE(ACCELERATED_COMPOSITING) + return m_pluginController->isAcceleratedCompositingEnabled(); +#else + return false; +#endif +} + +void NetscapePlugin::pushPopupsEnabledState(bool state) +{ + m_popupEnabledStates.append(state); +} + +void NetscapePlugin::popPopupsEnabledState() +{ + ASSERT(!m_popupEnabledStates.isEmpty()); + + m_popupEnabledStates.removeLast(); +} + +String NetscapePlugin::proxiesForURL(const String& urlString) +{ + return m_pluginController->proxiesForURL(urlString); +} + +String NetscapePlugin::cookiesForURL(const String& urlString) +{ + return m_pluginController->cookiesForURL(urlString); +} + +void NetscapePlugin::setCookiesForURL(const String& urlString, const String& cookieString) +{ + m_pluginController->setCookiesForURL(urlString, cookieString); +} + +NPError NetscapePlugin::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* savedData) +{ + return m_pluginModule->pluginFuncs().newp(pluginType, &m_npp, mode, argc, argn, argv, savedData); +} + +NPError NetscapePlugin::NPP_Destroy(NPSavedData** savedData) +{ + return m_pluginModule->pluginFuncs().destroy(&m_npp, savedData); +} + +NPError NetscapePlugin::NPP_SetWindow(NPWindow* npWindow) +{ + return m_pluginModule->pluginFuncs().setwindow(&m_npp, npWindow); +} + +NPError NetscapePlugin::NPP_NewStream(NPMIMEType mimeType, NPStream* stream, NPBool seekable, uint16_t* streamType) +{ + return m_pluginModule->pluginFuncs().newstream(&m_npp, mimeType, stream, seekable, streamType); +} + +NPError NetscapePlugin::NPP_DestroyStream(NPStream* stream, NPReason reason) +{ + return m_pluginModule->pluginFuncs().destroystream(&m_npp, stream, reason); +} + +void NetscapePlugin::NPP_StreamAsFile(NPStream* stream, const char* filename) +{ + return m_pluginModule->pluginFuncs().asfile(&m_npp, stream, filename); +} + +int32_t NetscapePlugin::NPP_WriteReady(NPStream* stream) +{ + return m_pluginModule->pluginFuncs().writeready(&m_npp, stream); +} + +int32_t NetscapePlugin::NPP_Write(NPStream* stream, int32_t offset, int32_t len, void* buffer) +{ + return m_pluginModule->pluginFuncs().write(&m_npp, stream, offset, len, buffer); +} + +int16_t NetscapePlugin::NPP_HandleEvent(void* event) +{ + return m_pluginModule->pluginFuncs().event(&m_npp, event); +} + +void NetscapePlugin::NPP_URLNotify(const char* url, NPReason reason, void* notifyData) +{ + m_pluginModule->pluginFuncs().urlnotify(&m_npp, url, reason, notifyData); +} + +NPError NetscapePlugin::NPP_GetValue(NPPVariable variable, void *value) +{ + if (!m_pluginModule->pluginFuncs().getvalue) + return NPERR_GENERIC_ERROR; + + return m_pluginModule->pluginFuncs().getvalue(&m_npp, variable, value); +} + +NPError NetscapePlugin::NPP_SetValue(NPNVariable variable, void *value) +{ + if (!m_pluginModule->pluginFuncs().setvalue) + return NPERR_GENERIC_ERROR; + + return m_pluginModule->pluginFuncs().setvalue(&m_npp, variable, value); +} + +void NetscapePlugin::callSetWindow() +{ + m_npWindow.x = m_frameRect.x(); + m_npWindow.y = m_frameRect.y(); + m_npWindow.width = m_frameRect.width(); + m_npWindow.height = m_frameRect.height(); + m_npWindow.clipRect.top = m_clipRect.y(); + m_npWindow.clipRect.left = m_clipRect.x(); + m_npWindow.clipRect.bottom = m_clipRect.bottom(); + m_npWindow.clipRect.right = m_clipRect.right(); + + NPP_SetWindow(&m_npWindow); +} + +bool NetscapePlugin::shouldLoadSrcURL() +{ + // Check if we should cancel the load + NPBool cancelSrcStream = false; + + if (NPP_GetValue(NPPVpluginCancelSrcStream, &cancelSrcStream) != NPERR_NO_ERROR) + return true; + + return !cancelSrcStream; +} + +NetscapePluginStream* NetscapePlugin::streamFromID(uint64_t streamID) +{ + return m_streams.get(streamID).get(); +} + +void NetscapePlugin::stopAllStreams() +{ + Vector<RefPtr<NetscapePluginStream> > streams; + copyValuesToVector(m_streams, streams); + + for (size_t i = 0; i < streams.size(); ++i) + streams[i]->stop(NPRES_USER_BREAK); +} + +bool NetscapePlugin::allowPopups() const +{ + if (m_pluginModule->pluginFuncs().version >= NPVERS_HAS_POPUPS_ENABLED_STATE) { + if (!m_popupEnabledStates.isEmpty()) + return m_popupEnabledStates.last(); + } + + // FIXME: Check if the current event is a user gesture. + // Really old versions of Flash required this for popups to work, but all newer versions + // support NPN_PushPopupEnabledState/NPN_PopPopupEnabledState. + return false; +} + +bool NetscapePlugin::initialize(PluginController* pluginController, const Parameters& parameters) +{ + ASSERT(!m_pluginController); + ASSERT(pluginController); + + m_pluginController = pluginController; + + uint16_t mode = parameters.loadManually ? NP_FULL : NP_EMBED; + + m_loadManually = parameters.loadManually; + + CString mimeTypeCString = parameters.mimeType.utf8(); + + ASSERT(parameters.names.size() == parameters.values.size()); + + Vector<CString> paramNames; + Vector<CString> paramValues; + for (size_t i = 0; i < parameters.names.size(); ++i) { + paramNames.append(parameters.names[i].utf8()); + paramValues.append(parameters.values[i].utf8()); + } + + // The strings that these pointers point to are kept alive by paramNames and paramValues. + Vector<const char*> names; + Vector<const char*> values; + for (size_t i = 0; i < paramNames.size(); ++i) { + names.append(paramNames[i].data()); + values.append(paramValues[i].data()); + } + + NetscapePlugin* previousNPPNewPlugin = currentNPPNewPlugin; + + m_inNPPNew = true; + currentNPPNewPlugin = this; + + NPError error = NPP_New(const_cast<char*>(mimeTypeCString.data()), mode, names.size(), + const_cast<char**>(names.data()), const_cast<char**>(values.data()), 0); + + m_inNPPNew = false; + currentNPPNewPlugin = previousNPPNewPlugin; + + if (error != NPERR_NO_ERROR) + return false; + + m_isStarted = true; + + // FIXME: This is not correct in all cases. + m_npWindow.type = NPWindowTypeDrawable; + + if (!platformPostInitialize()) { + destroy(); + return false; + } + + // Load the src URL if needed. + if (!parameters.loadManually && !parameters.url.isEmpty() && shouldLoadSrcURL()) + loadURL("GET", parameters.url.string(), String(), HTTPHeaderMap(), Vector<uint8_t>(), false, 0); + + return true; +} + +void NetscapePlugin::destroy() +{ + ASSERT(m_isStarted); + + // Stop all streams. + stopAllStreams(); + + NPP_Destroy(0); + + m_isStarted = false; + m_pluginController = 0; + + platformDestroy(); +} + +void NetscapePlugin::paint(GraphicsContext* context, const IntRect& dirtyRect) +{ + ASSERT(m_isStarted); + + platformPaint(context, dirtyRect); +} + +void NetscapePlugin::geometryDidChange(const IntRect& frameRect, const IntRect& clipRect) +{ + ASSERT(m_isStarted); + + if (m_frameRect == frameRect && m_clipRect == clipRect) { + // Nothing to do. + return; + } + + m_frameRect = frameRect; + m_clipRect = clipRect; + + platformGeometryDidChange(); + callSetWindow(); +} + +void NetscapePlugin::frameDidFinishLoading(uint64_t requestID) +{ + ASSERT(m_isStarted); + + PendingURLNotifyMap::iterator it = m_pendingURLNotifications.find(requestID); + if (it == m_pendingURLNotifications.end()) + return; + + String url = it->second.first; + void* notificationData = it->second.second; + + m_pendingURLNotifications.remove(it); + + NPP_URLNotify(url.utf8().data(), NPRES_DONE, notificationData); +} + +void NetscapePlugin::frameDidFail(uint64_t requestID, bool wasCancelled) +{ + ASSERT(m_isStarted); + + PendingURLNotifyMap::iterator it = m_pendingURLNotifications.find(requestID); + if (it == m_pendingURLNotifications.end()) + return; + + String url = it->second.first; + void* notificationData = it->second.second; + + m_pendingURLNotifications.remove(it); + + NPP_URLNotify(url.utf8().data(), wasCancelled ? NPRES_USER_BREAK : NPRES_NETWORK_ERR, notificationData); +} + +void NetscapePlugin::didEvaluateJavaScript(uint64_t requestID, const String& requestURLString, const String& result) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(requestID)) + pluginStream->sendJavaScriptStream(requestURLString, result); +} + +void NetscapePlugin::streamDidReceiveResponse(uint64_t streamID, const KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(streamID)) + pluginStream->didReceiveResponse(responseURL, streamLength, lastModifiedTime, mimeType, headers); +} + +void NetscapePlugin::streamDidReceiveData(uint64_t streamID, const char* bytes, int length) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(streamID)) + pluginStream->didReceiveData(bytes, length); +} + +void NetscapePlugin::streamDidFinishLoading(uint64_t streamID) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(streamID)) + pluginStream->didFinishLoading(); +} + +void NetscapePlugin::streamDidFail(uint64_t streamID, bool wasCancelled) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(streamID)) + pluginStream->didFail(wasCancelled); +} + +void NetscapePlugin::manualStreamDidReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, + const String& mimeType, const String& headers) +{ + ASSERT(m_isStarted); + ASSERT(m_loadManually); + ASSERT(!m_manualStream); + + m_manualStream = NetscapePluginStream::create(this, 0, false, 0); + m_manualStream->didReceiveResponse(responseURL, streamLength, lastModifiedTime, mimeType, headers); +} + +void NetscapePlugin::manualStreamDidReceiveData(const char* bytes, int length) +{ + ASSERT(m_isStarted); + ASSERT(m_loadManually); + ASSERT(m_manualStream); + + m_manualStream->didReceiveData(bytes, length); +} + +void NetscapePlugin::manualStreamDidFinishLoading() +{ + ASSERT(m_isStarted); + ASSERT(m_loadManually); + ASSERT(m_manualStream); + + m_manualStream->didFinishLoading(); +} + +void NetscapePlugin::manualStreamDidFail(bool wasCancelled) +{ + ASSERT(m_isStarted); + ASSERT(m_loadManually); + ASSERT(m_manualStream); + + m_manualStream->didFail(wasCancelled); +} + +bool NetscapePlugin::handleMouseEvent(const WebMouseEvent& mouseEvent) +{ + ASSERT(m_isStarted); + + return platformHandleMouseEvent(mouseEvent); +} + +bool NetscapePlugin::handleWheelEvent(const WebWheelEvent& wheelEvent) +{ + ASSERT(m_isStarted); + + return platformHandleWheelEvent(wheelEvent); +} + +bool NetscapePlugin::handleMouseEnterEvent(const WebMouseEvent& mouseEvent) +{ + ASSERT(m_isStarted); + + return platformHandleMouseEnterEvent(mouseEvent); +} + +bool NetscapePlugin::handleMouseLeaveEvent(const WebMouseEvent& mouseEvent) +{ + ASSERT(m_isStarted); + + return platformHandleMouseLeaveEvent(mouseEvent); +} + +bool NetscapePlugin::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent) +{ + ASSERT(m_isStarted); + + return platformHandleKeyboardEvent(keyboardEvent); +} + +void NetscapePlugin::setFocus(bool hasFocus) +{ + ASSERT(m_isStarted); + + platformSetFocus(hasFocus); +} + +NPObject* NetscapePlugin::pluginScriptableNPObject() +{ + ASSERT(m_isStarted); + NPObject* scriptableNPObject = 0; + + if (NPP_GetValue(NPPVpluginScriptableNPObject, &scriptableNPObject) != NPERR_NO_ERROR) + return 0; + + return scriptableNPObject; +} + +void NetscapePlugin::privateBrowsingStateChanged(bool privateBrowsingEnabled) +{ + ASSERT(m_isStarted); + + // From https://wiki.mozilla.org/Plugins:PrivateMode + // When the browser turns private mode on or off it will call NPP_SetValue for "NPNVprivateModeBool" + // (assigned enum value 18) with a pointer to an NPBool value on all applicable instances. + // Plugins should check the boolean value pointed to, not the pointer itself. + // The value will be true when private mode is on. + NPBool value = privateBrowsingEnabled; + NPP_SetValue(NPNVprivateModeBool, &value); +} + +PluginController* NetscapePlugin::controller() +{ + return m_pluginController; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h new file mode 100644 index 0000000..fb5d37e --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -0,0 +1,229 @@ +/* + * 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. + */ + +#ifndef NetscapePlugin_h +#define NetscapePlugin_h + +#include "NetscapePluginModule.h" +#include "Plugin.h" +#include "RunLoop.h" +#include <WebCore/GraphicsLayer.h> +#include <WebCore/IntRect.h> +#include <wtf/HashMap.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + class HTTPHeaderMap; +} + +namespace WebKit { + +class NetscapePluginStream; + +class NetscapePlugin : public Plugin { +public: + static PassRefPtr<NetscapePlugin> create(PassRefPtr<NetscapePluginModule> pluginModule); + virtual ~NetscapePlugin(); + + static PassRefPtr<NetscapePlugin> fromNPP(NPP); + +#if PLATFORM(MAC) + NPError setDrawingModel(NPDrawingModel); + NPError setEventModel(NPEventModel); + NPBool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace); + +#ifndef NP_NO_CARBON + WindowRef windowRef() const; + bool isWindowActive() const { return m_windowHasFocus; } + + static NetscapePlugin* netscapePluginFromWindow(WindowRef); + static unsigned buttonState(); +#endif + +#elif PLATFORM(WIN) + HWND containingWindow() const; +#endif + + void invalidate(const NPRect*); + static const char* userAgent(NPP); + void loadURL(const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, + const Vector<uint8_t>& httpBody, bool sendNotification, void* notificationData); + NPError destroyStream(NPStream*, NPReason); + void setIsWindowed(bool); + void setStatusbarText(const String&); + static void setException(const String&); + bool evaluate(NPObject*, const String&scriptString, NPVariant* result); + bool isPrivateBrowsingEnabled(); + + // These return retained objects. + NPObject* windowScriptNPObject(); + NPObject* pluginElementNPObject(); + + void cancelStreamLoad(NetscapePluginStream*); + void removePluginStream(NetscapePluginStream*); + + bool isAcceleratedCompositingEnabled(); + + void pushPopupsEnabledState(bool enabled); + void popPopupsEnabledState(); + + String proxiesForURL(const String& urlString); + String cookiesForURL(const String& urlString); + void setCookiesForURL(const String& urlString, const String& cookieString); + + // Member functions for calling into the plug-in. + NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*); + NPError NPP_Destroy(NPSavedData**); + NPError NPP_SetWindow(NPWindow*); + NPError NPP_NewStream(NPMIMEType, NPStream*, NPBool seekable, uint16_t* stype); + NPError NPP_DestroyStream(NPStream*, NPReason); + void NPP_StreamAsFile(NPStream*, const char* filename); + int32_t NPP_WriteReady(NPStream*); + int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer); + int16_t NPP_HandleEvent(void* event); + void NPP_URLNotify(const char* url, NPReason, void* notifyData); + NPError NPP_GetValue(NPPVariable, void *value); + NPError NPP_SetValue(NPNVariable, void *value); + +private: + NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule); + + void callSetWindow(); + bool shouldLoadSrcURL(); + NetscapePluginStream* streamFromID(uint64_t streamID); + void stopAllStreams(); + bool allowPopups() const; + + const char* userAgent(); + + bool platformPostInitialize(); + void platformDestroy(); + bool platformInvalidate(const WebCore::IntRect&); + void platformGeometryDidChange(); + void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + + bool platformHandleMouseEvent(const WebMouseEvent&); + bool platformHandleWheelEvent(const WebWheelEvent&); + bool platformHandleMouseEnterEvent(const WebMouseEvent&); + bool platformHandleMouseLeaveEvent(const WebMouseEvent&); + bool platformHandleKeyboardEvent(const WebKeyboardEvent&); + void platformSetFocus(bool); + + // Plugin + virtual bool initialize(PluginController*, const Parameters&); + virtual void destroy(); + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); +#if PLATFORM(MAC) + virtual PlatformLayer* pluginLayer(); +#endif + virtual void geometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect); + virtual void frameDidFinishLoading(uint64_t requestID); + virtual void frameDidFail(uint64_t requestID, bool wasCancelled); + virtual void didEvaluateJavaScript(uint64_t requestID, const String& requestURLString, const String& result); + virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers); + virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length); + virtual void streamDidFinishLoading(uint64_t streamID); + virtual void streamDidFail(uint64_t streamID, bool wasCancelled); + virtual void manualStreamDidReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers); + virtual void manualStreamDidReceiveData(const char* bytes, int length); + virtual void manualStreamDidFinishLoading(); + virtual void manualStreamDidFail(bool wasCancelled); + + virtual bool handleMouseEvent(const WebMouseEvent&); + virtual bool handleWheelEvent(const WebWheelEvent&); + virtual bool handleMouseEnterEvent(const WebMouseEvent&); + virtual bool handleMouseLeaveEvent(const WebMouseEvent&); + virtual bool handleKeyboardEvent(const WebKeyboardEvent&); + virtual void setFocus(bool); + virtual NPObject* pluginScriptableNPObject(); + +#if PLATFORM(MAC) + virtual void windowFocusChanged(bool); + virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); + virtual void windowVisibilityChanged(bool); + + virtual uint64_t pluginComplexTextInputIdentifier() const; + virtual void sendComplexTextInput(const String& textInput); +#endif + + virtual void privateBrowsingStateChanged(bool); + + virtual PluginController* controller(); + + PluginController* m_pluginController; + uint64_t m_nextRequestID; + + typedef HashMap<uint64_t, std::pair<String, void*> > PendingURLNotifyMap; + PendingURLNotifyMap m_pendingURLNotifications; + + typedef HashMap<uint64_t, RefPtr<NetscapePluginStream> > StreamsMap; + StreamsMap m_streams; + + RefPtr<NetscapePluginModule> m_pluginModule; + NPP_t m_npp; + NPWindow m_npWindow; + + WebCore::IntRect m_frameRect; + WebCore::IntRect m_clipRect; + + CString m_userAgent; + + bool m_isStarted; + bool m_isWindowed; + bool m_inNPPNew; + bool m_loadManually; + RefPtr<NetscapePluginStream> m_manualStream; + Vector<bool, 8> m_popupEnabledStates; + +#if PLATFORM(MAC) + NPDrawingModel m_drawingModel; + NPEventModel m_eventModel; + RetainPtr<PlatformLayer> m_pluginLayer; + + bool m_pluginHasFocus; + bool m_windowHasFocus; + + WebCore::IntRect m_windowFrameInScreenCoordinates; + WebCore::IntRect m_viewFrameInWindowCoordinates; + +#ifndef NP_NO_CARBON + void nullEventTimerFired(); + + // FIXME: It's a bit wasteful to have one null event timer per plug-in. + // We should investigate having one per window. + RunLoop::Timer<NetscapePlugin> m_nullEventTimer; + NP_CGContext m_npCGContext; +#endif +#elif PLATFORM(WIN) + HWND m_window; +#endif +}; + +} // namespace WebKit + +#endif // NetscapePlugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp new file mode 100644 index 0000000..be60795 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp @@ -0,0 +1,355 @@ +/* + * 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 "NetscapePluginStream.h" + +#include "NetscapePlugin.h" +#include <utility> + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +NetscapePluginStream::NetscapePluginStream(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, bool sendNotification, void* notificationData) + : m_plugin(plugin) + , m_streamID(streamID) + , m_sendNotification(sendNotification) + , m_notificationData(notificationData) + , m_npStream() + , m_transferMode(NP_NORMAL) + , m_offset(0) + , m_fileHandle(invalidPlatformFileHandle) + , m_isStarted(false) +#if !ASSERT_DISABLED + , m_urlNotifyHasBeenCalled(false) +#endif + , m_deliveryDataTimer(RunLoop::main(), this, &NetscapePluginStream::deliverDataToPlugin) + , m_stopStreamWhenDoneDelivering(false) +{ +} + +NetscapePluginStream::~NetscapePluginStream() +{ + ASSERT(!m_isStarted); + ASSERT(!m_sendNotification || m_urlNotifyHasBeenCalled); + ASSERT(m_fileHandle == invalidPlatformFileHandle); +} + +void NetscapePluginStream::didReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers) +{ + // Starting the stream could cause the plug-in stream to go away so we keep a reference to it here. + RefPtr<NetscapePluginStream> protect(this); + + start(responseURL, streamLength, lastModifiedTime, mimeType, headers); +} + +void NetscapePluginStream::didReceiveData(const char* bytes, int length) +{ + // Delivering the data could cause the plug-in stream to go away so we keep a reference to it here. + RefPtr<NetscapePluginStream> protect(this); + + deliverData(bytes, length); +} + +void NetscapePluginStream::didFinishLoading() +{ + // Stopping the stream could cause the plug-in stream to go away so we keep a reference to it here. + RefPtr<NetscapePluginStream> protect(this); + + stop(NPRES_DONE); +} + +void NetscapePluginStream::didFail(bool wasCancelled) +{ + // Stopping the stream could cause the plug-in stream to go away so we keep a reference to it here. + RefPtr<NetscapePluginStream> protect(this); + + stop(wasCancelled ? NPRES_USER_BREAK : NPRES_NETWORK_ERR); +} + +void NetscapePluginStream::sendJavaScriptStream(const String& requestURLString, const String& result) +{ + // starting the stream or delivering the data to it might cause the plug-in stream to go away, so we keep + // a reference to it here. + RefPtr<NetscapePluginStream> protect(this); + + CString resultCString = requestURLString.utf8(); + if (resultCString.isNull()) { + // There was an error evaluating the JavaScript, call NPP_URLNotify if needed and then destroy the stream. + notifyAndDestroyStream(NPRES_NETWORK_ERR); + return; + } + + if (!start(requestURLString, resultCString.length(), 0, "text/plain", "")) + return; + + deliverData(resultCString.data(), resultCString.length()); + stop(NPRES_DONE); +} + +NPError NetscapePluginStream::destroy(NPReason reason) +{ + // It doesn't make sense to call NPN_DestroyStream on a stream that hasn't been started yet. + if (!m_isStarted) + return NPERR_GENERIC_ERROR; + + // It isn't really valid for a plug-in to call NPN_DestroyStream with NPRES_DONE. + // (At least not for browser initiated streams, and we don't support plug-in initiated streams). + if (reason == NPRES_DONE) + return NPERR_INVALID_PARAM; + + cancel(); + stop(reason); + return NPERR_NO_ERROR; +} + +static bool isSupportedTransferMode(uint16_t transferMode) +{ + switch (transferMode) { + case NP_ASFILEONLY: + case NP_ASFILE: + case NP_NORMAL: + return true; + // FIXME: We don't support seekable streams. + case NP_SEEK: + return false; + } + + ASSERT_NOT_REACHED(); + return false; +} + +bool NetscapePluginStream::start(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers) +{ + m_responseURL = responseURLString.utf8(); + m_mimeType = mimeType.utf8(); + m_headers = headers.utf8(); + + m_npStream.ndata = this; + m_npStream.url = m_responseURL.data(); + m_npStream.end = streamLength; + m_npStream.lastmodified = lastModifiedTime; + m_npStream.notifyData = m_notificationData; + m_npStream.headers = m_headers.length() == 0 ? 0 : m_headers.data(); + + NPError error = m_plugin->NPP_NewStream(const_cast<char*>(m_mimeType.data()), &m_npStream, false, &m_transferMode); + if (error != NPERR_NO_ERROR) { + // We failed to start the stream, cancel the load and destroy it. + cancel(); + notifyAndDestroyStream(NPRES_NETWORK_ERR); + return false; + } + + // We successfully started the stream. + m_isStarted = true; + + if (!isSupportedTransferMode(m_transferMode)) { + // Cancel the load and stop the stream. + cancel(); + stop(NPRES_NETWORK_ERR); + return false; + } + + return true; +} + +void NetscapePluginStream::deliverData(const char* bytes, int length) +{ + ASSERT(m_isStarted); + + if (m_transferMode != NP_ASFILEONLY) { + if (!m_deliveryData) + m_deliveryData.set(new Vector<uint8_t>); + + m_deliveryData->reserveCapacity(m_deliveryData->size() + length); + m_deliveryData->append(bytes, length); + + deliverDataToPlugin(); + } + + if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY) + deliverDataToFile(bytes, length); +} + +void NetscapePluginStream::deliverDataToPlugin() +{ + ASSERT(m_isStarted); + + int32_t numBytesToDeliver = m_deliveryData->size(); + int32_t numBytesDelivered = 0; + + while (numBytesDelivered < numBytesToDeliver) { + int32_t numBytesPluginCanHandle = m_plugin->NPP_WriteReady(&m_npStream); + + // NPP_WriteReady could call NPN_DestroyStream and destroy the stream. + if (!m_isStarted) + return; + + if (numBytesPluginCanHandle <= 0) { + // The plug-in can't handle more data, we'll send the rest later + m_deliveryDataTimer.startOneShot(0); + break; + } + + // Figure out how much data to send to the plug-in. + int32_t dataLength = min(numBytesPluginCanHandle, numBytesToDeliver - numBytesDelivered); + uint8_t* data = m_deliveryData->data() + numBytesDelivered; + + int32_t numBytesWritten = m_plugin->NPP_Write(&m_npStream, m_offset, dataLength, data); + if (numBytesWritten < 0) { + stop(NPRES_NETWORK_ERR); + return; + } + + // NPP_Write could call NPN_DestroyStream and destroy the stream. + if (!m_isStarted) + return; + + numBytesWritten = min(numBytesWritten, dataLength); + m_offset += numBytesWritten; + numBytesDelivered += numBytesWritten; + } + + // We didn't write anything. + if (!numBytesDelivered) + return; + + if (numBytesDelivered < numBytesToDeliver) { + // Remove the bytes that we actually delivered. + m_deliveryData->remove(0, numBytesDelivered); + } else { + m_deliveryData->clear(); + + if (m_stopStreamWhenDoneDelivering) + stop(NPRES_DONE); + } +} + +void NetscapePluginStream::deliverDataToFile(const char* bytes, int length) +{ + if (m_fileHandle == invalidPlatformFileHandle && m_filePath.isNull()) { + // Create a temporary file. + m_filePath = openTemporaryFile("WebKitPluginStream", m_fileHandle); + + // We failed to open the file, stop the stream. + if (m_fileHandle == invalidPlatformFileHandle) { + stop(NPRES_NETWORK_ERR); + return; + } + } + + if (!length) + return; + + int byteCount = writeToFile(m_fileHandle, bytes, length); + if (byteCount != length) { + // This happens only rarely, when we are out of disk space or have a disk I/O error. + closeFile(m_fileHandle); + + stop(NPRES_NETWORK_ERR); + } +} + +void NetscapePluginStream::stop(NPReason reason) +{ + // The stream was stopped before it got a chance to start. This can happen if a stream is cancelled by + // WebKit before it received a response. + if (!m_isStarted) + return; + + if (reason == NPRES_DONE && m_deliveryData && !m_deliveryData->isEmpty()) { + // There is still data left that the plug-in hasn't been able to consume yet. + ASSERT(m_deliveryDataTimer.isActive()); + + // Set m_stopStreamWhenDoneDelivering to true so that the next time the delivery timer fires + // and calls deliverDataToPlugin the stream will be closed if all the remaining data was + // successfully delivered. + m_stopStreamWhenDoneDelivering = true; + return; + } + + m_deliveryData = 0; + m_deliveryDataTimer.stop(); + + if (m_transferMode == NP_ASFILE || m_transferMode == NP_ASFILEONLY) { + if (reason == NPRES_DONE) { + // Ensure that the file is created. + deliverDataToFile(0, 0); + if (m_fileHandle != invalidPlatformFileHandle) + closeFile(m_fileHandle); + + ASSERT(!m_filePath.isNull()); + + m_plugin->NPP_StreamAsFile(&m_npStream, m_filePath.data()); + } else { + // Just close the file. + if (m_fileHandle != invalidPlatformFileHandle) + closeFile(m_fileHandle); + } + + // Delete the file after calling NPP_StreamAsFile(), instead of in the destructor. It should be OK + // to delete the file here -- NPP_StreamAsFile() is always called immediately before NPP_DestroyStream() + // (the stream destruction function), so there can be no expectation that a plugin will read the stream + // file asynchronously after NPP_StreamAsFile() is called. + deleteFile(String::fromUTF8(m_filePath.data())); + m_filePath = CString(); + + // NPP_StreamAsFile could call NPN_DestroyStream and destroy the stream. + if (!m_isStarted) + return; + } + + // Set m_isStarted to false before calling NPP_DestroyStream in case NPP_DestroyStream calls NPN_DestroyStream. + m_isStarted = false; + + m_plugin->NPP_DestroyStream(&m_npStream, reason); + + notifyAndDestroyStream(reason); +} + +void NetscapePluginStream::cancel() +{ + m_plugin->cancelStreamLoad(this); +} + +void NetscapePluginStream::notifyAndDestroyStream(NPReason reason) +{ + ASSERT(!m_isStarted); + ASSERT(!m_deliveryDataTimer.isActive()); + ASSERT(!m_urlNotifyHasBeenCalled); + + if (m_sendNotification) { + m_plugin->NPP_URLNotify(m_responseURL.data(), reason, m_notificationData); + +#if !ASSERT_DISABLED + m_urlNotifyHasBeenCalled = true; +#endif + } + + m_plugin->removePluginStream(this); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h new file mode 100644 index 0000000..7757001 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h @@ -0,0 +1,112 @@ +/* + * 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. + */ + +#ifndef NetscapePluginStream_h +#define NetscapePluginStream_h + +#include "RunLoop.h" +#include <WebCore/FileSystem.h> +#include <WebCore/npruntime_internal.h> +#include <wtf/Forward.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> +#include <wtf/text/CString.h> + +namespace WebCore { + class KURL; +} + +namespace WebKit { + +class NetscapePlugin; + +class NetscapePluginStream : public RefCounted<NetscapePluginStream> { +public: + static PassRefPtr<NetscapePluginStream> create(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, bool sendNotification, void* notificationData) + { + return adoptRef(new NetscapePluginStream(plugin, streamID, sendNotification, notificationData)); + } + ~NetscapePluginStream(); + + uint64_t streamID() const { return m_streamID; } + const NPStream* npStream() const { return &m_npStream; } + + void didReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers); + void didReceiveData(const char* bytes, int length); + void didFinishLoading(); + void didFail(bool wasCancelled); + + void sendJavaScriptStream(const String& requestURLString, const String& result); + + void stop(NPReason); + NPError destroy(NPReason); + +private: + NetscapePluginStream(PassRefPtr<NetscapePlugin>, uint64_t streamID, bool sendNotification, void* notificationData); + + bool start(const String& responseURLString, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers); + + void cancel(); + void notifyAndDestroyStream(NPReason); + + void deliverData(const char* bytes, int length); + void deliverDataToPlugin(); + void deliverDataToFile(const char* bytes, int length); + + RefPtr<NetscapePlugin> m_plugin; + uint64_t m_streamID; + + bool m_sendNotification; + void* m_notificationData; + + NPStream m_npStream; + uint16_t m_transferMode; + int32_t m_offset; + + CString m_filePath; + WebCore::PlatformFileHandle m_fileHandle; + + // Whether NPP_NewStream has successfully been called. + bool m_isStarted; + +#if !ASSERT_DISABLED + bool m_urlNotifyHasBeenCalled; +#endif + + CString m_responseURL; + CString m_mimeType; + CString m_headers; + + RunLoop::Timer<NetscapePluginStream> m_deliveryDataTimer; + OwnPtr< Vector<uint8_t> > m_deliveryData; + bool m_stopStreamWhenDoneDelivering; +}; + +} // namespace WebKit + +#endif // NetscapePluginStream_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp new file mode 100644 index 0000000..64239f3 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "NetscapePlugin.h" + +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +bool NetscapePlugin::platformPostInitialize() +{ + notImplemented(); + return true; +} + +void NetscapePlugin::platformDestroy() +{ + notImplemented(); +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + notImplemented(); +} + +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +{ + notImplemented(); +} + +NPEvent toNP(const WebMouseEvent& event) +{ + NPEvent npEvent = NPEvent(); + notImplemented(); + return npEvent; +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +{ + notImplemented(); + return true; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformSetFocus(bool) +{ + notImplemented(); +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + notImplemented(); + return true; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + notImplemented(); + return true; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&) +{ + notImplemented(); + return false; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm new file mode 100644 index 0000000..1240ed7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm @@ -0,0 +1,903 @@ +/* + * 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 "NetscapePlugin.h" + +#include "PluginController.h" +#include "WebEvent.h" +#include <WebCore/GraphicsContext.h> +#include <Carbon/Carbon.h> +#include <WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +#ifndef NP_NO_CARBON +static const double nullEventIntervalActive = 0.02; +static const double nullEventIntervalNotActive = 0.25; + +static unsigned buttonStateFromLastMouseEvent; + +#endif + +NPError NetscapePlugin::setDrawingModel(NPDrawingModel drawingModel) +{ + // The drawing model can only be set from NPP_New. + if (!m_inNPPNew) + return NPERR_GENERIC_ERROR; + + switch (drawingModel) { +#ifndef NP_NO_QUICKDRAW + case NPDrawingModelQuickDraw: +#endif + case NPDrawingModelCoreGraphics: + case NPDrawingModelCoreAnimation: + m_drawingModel = drawingModel; + break; + + default: + return NPERR_GENERIC_ERROR; + } + + return NPERR_NO_ERROR; +} + +NPError NetscapePlugin::setEventModel(NPEventModel eventModel) +{ + // The event model can only be set from NPP_New. + if (!m_inNPPNew) + return NPERR_GENERIC_ERROR; + + switch (eventModel) { +#ifndef NP_NO_CARBON + case NPEventModelCarbon: +#endif + case NPEventModelCocoa: + m_eventModel = eventModel; + break; + + default: + return NPERR_GENERIC_ERROR; + } + + return NPERR_NO_ERROR; +} + +static double flipScreenYCoordinate(double y) +{ + return [[[NSScreen screens] objectAtIndex:0] frame].size.height - y; +} + +NPBool NetscapePlugin::convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace) +{ + if (sourceSpace == destSpace) { + destX = sourceX; + destY = sourceY; + return true; + } + + double sourceXInScreenSpace; + double sourceYInScreenSpace; + + FloatPoint sourceInScreenSpace; + switch (sourceSpace) { + case NPCoordinateSpacePlugin: + sourceXInScreenSpace = sourceX + m_windowFrameInScreenCoordinates.x() + m_viewFrameInWindowCoordinates.x() + m_npWindow.x; + sourceYInScreenSpace = m_windowFrameInScreenCoordinates.y() + m_viewFrameInWindowCoordinates.y() + m_viewFrameInWindowCoordinates.height() - (sourceY + m_npWindow.y); + break; + case NPCoordinateSpaceWindow: + sourceXInScreenSpace = sourceX + m_windowFrameInScreenCoordinates.x(); + sourceYInScreenSpace = sourceY + m_windowFrameInScreenCoordinates.y(); + break; + case NPCoordinateSpaceFlippedWindow: + sourceXInScreenSpace = sourceX + m_windowFrameInScreenCoordinates.x(); + sourceYInScreenSpace = m_windowFrameInScreenCoordinates.y() + m_windowFrameInScreenCoordinates.height() - sourceY; + break; + case NPCoordinateSpaceScreen: + sourceXInScreenSpace = sourceX; + sourceYInScreenSpace = sourceY; + break; + case NPCoordinateSpaceFlippedScreen: + sourceXInScreenSpace = sourceX; + sourceYInScreenSpace = flipScreenYCoordinate(sourceY); + default: + return false; + } + + // Now convert back. + switch (destSpace) { + case NPCoordinateSpacePlugin: + destX = sourceXInScreenSpace - (m_windowFrameInScreenCoordinates.x() + m_viewFrameInWindowCoordinates.x() + m_npWindow.x); + destY = m_windowFrameInScreenCoordinates.y() + m_viewFrameInWindowCoordinates.y() + m_viewFrameInWindowCoordinates.height() - (sourceYInScreenSpace + m_npWindow.y); + break; + case NPCoordinateSpaceWindow: + destX = sourceXInScreenSpace - m_windowFrameInScreenCoordinates.x(); + destY = sourceYInScreenSpace - m_windowFrameInScreenCoordinates.y(); + break; + case NPCoordinateSpaceFlippedWindow: + destX = sourceXInScreenSpace - m_windowFrameInScreenCoordinates.x(); + destY = sourceYInScreenSpace - m_windowFrameInScreenCoordinates.y(); + destY = m_windowFrameInScreenCoordinates.height() - destY; + break; + case NPCoordinateSpaceScreen: + destX = sourceXInScreenSpace; + destY = sourceYInScreenSpace; + break; + case NPCoordinateSpaceFlippedScreen: + destX = sourceXInScreenSpace; + destY = flipScreenYCoordinate(sourceYInScreenSpace); + break; + default: + return false; + } + + return true; +} + +#ifndef NP_NO_CARBON +typedef HashMap<WindowRef, NetscapePlugin*> WindowMap; + +static WindowMap& windowMap() +{ + DEFINE_STATIC_LOCAL(WindowMap, windowMap, ()); + + return windowMap; +} +#endif + +bool NetscapePlugin::platformPostInitialize() +{ + if (m_drawingModel == static_cast<NPDrawingModel>(-1)) { +#ifndef NP_NO_QUICKDRAW + // Default to QuickDraw if the plugin did not specify a drawing model. + m_drawingModel = NPDrawingModelQuickDraw; +#else + // QuickDraw is not available, so we can't default to it. Instead, default to CoreGraphics. + m_drawingModel = NPDrawingModelCoreGraphics; +#endif + } + + if (m_eventModel == static_cast<NPEventModel>(-1)) { + // If the plug-in did not specify a drawing model we default to Carbon when it is available. +#ifndef NP_NO_CARBON + m_eventModel = NPEventModelCarbon; +#else + m_eventModel = NPEventModelCocoa; +#endif // NP_NO_CARBON + } + +#if !defined(NP_NO_CARBON) && !defined(NP_NO_QUICKDRAW) + // The CA drawing model does not work with the Carbon event model. + if (m_drawingModel == NPDrawingModelCoreAnimation && m_eventModel == NPEventModelCarbon) + return false; + + // The Cocoa event model does not work with the QuickDraw drawing model. + if (m_eventModel == NPEventModelCocoa && m_drawingModel == NPDrawingModelQuickDraw) + return false; +#endif + +#ifndef NP_NO_QUICKDRAW + // Right now we don't support the QuickDraw drawing model at all + if (m_drawingModel == NPDrawingModelQuickDraw) + return false; +#endif + + if (m_drawingModel == NPDrawingModelCoreAnimation) { + void* value = 0; + // Get the Core Animation layer. + if (NPP_GetValue(NPPVpluginCoreAnimationLayer, &value) == NPERR_NO_ERROR && value) { + ASSERT(!m_pluginLayer); + m_pluginLayer = reinterpret_cast<CALayer *>(value); + } + } + +#ifndef NP_NO_CARBON + if (m_eventModel == NPEventModelCarbon) { + // Initialize the fake Carbon window. + ::Rect bounds = { 0, 0, 0, 0 }; + CreateNewWindow(kDocumentWindowClass, kWindowNoTitleBarAttribute, &bounds, reinterpret_cast<WindowRef*>(&m_npCGContext.window)); + ASSERT(m_npCGContext.window); + + // FIXME: Disable the backing store. + + m_npWindow.window = &m_npCGContext; + + ASSERT(!windowMap().contains(windowRef())); + windowMap().set(windowRef(), this); + + // Start the null event timer. + // FIXME: Throttle null events when the plug-in isn't visible on screen. + m_nullEventTimer.startRepeating(nullEventIntervalActive); + } +#endif + + return true; +} + +void NetscapePlugin::platformDestroy() +{ +#ifndef NP_NO_CARBON + if (m_eventModel == NPEventModelCarbon) { + if (WindowRef window = windowRef()) { + // Destroy the fake Carbon window. + DisposeWindow(window); + + ASSERT(windowMap().contains(window)); + windowMap().remove(window); + } + + // Stop the null event timer. + m_nullEventTimer.stop(); + } +#endif +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ +} + +static inline NPCocoaEvent initializeEvent(NPCocoaEventType type) +{ + NPCocoaEvent event; + + event.type = type; + event.version = 0; + + return event; +} + +#ifndef NP_NO_CARBON +NetscapePlugin* NetscapePlugin::netscapePluginFromWindow(WindowRef windowRef) +{ + return windowMap().get(windowRef); +} + +WindowRef NetscapePlugin::windowRef() const +{ + ASSERT(m_eventModel == NPEventModelCarbon); + + return reinterpret_cast<WindowRef>(m_npCGContext.window); +} + +unsigned NetscapePlugin::buttonState() +{ + return buttonStateFromLastMouseEvent; +} + +static inline EventRecord initializeEventRecord(EventKind eventKind) +{ + EventRecord eventRecord; + + eventRecord.what = eventKind; + eventRecord.message = 0; + eventRecord.when = TickCount(); + eventRecord.where = Point(); + eventRecord.modifiers = 0; + + return eventRecord; +} + +static bool anyMouseButtonIsDown(const WebEvent& event) +{ + if (event.type() == WebEvent::MouseDown) + return true; + + if (event.type() == WebEvent::MouseMove && static_cast<const WebMouseEvent&>(event).button() != WebMouseEvent::NoButton) + return true; + + return false; +} + +static bool rightMouseButtonIsDown(const WebEvent& event) +{ + if (event.type() == WebEvent::MouseDown && static_cast<const WebMouseEvent&>(event).button() == WebMouseEvent::RightButton) + return true; + + if (event.type() == WebEvent::MouseMove && static_cast<const WebMouseEvent&>(event).button() == WebMouseEvent::RightButton) + return true; + + return false; +} + +static EventModifiers modifiersForEvent(const WebEvent& event) +{ + EventModifiers modifiers = 0; + + // We only want to set the btnState if a mouse button is _not_ down. + if (!anyMouseButtonIsDown(event)) + modifiers |= btnState; + + if (event.metaKey()) + modifiers |= cmdKey; + + if (event.shiftKey()) + modifiers |= shiftKey; + + if (event.altKey()) + modifiers |= optionKey; + + // Set controlKey if the control key is down or the right mouse button is down. + if (event.controlKey() || rightMouseButtonIsDown(event)) + modifiers |= controlKey; + + return modifiers; +} + +#endif + +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +{ + CGContextRef platformContext = context->platformContext(); + + // Translate the context so that the origin is at the top left corner of the plug-in view. + context->translate(m_frameRect.x(), m_frameRect.y()); + + switch (m_eventModel) { + case NPEventModelCocoa: { + // Don't send draw events when we're using the Core Animation drawing model. + if (m_drawingModel == NPDrawingModelCoreAnimation) + return; + + NPCocoaEvent event = initializeEvent(NPCocoaEventDrawRect); + + event.data.draw.context = platformContext; + event.data.draw.x = dirtyRect.x() - m_frameRect.x(); + event.data.draw.y = dirtyRect.y() - m_frameRect.y(); + event.data.draw.width = dirtyRect.width(); + event.data.draw.height = dirtyRect.height(); + + NPP_HandleEvent(&event); + break; + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + if (platformContext != m_npCGContext.context) { + m_npCGContext.context = platformContext; + callSetWindow(); + } + + EventRecord event = initializeEventRecord(updateEvt); + event.message = reinterpret_cast<unsigned long>(windowRef()); + + NPP_HandleEvent(&event); + break; + } +#endif + + default: + ASSERT_NOT_REACHED(); + } +} + +static uint32_t modifierFlags(const WebEvent& event) +{ + uint32_t modifiers = 0; + + if (event.shiftKey()) + modifiers |= NSShiftKeyMask; + if (event.controlKey()) + modifiers |= NSControlKeyMask; + if (event.altKey()) + modifiers |= NSAlternateKeyMask; + if (event.metaKey()) + modifiers |= NSCommandKeyMask; + + return modifiers; +} + +static int32_t buttonNumber(WebMouseEvent::Button button) +{ + switch (button) { + case WebMouseEvent::NoButton: + case WebMouseEvent::LeftButton: + return 0; + case WebMouseEvent::RightButton: + return 1; + case WebMouseEvent::MiddleButton: + return 2; + } + + ASSERT_NOT_REACHED(); + return -1; +} + +static void fillInCocoaEventFromMouseEvent(NPCocoaEvent& event, const WebMouseEvent& mouseEvent, const WebCore::IntPoint& pluginLocation) +{ + event.data.mouse.modifierFlags = modifierFlags(mouseEvent); + event.data.mouse.pluginX = mouseEvent.position().x() - pluginLocation.x(); + event.data.mouse.pluginY = mouseEvent.position().y() - pluginLocation.y(); + event.data.mouse.buttonNumber = buttonNumber(mouseEvent.button()); + event.data.mouse.clickCount = mouseEvent.clickCount(); + event.data.mouse.deltaX = mouseEvent.deltaX(); + event.data.mouse.deltaY = mouseEvent.deltaY(); + event.data.mouse.deltaZ = mouseEvent.deltaZ(); +} + +static NPCocoaEvent initializeMouseEvent(const WebMouseEvent& mouseEvent, const WebCore::IntPoint& pluginLocation) +{ + NPCocoaEventType eventType; + + switch (mouseEvent.type()) { + case WebEvent::MouseDown: + eventType = NPCocoaEventMouseDown; + break; + case WebEvent::MouseUp: + eventType = NPCocoaEventMouseUp; + break; + case WebEvent::MouseMove: + if (mouseEvent.button() == WebMouseEvent::NoButton) + eventType = NPCocoaEventMouseMoved; + else + eventType = NPCocoaEventMouseDragged; + break; + default: + ASSERT_NOT_REACHED(); + return NPCocoaEvent(); + } + + NPCocoaEvent event = initializeEvent(eventType); + fillInCocoaEventFromMouseEvent(event, mouseEvent, pluginLocation); + return event; +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& mouseEvent) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeMouseEvent(mouseEvent, m_frameRect.location()); + return NPP_HandleEvent(&event); + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + EventKind eventKind = nullEvent; + + switch (mouseEvent.type()) { + case WebEvent::MouseDown: + eventKind = mouseDown; + buttonStateFromLastMouseEvent |= (1 << buttonNumber(mouseEvent.button())); + break; + case WebEvent::MouseUp: + eventKind = mouseUp; + buttonStateFromLastMouseEvent &= ~(1 << buttonNumber(mouseEvent.button())); + break; + case WebEvent::MouseMove: + eventKind = nullEvent; + break; + default: + ASSERT_NOT_REACHED(); + } + + EventRecord event = initializeEventRecord(eventKind); + event.modifiers = modifiersForEvent(mouseEvent); + event.where.h = mouseEvent.globalPosition().x(); + event.where.v = mouseEvent.globalPosition().y(); + + return NPP_HandleEvent(&event); + } +#endif + + default: + ASSERT_NOT_REACHED(); + } + + return false; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& wheelEvent) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeEvent(NPCocoaEventScrollWheel); + + event.data.mouse.modifierFlags = modifierFlags(wheelEvent); + event.data.mouse.pluginX = wheelEvent.position().x() - m_frameRect.x(); + event.data.mouse.pluginY = wheelEvent.position().y() - m_frameRect.y(); + event.data.mouse.buttonNumber = 0; + event.data.mouse.clickCount = 0; + event.data.mouse.deltaX = wheelEvent.delta().width(); + event.data.mouse.deltaY = wheelEvent.delta().height(); + event.data.mouse.deltaZ = 0; + return NPP_HandleEvent(&event); + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: + // Carbon doesn't have wheel events. + break; +#endif + + default: + ASSERT_NOT_REACHED(); + } + + return false; +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& mouseEvent) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeEvent(NPCocoaEventMouseEntered); + + fillInCocoaEventFromMouseEvent(event, mouseEvent, m_frameRect.location()); + return NPP_HandleEvent(&event); + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + EventRecord eventRecord = initializeEventRecord(NPEventType_AdjustCursorEvent); + eventRecord.modifiers = modifiersForEvent(mouseEvent); + + return NPP_HandleEvent(&eventRecord); + } +#endif + + default: + ASSERT_NOT_REACHED(); + } + + return false; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& mouseEvent) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeEvent(NPCocoaEventMouseExited); + + fillInCocoaEventFromMouseEvent(event, mouseEvent, m_frameRect.location()); + return NPP_HandleEvent(&event); + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + EventRecord eventRecord = initializeEventRecord(NPEventType_AdjustCursorEvent); + eventRecord.modifiers = modifiersForEvent(mouseEvent); + + return NPP_HandleEvent(&eventRecord); + } +#endif + + default: + ASSERT_NOT_REACHED(); + } + + return false; +} + +static unsigned modifierFlags(const WebKeyboardEvent& keyboardEvent) +{ + unsigned modifierFlags = 0; + + if (keyboardEvent.shiftKey()) + modifierFlags |= NSShiftKeyMask; + if (keyboardEvent.controlKey()) + modifierFlags |= NSControlKeyMask; + if (keyboardEvent.altKey()) + modifierFlags |= NSAlternateKeyMask; + if (keyboardEvent.metaKey()) + modifierFlags |= NSCommandKeyMask; + + return modifierFlags; +} + +static NPCocoaEvent initializeKeyboardEvent(const WebKeyboardEvent& keyboardEvent) +{ + NPCocoaEventType eventType; + + switch (keyboardEvent.type()) { + case WebEvent::KeyDown: + eventType = NPCocoaEventKeyDown; + break; + case WebEvent::KeyUp: + eventType = NPCocoaEventKeyUp; + break; + default: + ASSERT_NOT_REACHED(); + return NPCocoaEvent(); + } + + NPCocoaEvent event = initializeEvent(eventType); + event.data.key.modifierFlags = modifierFlags(keyboardEvent); + event.data.key.characters = reinterpret_cast<NPNSString*>(static_cast<NSString*>(keyboardEvent.text())); + event.data.key.charactersIgnoringModifiers = reinterpret_cast<NPNSString*>(static_cast<NSString*>(keyboardEvent.unmodifiedText())); + event.data.key.isARepeat = keyboardEvent.isAutoRepeat(); + event.data.key.keyCode = keyboardEvent.nativeVirtualKeyCode(); + + return event; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& keyboardEvent) +{ + bool handled = false; + + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeKeyboardEvent(keyboardEvent); + handled = NPP_HandleEvent(&event); + break; + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + EventKind eventKind = nullEvent; + + switch (keyboardEvent.type()) { + case WebEvent::KeyDown: + eventKind = keyboardEvent.isAutoRepeat() ? autoKey : keyDown; + break; + case WebEvent::KeyUp: + eventKind = keyUp; + break; + default: + ASSERT_NOT_REACHED(); + } + + EventRecord event = initializeEventRecord(eventKind); + event.modifiers = modifiersForEvent(keyboardEvent); + event.message = keyboardEvent.nativeVirtualKeyCode() << 8 | keyboardEvent.macCharCode(); + handled = NPP_HandleEvent(&event); + break; + } +#endif + + default: + ASSERT_NOT_REACHED(); + } + + // Most plug-ins simply return true for all keyboard events, even those that aren't handled. + // This leads to bugs such as <rdar://problem/8740926>. We work around this by returning false + // if the keyboard event has the command modifier pressed. + if (keyboardEvent.metaKey()) + return false; + + return handled; +} + +void NetscapePlugin::platformSetFocus(bool hasFocus) +{ + m_pluginHasFocus = hasFocus; + m_pluginController->setComplexTextInputEnabled(m_pluginHasFocus && m_windowHasFocus); + + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeEvent(NPCocoaEventFocusChanged); + + event.data.focus.hasFocus = hasFocus; + NPP_HandleEvent(&event); + break; + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + EventRecord event = initializeEventRecord(hasFocus ? NPEventType_GetFocusEvent : NPEventType_LoseFocusEvent); + + NPP_HandleEvent(&event); + break; + } +#endif + + default: + ASSERT_NOT_REACHED(); + } +} + +void NetscapePlugin::windowFocusChanged(bool hasFocus) +{ + m_windowHasFocus = hasFocus; + m_pluginController->setComplexTextInputEnabled(m_pluginHasFocus && m_windowHasFocus); + + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeEvent(NPCocoaEventWindowFocusChanged); + + event.data.focus.hasFocus = hasFocus; + NPP_HandleEvent(&event); + break; + } + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + HiliteWindow(windowRef(), hasFocus); + if (hasFocus) + SetUserFocusWindow(windowRef()); + + EventRecord event = initializeEventRecord(activateEvt); + event.message = reinterpret_cast<unsigned long>(windowRef()); + if (hasFocus) + event.modifiers |= activeFlag; + + NPP_HandleEvent(&event); + break; + } +#endif + + default: + ASSERT_NOT_REACHED(); + } +} + +#ifndef NP_NO_CARBON +static Rect computeFakeWindowBoundsRect(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) +{ + // Carbon global coordinates has the origin set at the top left corner of the main viewing screen, so we want to flip the y coordinate. + CGFloat maxY = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]); + + int flippedWindowFrameYCoordinate = maxY - windowFrameInScreenCoordinates.bottom(); + int flippedViewFrameYCoordinate = windowFrameInScreenCoordinates.height() - viewFrameInWindowCoordinates.bottom(); + + Rect bounds; + + bounds.top = flippedWindowFrameYCoordinate + flippedViewFrameYCoordinate; + bounds.left = windowFrameInScreenCoordinates.x(); + bounds.right = bounds.left + viewFrameInWindowCoordinates.width(); + bounds.bottom = bounds.top + viewFrameInWindowCoordinates.height(); + + return bounds; +} +#endif + +void NetscapePlugin::windowAndViewFramesChanged(const IntRect& windowFrameInScreenCoordinates, const IntRect& viewFrameInWindowCoordinates) +{ + m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates; + m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates; + + switch (m_eventModel) { + case NPEventModelCocoa: + // Nothing to do. + break; + +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + Rect bounds = computeFakeWindowBoundsRect(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates); + + ::SetWindowBounds(windowRef(), kWindowStructureRgn, &bounds); + break; + } +#endif + + default: + ASSERT_NOT_REACHED(); + } +} + +void NetscapePlugin::windowVisibilityChanged(bool) +{ + // FIXME: Implement. +} + +uint64_t NetscapePlugin::pluginComplexTextInputIdentifier() const +{ + // This is never called for NetscapePlugin. + ASSERT_NOT_REACHED(); + return 0; +} + + +#ifndef NP_NO_CARBON +static bool convertStringToKeyCodes(const String& string, ScriptCode scriptCode, Vector<UInt8>& keyCodes) +{ + // Create the mapping. + UnicodeMapping mapping; + + if (GetTextEncodingFromScriptInfo(scriptCode, kTextLanguageDontCare, kTextRegionDontCare, &mapping.otherEncoding) != noErr) + return false; + + mapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault, kTextEncodingDefaultVariant, kTextEncodingDefaultFormat); + mapping.mappingVersion = kUnicodeUseLatestMapping; + + // Create the converter + UnicodeToTextInfo textInfo; + + if (CreateUnicodeToTextInfo(&mapping, &textInfo) != noErr) + return false; + + ByteCount inputLength = string.length() * sizeof(UniChar); + ByteCount inputRead; + ByteCount outputLength; + ByteCount maxOutputLength = string.length() * sizeof(UniChar); + + Vector<UInt8> outputData(maxOutputLength); + OSStatus status = ConvertFromUnicodeToText(textInfo, inputLength, string.characters(), kNilOptions, 0, 0, 0, 0, maxOutputLength, &inputRead, &outputLength, outputData.data()); + + DisposeUnicodeToTextInfo(&textInfo); + + if (status != noErr) + return false; + + outputData.swap(keyCodes); + return true; +} +#endif + +void NetscapePlugin::sendComplexTextInput(const String& textInput) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + NPCocoaEvent event = initializeEvent(NPCocoaEventTextInput); + event.data.text.text = reinterpret_cast<NPNSString*>(static_cast<NSString*>(textInput)); + NPP_HandleEvent(&event); + break; + } +#ifndef NP_NO_CARBON + case NPEventModelCarbon: { + ScriptCode scriptCode = WKGetScriptCodeFromCurrentKeyboardInputSource(); + Vector<UInt8> keyCodes; + + if (!convertStringToKeyCodes(textInput, scriptCode, keyCodes)) + return; + + // Set the script code as the keyboard script. Normally Carbon does this whenever the input source changes. + // However, this is only done for the process that has the keyboard focus. We cheat and do it here instead. + SetScriptManagerVariable(smKeyScript, scriptCode); + + EventRecord event = initializeEventRecord(keyDown); + event.modifiers = 0; + + for (size_t i = 0; i < keyCodes.size(); i++) { + event.message = keyCodes[i]; + NPP_HandleEvent(&event); + } + break; + } +#endif + default: + ASSERT_NOT_REACHED(); + } +} + +PlatformLayer* NetscapePlugin::pluginLayer() +{ + return static_cast<PlatformLayer*>(m_pluginLayer.get()); +} + +#ifndef NP_NO_CARBON +void NetscapePlugin::nullEventTimerFired() +{ + EventRecord event = initializeEventRecord(nullEvent); + + event.message = 0; + CGPoint mousePosition; + HIGetMousePosition(kHICoordSpaceScreenPixel, 0, &mousePosition); + event.where.h = mousePosition.x; + event.where.v = mousePosition.y; + + event.modifiers = GetCurrentKeyModifiers(); + if (!Button()) + event.modifiers |= btnState; + + NPP_HandleEvent(&event); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm new file mode 100644 index 0000000..6ecf7b9 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm @@ -0,0 +1,49 @@ +/* + * 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. + */ + +#if ENABLE(PLUGIN_PROCESS) + +#include "PluginProxy.h" + +#include <WebKitSystemInterface.h> + +namespace WebKit { + +PlatformLayer* PluginProxy::pluginLayer() +{ + if (!m_pluginLayer && m_remoteLayerClientID) + m_pluginLayer = WKMakeRenderLayer(m_remoteLayerClientID); + + return m_pluginLayer.get(); +} + +bool PluginProxy::needsBackingStore() const +{ + return !m_remoteLayerClientID; +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp new file mode 100644 index 0000000..77efc01 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 University of Szeged + * + * 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 "NetscapePlugin.h" + +#include "NotImplemented.h" +#include "WebEvent.h" +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +bool NetscapePlugin::platformPostInitialize() +{ + notImplemented(); + return true; +} + +void NetscapePlugin::platformDestroy() +{ + notImplemented(); +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + notImplemented(); +} + +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +{ + notImplemented(); +} + +NPEvent toNP(const WebMouseEvent& event) +{ +#if OS(SYMBIAN) + NPEvent npEvent = QEvent(QEvent::None); +#else + NPEvent npEvent = NPEvent(); +#endif + + notImplemented(); + + return npEvent; +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformSetFocus(bool) +{ + notImplemented(); +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&) +{ + notImplemented(); + return false; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp new file mode 100644 index 0000000..930f87b --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp @@ -0,0 +1,293 @@ +/* + * 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 "NetscapePlugin.h" + +#include "NotImplemented.h" +#include "PluginController.h" +#include "WebEvent.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/LocalWindowsContext.h> + +using namespace WebCore; + +extern "C" HINSTANCE gInstance; + +namespace WebKit { + +static LPCWSTR windowClassName = L"org.webkit.NetscapePluginWindow"; + +static void registerPluginView() +{ + static bool didRegister; + if (didRegister) + return; + didRegister = true; + + WNDCLASSW windowClass = {0}; + windowClass.style = CS_DBLCLKS; + windowClass.lpfnWndProc = ::DefWindowProcW; + windowClass.hInstance = gInstance; + windowClass.hCursor = ::LoadCursorW(0, IDC_ARROW); + windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1); + windowClass.lpszClassName = windowClassName; + + ::RegisterClassW(&windowClass); +} + +HWND NetscapePlugin::containingWindow() const +{ + return m_pluginController->nativeParentWindow(); +} + +bool NetscapePlugin::platformPostInitialize() +{ + if (!m_isWindowed) { + m_window = 0; + return true; + } + + registerPluginView(); + + m_window = ::CreateWindowExW(0, windowClassName, 0, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, containingWindow(), 0, 0, 0); + if (!m_window) + return false; + + // FIXME: Do we need to pass our window to setPlatformWidget? + // FIXME: WebCore::PluginView sets the window proc to DefWindowProcA here for Shockwave Director. + + m_npWindow.type = NPWindowTypeWindow; + m_npWindow.window = m_window; + + return true; +} + +void NetscapePlugin::platformDestroy() +{ + if (!m_isWindowed) { + ASSERT(!m_window); + return; + } + + if (!::IsWindow(m_window)) + return; + ::DestroyWindow(m_window); +} + +bool NetscapePlugin::platformInvalidate(const IntRect& invalidRect) +{ + if (!m_isWindowed) + return false; + + RECT rect = invalidRect; + ::InvalidateRect(m_window, &rect, FALSE); + return true; +} + +enum RedrawOrNot { DoNotRedraw, Redraw }; +static void setWindowRegion(HWND window, PassOwnPtr<HRGN> popRegion, RedrawOrNot redrawOrNot) +{ + OwnPtr<HRGN> region = popRegion; + + if (!::SetWindowRgn(window, region.get(), redrawOrNot == Redraw)) + return; + + // Windows owns the region now. + region.leakPtr(); +} + +void NetscapePlugin::platformGeometryDidChange() +{ + if (!m_isWindowed) + return; + + IntRect clipRectInPluginWindowCoordinates = m_clipRect; + clipRectInPluginWindowCoordinates.move(-m_frameRect.x(), -m_frameRect.y()); + + OwnPtr<HRGN> clipRegion = adoptPtr(::CreateRectRgn(clipRectInPluginWindowCoordinates.x(), clipRectInPluginWindowCoordinates.y(), clipRectInPluginWindowCoordinates.right(), clipRectInPluginWindowCoordinates.bottom())); + setWindowRegion(m_window, clipRegion.release(), Redraw); + + // FIXME: We should only update the size here and let the UI process update our position so + // that we can keep our position in sync when scrolling, etc. + ::MoveWindow(m_window, m_frameRect.x(), m_frameRect.y(), m_frameRect.width(), m_frameRect.height(), TRUE); +} + +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +{ + // FIXME: Call SetWindow here if we haven't called it yet (see r59904). + + if (m_isWindowed) { + // FIXME: Paint windowed plugins into context if context->shouldIncludeChildWindows() is true. + return; + } + + // FIXME: Support transparent plugins. + LocalWindowsContext windowsContext(context, dirtyRect, false); + + m_npWindow.type = NPWindowTypeDrawable; + m_npWindow.window = windowsContext.hdc(); + + WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 }; + + windowpos.x = m_frameRect.x(); + windowpos.y = m_frameRect.y(); + windowpos.cx = m_frameRect.width(); + windowpos.cy = m_frameRect.height(); + + NPEvent npEvent; + npEvent.event = WM_WINDOWPOSCHANGED; + npEvent.wParam = 0; + npEvent.lParam = reinterpret_cast<uintptr_t>(&windowpos); + + NPP_HandleEvent(&npEvent); + + callSetWindow(); + + RECT dirtyWinRect = dirtyRect; + + npEvent.event = WM_PAINT; + npEvent.wParam = reinterpret_cast<uintptr_t>(windowsContext.hdc()); + npEvent.lParam = reinterpret_cast<uintptr_t>(&dirtyWinRect); + + NPP_HandleEvent(&npEvent); +} + +NPEvent toNP(const WebMouseEvent& event) +{ + NPEvent npEvent; + + npEvent.wParam = 0; + if (event.controlKey()) + npEvent.wParam |= MK_CONTROL; + if (event.shiftKey()) + npEvent.wParam |= MK_SHIFT; + + npEvent.lParam = MAKELPARAM(event.position().x(), event.position().y()); + + switch (event.type()) { + case WebEvent::MouseMove: + npEvent.event = WM_MOUSEMOVE; + switch (event.button()) { + case WebMouseEvent::LeftButton: + npEvent.wParam |= MK_LBUTTON; + break; + case WebMouseEvent::MiddleButton: + npEvent.wParam |= MK_MBUTTON; + break; + case WebMouseEvent::RightButton: + npEvent.wParam |= MK_RBUTTON; + break; + case WebMouseEvent::NoButton: + break; + } + break; + case WebEvent::MouseDown: + switch (event.button()) { + case WebMouseEvent::LeftButton: + npEvent.event = WM_LBUTTONDOWN; + break; + case WebMouseEvent::MiddleButton: + npEvent.event = WM_MBUTTONDOWN; + break; + case WebMouseEvent::RightButton: + npEvent.event = WM_RBUTTONDOWN; + break; + case WebMouseEvent::NoButton: + ASSERT_NOT_REACHED(); + break; + } + break; + case WebEvent::MouseUp: + switch (event.button()) { + case WebMouseEvent::LeftButton: + npEvent.event = WM_LBUTTONUP; + break; + case WebMouseEvent::MiddleButton: + npEvent.event = WM_MBUTTONUP; + break; + case WebMouseEvent::RightButton: + npEvent.event = WM_RBUTTONUP; + break; + case WebMouseEvent::NoButton: + ASSERT_NOT_REACHED(); + break; + } + break; + default: + ASSERT_NOT_REACHED(); + break; + } + + return npEvent; +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformSetFocus(bool) +{ + notImplemented(); +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&) +{ + notImplemented(); + return false; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.cpp b/Source/WebKit2/WebProcess/Plugins/Plugin.cpp new file mode 100644 index 0000000..32ad92d --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.cpp @@ -0,0 +1,76 @@ +/* + * 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 "Plugin.h" + +#include "WebCoreArgumentCoders.h" + +using namespace WebCore; + +namespace WebKit { + +void Plugin::Parameters::encode(CoreIPC::ArgumentEncoder* encoder) const +{ + encoder->encode(url.string()); + encoder->encode(names); + encoder->encode(values); + encoder->encode(mimeType); + encoder->encode(loadManually); +} + +bool Plugin::Parameters::decode(CoreIPC::ArgumentDecoder* decoder, Parameters& parameters) +{ + String urlString; + if (!decoder->decode(urlString)) + return false; + // FIXME: We can't assume that the url passed in here is valid. + parameters.url = KURL(ParsedURLString, urlString); + + if (!decoder->decode(parameters.names)) + return false; + if (!decoder->decode(parameters.values)) + return false; + if (!decoder->decode(parameters.mimeType)) + return false; + if (!decoder->decode(parameters.loadManually)) + return false; + + if (parameters.names.size() != parameters.values.size()) { + decoder->markInvalid(); + return false; + } + + return true; +} + +Plugin::Plugin() +{ +} + +Plugin::~Plugin() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.h b/Source/WebKit2/WebProcess/Plugins/Plugin.h new file mode 100644 index 0000000..6f20159 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.h @@ -0,0 +1,174 @@ +/* + * 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. + */ + +#ifndef Plugin_h +#define Plugin_h + +#include <WebCore/GraphicsLayer.h> +#include <WebCore/KURL.h> +#include <wtf/RefCounted.h> +#include <wtf/Vector.h> + +struct NPObject; + +namespace CoreIPC { + class ArgumentEncoder; + class ArgumentDecoder; +} + +namespace WebCore { + class GraphicsContext; + class IntRect; +} + +namespace WebKit { + +class WebKeyboardEvent; +class WebMouseEvent; +class WebWheelEvent; + +class PluginController; + +class Plugin : public RefCounted<Plugin> { +public: + struct Parameters { + WebCore::KURL url; + Vector<String> names; + Vector<String> values; + String mimeType; + bool loadManually; + + void encode(CoreIPC::ArgumentEncoder*) const; + static bool decode(CoreIPC::ArgumentDecoder*, Parameters&); + }; + + virtual ~Plugin(); + + // Initializes the plug-in. If the plug-in fails to initialize this should return false. + virtual bool initialize(PluginController*, const Parameters&) = 0; + + // Destroys the plug-in. + virtual void destroy() = 0; + + // Tells the plug-in to paint itself into the given graphics context. The passed-in context and + // dirty rect are in window coordinates. The context is saved/restored by the caller. + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect) = 0; + +#if PLATFORM(MAC) + // If a plug-in is using the Core Animation drawing model, this returns its plug-in layer. + virtual PlatformLayer* pluginLayer() = 0; +#endif + + // Tells the plug-in that either the plug-ins frame rect or its clip rect has changed. Both rects are in window coordinates. + virtual void geometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect) = 0; + + // Tells the plug-in that a frame load request that the plug-in made by calling PluginController::loadURL has finished. + virtual void frameDidFinishLoading(uint64_t requestID) = 0; + + // Tells the plug-in that a frame load request that the plug-in made by calling PluginController::loadURL has failed. + virtual void frameDidFail(uint64_t requestID, bool wasCancelled) = 0; + + // Tells the plug-in that a request to evaluate JavaScript (using PluginController::loadURL) has been fulfilled and passes + // back the result. If evaluating the script failed, result will be null. + virtual void didEvaluateJavaScript(uint64_t requestID, const String& requestURLString, const String& result) = 0; + + // Tells the plug-in that a stream has received its HTTP response. + virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers) = 0; + + // Tells the plug-in that a stream did receive data. + virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) = 0; + + // Tells the plug-in that a stream has finished loading. + virtual void streamDidFinishLoading(uint64_t streamID) = 0; + + // Tells the plug-in that a stream has failed to load, either because of network errors or because the load was cancelled. + virtual void streamDidFail(uint64_t streamID, bool wasCancelled) = 0; + + // Tells the plug-in that the manual stream has received its HTTP response. + virtual void manualStreamDidReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers) = 0; + + // Tells the plug-in that the manual stream did receive data. + virtual void manualStreamDidReceiveData(const char* bytes, int length) = 0; + + // Tells the plug-in that a stream has finished loading. + virtual void manualStreamDidFinishLoading() = 0; + + // Tells the plug-in that a stream has failed to load, either because of network errors or because the load was cancelled. + virtual void manualStreamDidFail(bool wasCancelled) = 0; + + // Tells the plug-in to handle the passed in mouse event. The plug-in should return true if it processed the event. + virtual bool handleMouseEvent(const WebMouseEvent&) = 0; + + // Tells the plug-in to handle the passed in wheel event. The plug-in should return true if it processed the event. + virtual bool handleWheelEvent(const WebWheelEvent&) = 0; + + // Tells the plug-in to handle the passed in mouse over event. The plug-in should return true if it processed the event. + virtual bool handleMouseEnterEvent(const WebMouseEvent&) = 0; + + // Tells the plug-in to handle the passed in mouse leave event. The plug-in should return true if it processed the event. + virtual bool handleMouseLeaveEvent(const WebMouseEvent&) = 0; + + // Tells the plug-in to handle the passed in keyboard event. The plug-in should return true if it processed the event. + virtual bool handleKeyboardEvent(const WebKeyboardEvent&) = 0; + + // Tells the plug-in about focus changes. + virtual void setFocus(bool) = 0; + + // Get the NPObject that corresponds to the plug-in's scriptable object. Returns a retained object. + virtual NPObject* pluginScriptableNPObject() = 0; + +#if PLATFORM(MAC) + // Tells the plug-in about window focus changes. + virtual void windowFocusChanged(bool) = 0; + + // Tells the plug-in about window and plug-in frame changes. + virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) = 0; + + // Tells the plug-in about window visibility changes. + virtual void windowVisibilityChanged(bool) = 0; + + // Get the per complex text input identifier. + virtual uint64_t pluginComplexTextInputIdentifier() const = 0; + + // Send the complex text input to the plug-in. + virtual void sendComplexTextInput(const String& textInput) = 0; +#endif + + // Called when the private browsing state for this plug-in changes. + virtual void privateBrowsingStateChanged(bool) = 0; + + // Returns the plug-in controller for this plug-in. + // FIXME: We could just have the controller be a member variable of Plugin. + virtual PluginController* controller() = 0; + +protected: + Plugin(); +}; + +} // namespace WebKit + +#endif // Plugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginController.h b/Source/WebKit2/WebProcess/Plugins/PluginController.h new file mode 100644 index 0000000..06cf2d7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginController.h @@ -0,0 +1,114 @@ +/* + * 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. + */ + +#ifndef PluginController_h +#define PluginController_h + +#include <wtf/Forward.h> + +struct NPObject; +typedef struct _NPVariant NPVariant; + +namespace WebCore { + class HTTPHeaderMap; + class IntRect; + class KURL; +} + +namespace WebKit { + +class PluginController { +public: + // Tells the controller that the plug-in wants the given rect to be repainted. The rect is in the plug-in's coordinate system. + virtual void invalidate(const WebCore::IntRect&) = 0; + + // Returns the user agent string. + virtual String userAgent() = 0; + + // Loads the given URL and associates it with the request ID. + // + // If a target is specified, then the URL will be loaded in the window or frame that the target refers to. + // Once the URL finishes loading, Plugin::frameDidFinishLoading will be called with the given requestID. If the URL + // fails to load, Plugin::frameDidFailToLoad will be called. + // + // If the URL is a JavaScript URL, the JavaScript code will be evaluated and the result sent back using Plugin::didEvaluateJavaScript. + virtual void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, + const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) = 0; + + /// Cancels the load of a stream that was requested by loadURL. + virtual void cancelStreamLoad(uint64_t streamID) = 0; + + // Cancels the load of the manual stream. + virtual void cancelManualStreamLoad() = 0; + + // Get the NPObject that corresponds to the window JavaScript object. Returns a retained object. + virtual NPObject* windowScriptNPObject() = 0; + + // Get the NPObject that corresponds to the plug-in's element. Returns a retained object. + virtual NPObject* pluginElementNPObject() = 0; + + // Evaluates the given script string in the context of the given NPObject. + virtual bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups) = 0; + + // Set the statusbar text. + virtual void setStatusbarText(const String&) = 0; + +#if USE(ACCELERATED_COMPOSITING) + // Return whether accelerated compositing is enabled. + virtual bool isAcceleratedCompositingEnabled() = 0; +#endif + + // Tells the controller that the plug-in process has crashed. + virtual void pluginProcessCrashed() = 0; + +#if PLATFORM(WIN) + // The window to use as the parent of the plugin's window. + virtual HWND nativeParentWindow() = 0; +#endif + +#if PLATFORM(MAC) + // Tells the controller that complex text input be enabled or disabled for the plug-in. + virtual void setComplexTextInputEnabled(bool) = 0; +#endif + + // Returns the proxies for the given URL or null on failure. + virtual String proxiesForURL(const String&) = 0; + + // Returns the cookies for the given URL or null on failure. + virtual String cookiesForURL(const String&) = 0; + + // Sets the cookies for the given URL. + virtual void setCookiesForURL(const String& urlString, const String& cookieString) = 0; + + // Returns whether private browsing is enabled. + virtual bool isPrivateBrowsingEnabled() = 0; + +protected: + virtual ~PluginController() { } +}; + +} // namespace WebKit + +#endif // PluginController_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp new file mode 100644 index 0000000..7c09e56 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#if ENABLE(PLUGIN_PROCESS) + +#include "PluginProcessConnection.h" + +#include "NPRemoteObjectMap.h" +#include "PluginProcessConnectionManager.h" +#include "PluginProxy.h" +#include "WebProcess.h" + +namespace WebKit { + +PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier) + : m_pluginProcessConnectionManager(pluginProcessConnectionManager) + , m_pluginPath(pluginPath) +{ + m_connection = CoreIPC::Connection::createClientConnection(connectionIdentifier, this, WebProcess::shared().runLoop()); + m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get()); + + m_connection->open(); +} + +PluginProcessConnection::~PluginProcessConnection() +{ + ASSERT(!m_connection); + ASSERT(!m_npRemoteObjectMap); +} + +void PluginProcessConnection::addPluginProxy(PluginProxy* plugin) +{ + ASSERT(!m_plugins.contains(plugin->pluginInstanceID())); + m_plugins.set(plugin->pluginInstanceID(), plugin); +} + +void PluginProcessConnection::removePluginProxy(PluginProxy* plugin) +{ + ASSERT(m_plugins.contains(plugin->pluginInstanceID())); + m_plugins.remove(plugin->pluginInstanceID()); + + if (!m_plugins.isEmpty()) + return; + + // Invalidate our remote object map. + m_npRemoteObjectMap->invalidate(); + m_npRemoteObjectMap = 0; + + // We have no more plug-ins, invalidate the connection to the plug-in process. + ASSERT(m_connection); + m_connection->invalidate(); + m_connection = nullptr; + + // This will cause us to be deleted. + m_pluginProcessConnectionManager->removePluginProcessConnection(this); +} + +void PluginProcessConnection::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (arguments->destinationID()) { + if (PluginProxy* pluginProxy = m_plugins.get(arguments->destinationID())) + pluginProxy->didReceivePluginProxyMessage(connection, messageID, arguments); + return; + } + + ASSERT_NOT_REACHED(); +} + +CoreIPC::SyncReplyMode PluginProcessConnection::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply) +{ + if (messageID.is<CoreIPC::MessageClassNPObjectMessageReceiver>()) + return m_npRemoteObjectMap->didReceiveSyncMessage(connection, messageID, arguments, reply); + + if (PluginProxy* pluginProxy = m_plugins.get(arguments->destinationID())) + return pluginProxy->didReceiveSyncPluginProxyMessage(connection, messageID, arguments, reply); + + ASSERT_NOT_REACHED(); + return CoreIPC::AutomaticReply; +} + +void PluginProcessConnection::didClose(CoreIPC::Connection*) +{ + // The plug-in process must have crashed. + for (HashMap<uint64_t, PluginProxy*>::const_iterator::Values it = m_plugins.begin().values(), end = m_plugins.end().values(); it != end; ++it) { + PluginProxy* pluginProxy = (*it); + + pluginProxy->pluginProcessCrashed(); + } +} + +void PluginProcessConnection::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID) +{ +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h new file mode 100644 index 0000000..76e2315 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h @@ -0,0 +1,86 @@ +/* + * 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. + */ + +#ifndef PluginProcessConnection_h +#define PluginProcessConnection_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "Connection.h" +#include "Plugin.h" +#include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> + +// A CoreIPC connection to a plug-in process. + +namespace WebKit { + +class NPRemoteObjectMap; +class PluginProcessConnectionManager; +class PluginProxy; + +class PluginProcessConnection : public RefCounted<PluginProcessConnection>, CoreIPC::Connection::Client { +public: + static PassRefPtr<PluginProcessConnection> create(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier) + { + return adoptRef(new PluginProcessConnection(pluginProcessConnectionManager, pluginPath, connectionIdentifier)); + } + ~PluginProcessConnection(); + + const String& pluginPath() const { return m_pluginPath; } + + CoreIPC::Connection* connection() const { return m_connection.get(); } + + void addPluginProxy(PluginProxy*); + void removePluginProxy(PluginProxy*); + + NPRemoteObjectMap* npRemoteObjectMap() const { return m_npRemoteObjectMap.get(); } + +private: + PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier); + + // CoreIPC::Connection::Client + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + virtual CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + + PluginProcessConnectionManager* m_pluginProcessConnectionManager; + String m_pluginPath; + + // The connection from the web process to the plug-in process. + RefPtr<CoreIPC::Connection> m_connection; + + // The plug-ins. We use a weak reference to the plug-in proxies because the plug-in view holds the strong reference. + HashMap<uint64_t, PluginProxy*> m_plugins; + + RefPtr<NPRemoteObjectMap> m_npRemoteObjectMap; +}; + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginProcessConnection_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp new file mode 100644 index 0000000..99848ef --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#if ENABLE(PLUGIN_PROCESS) + +#include "PluginProcessConnectionManager.h" + +#include "ArgumentDecoder.h" +#include "ArgumentEncoder.h" +#include "MachPort.h" +#include "PluginProcessConnection.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcess.h" +#include "WebProcessProxyMessageKinds.h" +#include <wtf/StdLibExtras.h> + +namespace WebKit { + +PluginProcessConnectionManager& PluginProcessConnectionManager::shared() +{ + DEFINE_STATIC_LOCAL(PluginProcessConnectionManager, pluginProcessConnectionManager, ()); + return pluginProcessConnectionManager; +} + +PluginProcessConnectionManager::PluginProcessConnectionManager() +{ +} + +PluginProcessConnectionManager::~PluginProcessConnectionManager() +{ +} + +PluginProcessConnection* PluginProcessConnectionManager::getPluginProcessConnection(const String& pluginPath) +{ + for (size_t i = 0; i < m_pluginProcessConnections.size(); ++i) { + if (m_pluginProcessConnections[i]->pluginPath() == pluginPath) + return m_pluginProcessConnections[i].get(); + } + + CoreIPC::Connection::Identifier connectionIdentifier; + CoreIPC::MachPort connectionMachPort; + if (!WebProcess::shared().connection()->sendSync(WebProcessProxyLegacyMessage::GetPluginProcessConnection, 0, CoreIPC::In(pluginPath), CoreIPC::Out(connectionMachPort))) + return 0; + + connectionIdentifier = connectionMachPort.port(); + if (!connectionIdentifier) + return 0; + + RefPtr<PluginProcessConnection> pluginProcessConnection = PluginProcessConnection::create(this, pluginPath, connectionIdentifier); + m_pluginProcessConnections.append(pluginProcessConnection); + + return pluginProcessConnection.get(); +} + +void PluginProcessConnectionManager::removePluginProcessConnection(PluginProcessConnection* pluginProcessConnection) +{ + size_t vectorIndex = m_pluginProcessConnections.find(pluginProcessConnection); + ASSERT(vectorIndex != notFound); + + m_pluginProcessConnections.remove(vectorIndex); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h new file mode 100644 index 0000000..d7ba853 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef PluginProcessConnectionManager_h +#define PluginProcessConnectionManager_h + +#if ENABLE(PLUGIN_PROCESS) + +#include <wtf/Forward.h> +#include <wtf/Noncopyable.h> +#include <wtf/Vector.h> + +// Manages plug-in process connections for the given web process. + +namespace WebKit { + +class PluginProcessConnection; + +class PluginProcessConnectionManager : Noncopyable { +public: + static PluginProcessConnectionManager& shared(); + + PluginProcessConnection* getPluginProcessConnection(const String& pluginPath); + void removePluginProcessConnection(PluginProcessConnection*); + +private: + PluginProcessConnectionManager(); + ~PluginProcessConnectionManager(); + + Vector<RefPtr<PluginProcessConnection> > m_pluginProcessConnections; +}; + +} + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginProcessConnectionManager_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp new file mode 100644 index 0000000..f029cbf --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp @@ -0,0 +1,458 @@ +/* + * 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. + */ + +#if ENABLE(PLUGIN_PROCESS) + +#include "PluginProxy.h" + +#include "DataReference.h" +#include "NPRemoteObjectMap.h" +#include "NPRuntimeUtilities.h" +#include "NPVariantData.h" +#include "PluginController.h" +#include "PluginControllerProxyMessages.h" +#include "PluginProcessConnection.h" +#include "PluginProcessConnectionManager.h" +#include "ShareableBitmap.h" +#include "WebCoreArgumentCoders.h" +#include "WebEvent.h" +#include "WebProcessConnectionMessages.h" +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +static uint64_t generatePluginInstanceID() +{ + static uint64_t uniquePluginInstanceID; + return ++uniquePluginInstanceID; +} + +PassRefPtr<PluginProxy> PluginProxy::create(const String& pluginPath) +{ + return adoptRef(new PluginProxy(pluginPath)); +} + +PluginProxy::PluginProxy(const String& pluginPath) + : m_pluginPath(pluginPath) + , m_pluginInstanceID(generatePluginInstanceID()) + , m_pluginController(0) + , m_pluginBackingStoreContainsValidData(false) + , m_isStarted(false) + , m_waitingForPaintInResponseToUpdate(false) + , m_remoteLayerClientID(0) +{ +} + +PluginProxy::~PluginProxy() +{ +} + +void PluginProxy::pluginProcessCrashed() +{ + if (m_pluginController) + m_pluginController->pluginProcessCrashed(); +} + +bool PluginProxy::initialize(PluginController* pluginController, const Parameters& parameters) +{ + ASSERT(!m_pluginController); + ASSERT(pluginController); + + m_pluginController = pluginController; + + ASSERT(!m_connection); + m_connection = PluginProcessConnectionManager::shared().getPluginProcessConnection(m_pluginPath); + + if (!m_connection) + return false; + + // Add the plug-in proxy before creating the plug-in; it needs to be in the map because CreatePlugin + // can call back out to the plug-in proxy. + m_connection->addPluginProxy(this); + + // Ask the plug-in process to create a plug-in. + bool result = false; + + uint32_t remoteLayerClientID = 0; + if (!m_connection->connection()->sendSync(Messages::WebProcessConnection::CreatePlugin(m_pluginInstanceID, parameters, pluginController->userAgent(), pluginController->isPrivateBrowsingEnabled(), pluginController->isAcceleratedCompositingEnabled()), Messages::WebProcessConnection::CreatePlugin::Reply(result, remoteLayerClientID), 0) || !result) { + m_connection->removePluginProxy(this); + return false; + } + + m_remoteLayerClientID = remoteLayerClientID; + m_isStarted = true; + + return true; +} + +void PluginProxy::destroy() +{ + ASSERT(m_isStarted); + + m_connection->connection()->sendSync(Messages::WebProcessConnection::DestroyPlugin(m_pluginInstanceID), Messages::WebProcessConnection::DestroyPlugin::Reply(), 0); + + m_isStarted = false; + m_connection->removePluginProxy(this); +} + +void PluginProxy::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRect) +{ + if (!needsBackingStore() || !m_backingStore) + return; + + if (!m_pluginBackingStoreContainsValidData) { + m_connection->connection()->sendSync(Messages::PluginControllerProxy::PaintEntirePlugin(), Messages::PluginControllerProxy::PaintEntirePlugin::Reply(), m_pluginInstanceID); + + // Blit the plug-in backing store into our own backing store. + OwnPtr<WebCore::GraphicsContext> graphicsContext = m_backingStore->createGraphicsContext(); + + m_pluginBackingStore->paint(*graphicsContext, IntPoint(), IntRect(0, 0, m_frameRect.width(), m_frameRect.height())); + + m_pluginBackingStoreContainsValidData = true; + } + + IntRect dirtyRectInPluginCoordinates = dirtyRect; + dirtyRectInPluginCoordinates.move(-m_frameRect.x(), -m_frameRect.y()); + + m_backingStore->paint(*graphicsContext, dirtyRect.location(), dirtyRectInPluginCoordinates); + + if (m_waitingForPaintInResponseToUpdate) { + m_waitingForPaintInResponseToUpdate = false; + m_connection->connection()->send(Messages::PluginControllerProxy::DidUpdate(), m_pluginInstanceID); + return; + } +} + +void PluginProxy::geometryDidChange(const IntRect& frameRect, const IntRect& clipRect) +{ + ASSERT(m_isStarted); + + m_frameRect = frameRect; + + if (!needsBackingStore()) { + SharedMemory::Handle pluginBackingStoreHandle; + m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(frameRect, clipRect, pluginBackingStoreHandle), m_pluginInstanceID); + return; + } + + bool didUpdateBackingStore = false; + if (!m_backingStore) { + m_backingStore = ShareableBitmap::create(frameRect.size()); + didUpdateBackingStore = true; + } else if (frameRect.size() != m_backingStore->size()) { + // The backing store already exists, just resize it. + if (!m_backingStore->resize(frameRect.size())) + return; + + didUpdateBackingStore = true; + } + + SharedMemory::Handle pluginBackingStoreHandle; + + if (didUpdateBackingStore) { + // Create a new plug-in backing store. + m_pluginBackingStore = ShareableBitmap::createShareable(frameRect.size()); + if (!m_pluginBackingStore) + return; + + // Create a handle to the plug-in backing store so we can send it over. + if (!m_pluginBackingStore->createHandle(pluginBackingStoreHandle)) { + m_pluginBackingStore.clear(); + return; + } + + m_pluginBackingStoreContainsValidData = false; + } + + m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(frameRect, clipRect, pluginBackingStoreHandle), m_pluginInstanceID); +} + +void PluginProxy::frameDidFinishLoading(uint64_t requestID) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::FrameDidFinishLoading(requestID), m_pluginInstanceID); +} + +void PluginProxy::frameDidFail(uint64_t requestID, bool wasCancelled) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::FrameDidFail(requestID, wasCancelled), m_pluginInstanceID); +} + +void PluginProxy::didEvaluateJavaScript(uint64_t requestID, const WTF::String& requestURLString, const WTF::String& result) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::DidEvaluateJavaScript(requestID, requestURLString, result), m_pluginInstanceID); +} + +void PluginProxy::streamDidReceiveResponse(uint64_t streamID, const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveResponse(streamID, responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID); +} + +void PluginProxy::streamDidReceiveData(uint64_t streamID, const char* bytes, int length) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveData(streamID, CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(bytes), length)), m_pluginInstanceID); +} + +void PluginProxy::streamDidFinishLoading(uint64_t streamID) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidFinishLoading(streamID), m_pluginInstanceID); +} + +void PluginProxy::streamDidFail(uint64_t streamID, bool wasCancelled) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidFail(streamID, wasCancelled), m_pluginInstanceID); +} + +void PluginProxy::manualStreamDidReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidReceiveResponse(responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID); +} + +void PluginProxy::manualStreamDidReceiveData(const char* bytes, int length) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidReceiveData(CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(bytes), length)), m_pluginInstanceID); +} + +void PluginProxy::manualStreamDidFinishLoading() +{ + m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidFinishLoading(), m_pluginInstanceID); +} + +void PluginProxy::manualStreamDidFail(bool wasCancelled) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidFail(wasCancelled), m_pluginInstanceID); +} + +bool PluginProxy::handleMouseEvent(const WebMouseEvent& mouseEvent) +{ + bool handled = false; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseEvent(mouseEvent), Messages::PluginControllerProxy::HandleMouseEvent::Reply(handled), m_pluginInstanceID)) + return false; + + return handled; +} + +bool PluginProxy::handleWheelEvent(const WebWheelEvent& wheelEvent) +{ + bool handled = false; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleWheelEvent(wheelEvent), Messages::PluginControllerProxy::HandleWheelEvent::Reply(handled), m_pluginInstanceID)) + return false; + + return handled; +} + +bool PluginProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent) +{ + bool handled = false; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseEnterEvent(mouseEnterEvent), Messages::PluginControllerProxy::HandleMouseEnterEvent::Reply(handled), m_pluginInstanceID)) + return false; + + return handled; +} + +bool PluginProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent) +{ + bool handled = false; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseLeaveEvent(mouseLeaveEvent), Messages::PluginControllerProxy::HandleMouseLeaveEvent::Reply(handled), m_pluginInstanceID)) + return false; + + return handled; +} + +bool PluginProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent) +{ + bool handled = false; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleKeyboardEvent(keyboardEvent), Messages::PluginControllerProxy::HandleKeyboardEvent::Reply(handled), m_pluginInstanceID)) + return false; + + return handled; +} + +void PluginProxy::setFocus(bool hasFocus) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::SetFocus(hasFocus), m_pluginInstanceID); +} + +NPObject* PluginProxy::pluginScriptableNPObject() +{ + uint64_t pluginScriptableNPObjectID = 0; + + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::GetPluginScriptableNPObject(), Messages::PluginControllerProxy::GetPluginScriptableNPObject::Reply(pluginScriptableNPObjectID), m_pluginInstanceID)) + return 0; + + if (!pluginScriptableNPObjectID) + return 0; + + return m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginScriptableNPObjectID); +} + +#if PLATFORM(MAC) +void PluginProxy::windowFocusChanged(bool hasFocus) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::WindowFocusChanged(hasFocus), m_pluginInstanceID); +} + +void PluginProxy::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates), m_pluginInstanceID); +} + +void PluginProxy::windowVisibilityChanged(bool isVisible) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::WindowVisibilityChanged(isVisible), m_pluginInstanceID); +} + +uint64_t PluginProxy::pluginComplexTextInputIdentifier() const +{ + return m_pluginInstanceID; +} + +void PluginProxy::sendComplexTextInput(const String& textInput) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::SendComplexTextInput(textInput), m_pluginInstanceID); +} + +#endif + +void PluginProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::PrivateBrowsingStateChanged(isPrivateBrowsingEnabled), m_pluginInstanceID); +} + +PluginController* PluginProxy::controller() +{ + return m_pluginController; +} + +void PluginProxy::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) +{ + m_pluginController->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups); +} + +void PluginProxy::proxiesForURL(const String& urlString, String& proxyString) +{ + proxyString = m_pluginController->proxiesForURL(urlString); +} + +void PluginProxy::cookiesForURL(const String& urlString, String& cookieString) +{ + cookieString = m_pluginController->cookiesForURL(urlString); +} + +void PluginProxy::setCookiesForURL(const String& urlString, const String& cookieString) +{ + m_pluginController->setCookiesForURL(urlString, cookieString); +} + +void PluginProxy::getWindowScriptNPObject(uint64_t& windowScriptNPObjectID) +{ + NPObject* windowScriptNPObject = m_pluginController->windowScriptNPObject(); + if (!windowScriptNPObject) { + windowScriptNPObjectID = 0; + return; + } + + windowScriptNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(windowScriptNPObject); + releaseNPObject(windowScriptNPObject); +} + +void PluginProxy::getPluginElementNPObject(uint64_t& pluginElementNPObjectID) +{ + NPObject* pluginElementNPObject = m_pluginController->pluginElementNPObject(); + if (!pluginElementNPObject) { + pluginElementNPObjectID = 0; + return; + } + + pluginElementNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginElementNPObject); + releaseNPObject(pluginElementNPObject); +} + +void PluginProxy::evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, bool& returnValue, NPVariantData& resultData) +{ + NPVariant npObjectAsVariant = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(npObjectAsVariantData); + ASSERT(NPVARIANT_IS_OBJECT(npObjectAsVariant)); + + NPVariant result; + returnValue = m_pluginController->evaluate(NPVARIANT_TO_OBJECT(npObjectAsVariant), scriptString, &result, allowPopups); + if (!returnValue) + return; + + // Convert the NPVariant to an NPVariantData. + resultData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(result); + + // And release the result. + releaseNPVariantValue(&result); + + releaseNPVariantValue(&npObjectAsVariant); +} + +void PluginProxy::cancelStreamLoad(uint64_t streamID) +{ + m_pluginController->cancelStreamLoad(streamID); +} + +void PluginProxy::cancelManualStreamLoad() +{ + m_pluginController->cancelManualStreamLoad(); +} + +void PluginProxy::setStatusbarText(const String& statusbarText) +{ + m_pluginController->setStatusbarText(statusbarText); +} + +#if PLATFORM(MAC) +void PluginProxy::setComplexTextInputEnabled(bool complexTextInputEnabled) +{ + m_pluginController->setComplexTextInputEnabled(complexTextInputEnabled); +} +#endif + +void PluginProxy::update(const IntRect& paintedRect) +{ + if (paintedRect == m_frameRect) + m_pluginBackingStoreContainsValidData = true; + + IntRect paintedRectPluginCoordinates = paintedRect; + paintedRectPluginCoordinates.move(-m_frameRect.x(), -m_frameRect.y()); + + if (m_backingStore) { + // Blit the plug-in backing store into our own backing store. + OwnPtr<GraphicsContext> graphicsContext = m_backingStore->createGraphicsContext(); + + m_pluginBackingStore->paint(*graphicsContext, paintedRectPluginCoordinates.location(), + paintedRectPluginCoordinates); + } + + // Ask the controller to invalidate the rect for us. + m_waitingForPaintInResponseToUpdate = true; + m_pluginController->invalidate(paintedRectPluginCoordinates); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h new file mode 100644 index 0000000..2c3b052 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h @@ -0,0 +1,161 @@ +/* + * 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. + */ + +#ifndef PluginProxy_h +#define PluginProxy_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "Connection.h" +#include "Plugin.h" + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#ifdef __OBJC__ +@class CALayer; +#else +class CALayer; +#endif +#endif + +namespace WebCore { + class HTTPHeaderMap; +} + +namespace WebKit { + +class ShareableBitmap; +class NPVariantData; +class PluginProcessConnection; + +class PluginProxy : public Plugin { +public: + static PassRefPtr<PluginProxy> create(const String& pluginPath); + ~PluginProxy(); + + uint64_t pluginInstanceID() const { return m_pluginInstanceID; } + void pluginProcessCrashed(); + + void didReceivePluginProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments); + CoreIPC::SyncReplyMode didReceiveSyncPluginProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + +private: + explicit PluginProxy(const String& pluginPath); + + // Plugin + virtual bool initialize(PluginController*, const Parameters&); + virtual void destroy(); + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); +#if PLATFORM(MAC) + virtual PlatformLayer* pluginLayer(); +#endif + virtual void geometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect); + virtual void frameDidFinishLoading(uint64_t requestID); + virtual void frameDidFail(uint64_t requestID, bool wasCancelled); + virtual void didEvaluateJavaScript(uint64_t requestID, const WTF::String& requestURLString, const WTF::String& result); + virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers); + virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length); + virtual void streamDidFinishLoading(uint64_t streamID); + virtual void streamDidFail(uint64_t streamID, bool wasCancelled); + virtual void manualStreamDidReceiveResponse(const WebCore::KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers); + virtual void manualStreamDidReceiveData(const char* bytes, int length); + virtual void manualStreamDidFinishLoading(); + virtual void manualStreamDidFail(bool wasCancelled); + + virtual bool handleMouseEvent(const WebMouseEvent&); + virtual bool handleWheelEvent(const WebWheelEvent&); + virtual bool handleMouseEnterEvent(const WebMouseEvent&); + virtual bool handleMouseLeaveEvent(const WebMouseEvent&); + virtual bool handleKeyboardEvent(const WebKeyboardEvent&); + virtual void setFocus(bool); + virtual NPObject* pluginScriptableNPObject(); +#if PLATFORM(MAC) + virtual void windowFocusChanged(bool); + virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); + virtual void windowVisibilityChanged(bool); + virtual uint64_t pluginComplexTextInputIdentifier() const; + virtual void sendComplexTextInput(const String& textInput); +#endif + + virtual void privateBrowsingStateChanged(bool); + + virtual PluginController* controller(); + + bool needsBackingStore() const; + + // Message handlers. + void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups); + void update(const WebCore::IntRect& paintedRect); + void proxiesForURL(const String& urlString, String& proxyString); + void cookiesForURL(const String& urlString, String& cookieString); + void setCookiesForURL(const String& urlString, const String& cookieString); + void getWindowScriptNPObject(uint64_t& windowScriptNPObjectID); + void getPluginElementNPObject(uint64_t& pluginElementNPObjectID); + void evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, bool& returnValue, NPVariantData& resultData); + void cancelStreamLoad(uint64_t streamID); + void cancelManualStreamLoad(); + void setStatusbarText(const String& statusbarText); +#if PLATFORM(MAC) + void setComplexTextInputEnabled(bool); +#endif + + String m_pluginPath; + + RefPtr<PluginProcessConnection> m_connection; + uint64_t m_pluginInstanceID; + + PluginController* m_pluginController; + + // The plug-in rect in window coordinates. + WebCore::IntRect m_frameRect; + + // This is the backing store that we paint when we're told to paint. + RefPtr<ShareableBitmap> m_backingStore; + + // This is the shared memory backing store that the plug-in paints into. When the plug-in tells us + // that it's painted something in it, we'll blit from it to our own backing store. + RefPtr<ShareableBitmap> m_pluginBackingStore; + + // Whether all of the plug-in backing store contains valid data. + bool m_pluginBackingStoreContainsValidData; + + bool m_isStarted; + + // Whether we're called invalidate in response to an update call, and are now waiting for a paint call. + bool m_waitingForPaintInResponseToUpdate; + + // The client ID for the CA layer in the plug-in process. Will be 0 if the plug-in is not a CA plug-in. + uint32_t m_remoteLayerClientID; + +#if PLATFORM(MAC) + RetainPtr<CALayer> m_pluginLayer; +#endif +}; + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginProxy_h diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in new file mode 100644 index 0000000..81761ee --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in @@ -0,0 +1,65 @@ +# 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. + +#if ENABLE(PLUGIN_PROCESS) + +messages -> PluginProxy { + # Asks the web process to load a URL. + LoadURL(uint64_t requestID, WTF::String method, WTF::String urlString, WTF::String target, WebCore::HTTPHeaderMap headerFields, Vector<uint8_t> httpBody, bool allowPopups); + + # Called when the plug-in has painted into its backing store. + Update(WebCore::IntRect paintedRect) + + # Returns a PAC style string with proxies for the given URL. + ProxiesForURL(WTF::String urlString) -> (WTF::String proxiesString) + + # Returns the cookies for the given URL. + CookiesForURL(WTF::String urlString) -> (WTF::String cookieString) + + # Sets the cookies for the given URL. + SetCookiesForURL(WTF::String urlString, WTF::String cookieString) + + # Gets a reference to the window NPObject. + GetWindowScriptNPObject() -> (uint64_t windowScriptNPObjectID) + + # Gets a reference to the plug-in element NPObject. + GetPluginElementNPObject() -> (uint64_t pluginElementNPObjectID) + + # Evaluates the given JavaScript string. + Evaluate(WebKit::NPVariantData npObjectAsVariantData, WTF::String scriptString, bool allowPopups) -> (bool returnValue, WebKit::NPVariantData resultData) + + # Cancels the given stream load. + CancelStreamLoad(uint64_t streamID) + + # Cancel the manual stream load. + CancelManualStreamLoad() + + # Set the status bar text. + SetStatusbarText(WTF::String statusbarText) + +#if PLATFORM(MAC) + # Change whether complext text input is enabled for this plug-in. + SetComplexTextInputEnabled(bool complexTextInputEnabled) +#endif +} + +#endif diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp new file mode 100644 index 0000000..00271c1 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp @@ -0,0 +1,1013 @@ +/* + * 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 "PluginView.h" + +#include "NPRuntimeUtilities.h" +#include "Plugin.h" +#include "WebEvent.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include <WebCore/Chrome.h> +#include <WebCore/CookieJar.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/Event.h> +#include <WebCore/FocusController.h> +#include <WebCore/FrameLoadRequest.h> +#include <WebCore/FrameLoaderClient.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/HTMLPlugInElement.h> +#include <WebCore/HostWindow.h> +#include <WebCore/NetscapePlugInStreamLoader.h> +#include <WebCore/NetworkingContext.h> +#include <WebCore/ProxyServer.h> +#include <WebCore/RenderEmbeddedObject.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/ResourceLoadScheduler.h> +#include <WebCore/ScrollView.h> +#include <WebCore/Settings.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +class PluginView::URLRequest : public RefCounted<URLRequest> { +public: + static PassRefPtr<PluginView::URLRequest> create(uint64_t requestID, const FrameLoadRequest& request, bool allowPopups) + { + return adoptRef(new URLRequest(requestID, request, allowPopups)); + } + + uint64_t requestID() const { return m_requestID; } + const String& target() const { return m_request.frameName(); } + const ResourceRequest & request() const { return m_request.resourceRequest(); } + bool allowPopups() const { return m_allowPopups; } + +private: + URLRequest(uint64_t requestID, const FrameLoadRequest& request, bool allowPopups) + : m_requestID(requestID) + , m_request(request) + , m_allowPopups(allowPopups) + { + } + + uint64_t m_requestID; + FrameLoadRequest m_request; + bool m_allowPopups; +}; + +class PluginView::Stream : public RefCounted<PluginView::Stream>, NetscapePlugInStreamLoaderClient { +public: + static PassRefPtr<Stream> create(PluginView* pluginView, uint64_t streamID, const ResourceRequest& request) + { + return adoptRef(new Stream(pluginView, streamID, request)); + } + ~Stream(); + + void start(); + void cancel(); + + uint64_t streamID() const { return m_streamID; } + +private: + Stream(PluginView* pluginView, uint64_t streamID, const ResourceRequest& request) + : m_pluginView(pluginView) + , m_streamID(streamID) + , m_request(request) + , m_streamWasCancelled(false) + { + } + + // NetscapePluginStreamLoaderClient + virtual void didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse&); + virtual void didReceiveData(NetscapePlugInStreamLoader*, const char*, int); + virtual void didFail(NetscapePlugInStreamLoader*, const ResourceError&); + virtual void didFinishLoading(NetscapePlugInStreamLoader*); + + PluginView* m_pluginView; + uint64_t m_streamID; + const ResourceRequest m_request; + + // True if the stream was explicitly cancelled by calling cancel(). + // (As opposed to being cancelled by the user hitting the stop button for example. + bool m_streamWasCancelled; + + RefPtr<NetscapePlugInStreamLoader> m_loader; +}; + +PluginView::Stream::~Stream() +{ + ASSERT(!m_pluginView); +} + +void PluginView::Stream::start() +{ + ASSERT(!m_loader); + + Frame* frame = m_pluginView->m_pluginElement->document()->frame(); + ASSERT(frame); + + m_loader = resourceLoadScheduler()->schedulePluginStreamLoad(frame, this, m_request); +} + +void PluginView::Stream::cancel() +{ + ASSERT(m_loader); + + m_streamWasCancelled = true; + m_loader->cancel(m_loader->cancelledError()); + m_loader = 0; +} + +static String buildHTTPHeaders(const ResourceResponse& response, long long& expectedContentLength) +{ + if (!response.isHTTP()) + return String(); + + Vector<UChar> stringBuilder; + String separator(": "); + + String statusLine = String::format("HTTP %d ", response.httpStatusCode()); + stringBuilder.append(statusLine.characters(), statusLine.length()); + stringBuilder.append(response.httpStatusText().characters(), response.httpStatusText().length()); + stringBuilder.append('\n'); + + HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end(); + for (HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin(); it != end; ++it) { + stringBuilder.append(it->first.characters(), it->first.length()); + stringBuilder.append(separator.characters(), separator.length()); + stringBuilder.append(it->second.characters(), it->second.length()); + stringBuilder.append('\n'); + } + + String headers = String::adopt(stringBuilder); + + // If the content is encoded (most likely compressed), then don't send its length to the plugin, + // which is only interested in the decoded length, not yet known at the moment. + // <rdar://problem/4470599> tracks a request for -[NSURLResponse expectedContentLength] to incorporate this logic. + String contentEncoding = response.httpHeaderField("Content-Encoding"); + if (!contentEncoding.isNull() && contentEncoding != "identity") + expectedContentLength = -1; + + return headers; +} + +void PluginView::Stream::didReceiveResponse(NetscapePlugInStreamLoader*, const ResourceResponse& response) +{ + // Compute the stream related data from the resource response. + const KURL& responseURL = response.url(); + const String& mimeType = response.mimeType(); + long long expectedContentLength = response.expectedContentLength(); + + String headers = buildHTTPHeaders(response, expectedContentLength); + + uint32_t streamLength = 0; + if (expectedContentLength > 0) + streamLength = expectedContentLength; + + m_pluginView->m_plugin->streamDidReceiveResponse(m_streamID, responseURL, streamLength, response.lastModifiedDate(), mimeType, headers); +} + +void PluginView::Stream::didReceiveData(NetscapePlugInStreamLoader*, const char* bytes, int length) +{ + m_pluginView->m_plugin->streamDidReceiveData(m_streamID, bytes, length); +} + +void PluginView::Stream::didFail(NetscapePlugInStreamLoader*, const ResourceError& error) +{ + // Calling streamDidFail could cause us to be deleted, so we hold on to a reference here. + RefPtr<Stream> protect(this); + + // We only want to call streamDidFail if the stream was not explicitly cancelled by the plug-in. + if (!m_streamWasCancelled) + m_pluginView->m_plugin->streamDidFail(m_streamID, error.isCancellation()); + + m_pluginView->removeStream(this); + m_pluginView = 0; +} + +void PluginView::Stream::didFinishLoading(NetscapePlugInStreamLoader*) +{ + // Calling streamDidFinishLoading could cause us to be deleted, so we hold on to a reference here. + RefPtr<Stream> protectStream(this); + + // Protect the plug-in while we're calling into it. + NPRuntimeObjectMap::PluginProtector pluginProtector(&m_pluginView->m_npRuntimeObjectMap); + m_pluginView->m_plugin->streamDidFinishLoading(m_streamID); + + m_pluginView->removeStream(this); + m_pluginView = 0; +} + +static inline WebPage* webPage(HTMLPlugInElement* pluginElement) +{ + Frame* frame = pluginElement->document()->frame(); + ASSERT(frame); + + WebPage* webPage = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame()->page(); + ASSERT(webPage); + + return webPage; +} + +PassRefPtr<PluginView> PluginView::create(PassRefPtr<HTMLPlugInElement> pluginElement, PassRefPtr<Plugin> plugin, const Plugin::Parameters& parameters) +{ + return adoptRef(new PluginView(pluginElement, plugin, parameters)); +} + +PluginView::PluginView(PassRefPtr<HTMLPlugInElement> pluginElement, PassRefPtr<Plugin> plugin, const Plugin::Parameters& parameters) + : PluginViewBase(0) + , m_pluginElement(pluginElement) + , m_plugin(plugin) + , m_webPage(webPage(m_pluginElement.get())) + , m_parameters(parameters) + , m_isInitialized(false) + , m_isWaitingUntilMediaCanStart(false) + , m_isBeingDestroyed(false) + , m_pendingURLRequestsTimer(RunLoop::main(), this, &PluginView::pendingURLRequestsTimerFired) + , m_npRuntimeObjectMap(this) + , m_manualStreamState(StreamStateInitial) +{ +#if PLATFORM(MAC) + m_webPage->addPluginView(this); +#endif +} + +PluginView::~PluginView() +{ +#if PLATFORM(MAC) + m_webPage->removePluginView(this); +#endif + + ASSERT(!m_isBeingDestroyed); + + if (m_isWaitingUntilMediaCanStart) + m_pluginElement->document()->removeMediaCanStartListener(this); + + // Cancel all pending frame loads. + FrameLoadMap::iterator end = m_pendingFrameLoads.end(); + for (FrameLoadMap::iterator it = m_pendingFrameLoads.begin(), end = m_pendingFrameLoads.end(); it != end; ++it) + it->first->setLoadListener(0); + + if (m_plugin && m_isInitialized) { + m_isBeingDestroyed = true; + m_plugin->destroy(); + m_isBeingDestroyed = false; + } + + // Invalidate the object map. + m_npRuntimeObjectMap.invalidate(); + + // Cancel all streams. + cancelAllStreams(); +} + +Frame* PluginView::frame() +{ + return m_pluginElement->document()->frame(); +} + +void PluginView::manualLoadDidReceiveResponse(const ResourceResponse& response) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_plugin) + return; + + if (!m_isInitialized) { + ASSERT(m_manualStreamState == StreamStateInitial); + m_manualStreamState = StreamStateHasReceivedResponse; + m_manualStreamResponse = response; + return; + } + + // Compute the stream related data from the resource response. + const KURL& responseURL = response.url(); + const String& mimeType = response.mimeType(); + long long expectedContentLength = response.expectedContentLength(); + + String headers = buildHTTPHeaders(response, expectedContentLength); + + uint32_t streamLength = 0; + if (expectedContentLength > 0) + streamLength = expectedContentLength; + + m_plugin->manualStreamDidReceiveResponse(responseURL, streamLength, response.lastModifiedDate(), mimeType, headers); +} + +void PluginView::manualLoadDidReceiveData(const char* bytes, int length) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_plugin) + return; + + if (!m_isInitialized) { + ASSERT(m_manualStreamState == StreamStateHasReceivedResponse); + if (!m_manualStreamData) + m_manualStreamData = SharedBuffer::create(); + + m_manualStreamData->append(bytes, length); + return; + } + + m_plugin->manualStreamDidReceiveData(bytes, length); +} + +void PluginView::manualLoadDidFinishLoading() +{ + // The plug-in can be null here if it failed to initialize. + if (!m_plugin) + return; + + if (!m_isInitialized) { + ASSERT(m_manualStreamState == StreamStateHasReceivedResponse); + m_manualStreamState = StreamStateFinished; + return; + } + + m_plugin->manualStreamDidFinishLoading(); +} + +void PluginView::manualLoadDidFail(const ResourceError& error) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_plugin) + return; + + if (!m_isInitialized) { + m_manualStreamState = StreamStateFinished; + m_manualStreamError = error; + m_manualStreamData = nullptr; + return; + } + + m_plugin->manualStreamDidFail(error.isCancellation()); +} + +#if PLATFORM(MAC) +void PluginView::setWindowIsVisible(bool windowIsVisible) +{ + if (!m_plugin) + return; + + // FIXME: Implement. +} + +void PluginView::setWindowIsFocused(bool windowIsFocused) +{ + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->windowFocusChanged(windowIsFocused); +} + +void PluginView::windowAndViewFramesChanged(const IntRect& windowFrameInScreenCoordinates, const IntRect& viewFrameInWindowCoordinates) +{ + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates); +} + +bool PluginView::sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput) +{ + if (!m_plugin) + return false; + + if (m_plugin->pluginComplexTextInputIdentifier() != pluginComplexTextInputIdentifier) + return false; + + m_plugin->sendComplexTextInput(textInput); + return true; +} + +#endif + +void PluginView::initializePlugin() +{ + if (m_isInitialized) + return; + + if (!m_plugin) { + // We've already tried and failed to initialize the plug-in. + return; + } + + if (Frame* frame = m_pluginElement->document()->frame()) { + if (Page* page = frame->page()) { + + // We shouldn't initialize the plug-in right now, add a listener. + if (!page->canStartMedia()) { + if (m_isWaitingUntilMediaCanStart) + return; + + m_isWaitingUntilMediaCanStart = true; + m_pluginElement->document()->addMediaCanStartListener(this); + return; + } + } + } + + if (!m_plugin->initialize(this, m_parameters)) { + // We failed to initialize the plug-in. + m_plugin = 0; + + return; + } + + m_isInitialized = true; + + viewGeometryDidChange(); + + redeliverManualStream(); + +#if PLATFORM(MAC) + if (m_plugin->pluginLayer()) { + if (frame()) { + frame()->view()->enterCompositingMode(); + m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange); + } + } + + windowAndViewFramesChanged(m_webPage->windowFrameInScreenCoordinates(), m_webPage->viewFrameInWindowCoordinates()); + setWindowIsVisible(m_webPage->windowIsVisible()); + setWindowIsFocused(m_webPage->windowIsFocused()); +#endif +} + +#if PLATFORM(MAC) +PlatformLayer* PluginView::platformLayer() const +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return 0; + + return m_plugin->pluginLayer(); +} +#endif + +JSObject* PluginView::scriptObject(JSGlobalObject* globalObject) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return 0; + + NPObject* scriptableNPObject = m_plugin->pluginScriptableNPObject(); + if (!scriptableNPObject) + return 0; + + JSObject* jsObject = m_npRuntimeObjectMap.getOrCreateJSObject(globalObject, scriptableNPObject); + releaseNPObject(scriptableNPObject); + + return jsObject; +} + +void PluginView::privateBrowsingStateChanged(bool privateBrowsingEnabled) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->privateBrowsingStateChanged(privateBrowsingEnabled); +} + +void PluginView::setFrameRect(const WebCore::IntRect& rect) +{ + Widget::setFrameRect(rect); + viewGeometryDidChange(); +} + +void PluginView::paint(GraphicsContext* context, const IntRect& dirtyRect) +{ + if (context->paintingDisabled() || !m_plugin || !m_isInitialized) + return; + + IntRect dirtyRectInWindowCoordinates = parent()->contentsToWindow(dirtyRect); + + IntRect paintRectInWindowCoordinates = intersection(dirtyRectInWindowCoordinates, clipRectInWindowCoordinates()); + if (paintRectInWindowCoordinates.isEmpty()) + return; + + // context is in document coordinates. Translate it to window coordinates. + IntPoint documentOriginInWindowCoordinates = parent()->contentsToWindow(IntPoint()); + context->save(); + context->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y()); + + m_plugin->paint(context, paintRectInWindowCoordinates); + + context->restore(); +} + +void PluginView::frameRectsChanged() +{ + Widget::frameRectsChanged(); + viewGeometryDidChange(); +} + +void PluginView::setParent(ScrollView* scrollView) +{ + Widget::setParent(scrollView); + + if (scrollView) + initializePlugin(); +} + +void PluginView::handleEvent(Event* event) +{ + if (!m_isInitialized || !m_plugin) + return; + + const WebEvent* currentEvent = WebPage::currentEvent(); + if (!currentEvent) + return; + + bool didHandleEvent = false; + + if ((event->type() == eventNames().mousemoveEvent && currentEvent->type() == WebEvent::MouseMove) + || (event->type() == eventNames().mousedownEvent && currentEvent->type() == WebEvent::MouseDown) + || (event->type() == eventNames().mouseupEvent && currentEvent->type() == WebEvent::MouseUp)) { + // We have a mouse event. + if (currentEvent->type() == WebEvent::MouseDown) + focusPluginElement(); + + didHandleEvent = m_plugin->handleMouseEvent(static_cast<const WebMouseEvent&>(*currentEvent)); + } else if (event->type() == eventNames().mousewheelEvent && currentEvent->type() == WebEvent::Wheel) { + // We have a wheel event. + didHandleEvent = m_plugin->handleWheelEvent(static_cast<const WebWheelEvent&>(*currentEvent)); + } else if (event->type() == eventNames().mouseoverEvent && currentEvent->type() == WebEvent::MouseMove) { + // We have a mouse enter event. + didHandleEvent = m_plugin->handleMouseEnterEvent(static_cast<const WebMouseEvent&>(*currentEvent)); + } else if (event->type() == eventNames().mouseoutEvent && currentEvent->type() == WebEvent::MouseMove) { + // We have a mouse leave event. + didHandleEvent = m_plugin->handleMouseLeaveEvent(static_cast<const WebMouseEvent&>(*currentEvent)); + } else if ((event->type() == eventNames().keydownEvent && currentEvent->type() == WebEvent::KeyDown) + || (event->type() == eventNames().keyupEvent && currentEvent->type() == WebEvent::KeyUp)) { + // We have a keyboard event. + didHandleEvent = m_plugin->handleKeyboardEvent(static_cast<const WebKeyboardEvent&>(*currentEvent)); + } + + if (didHandleEvent) + event->setDefaultHandled(); +} + +void PluginView::viewGeometryDidChange() +{ + if (!m_isInitialized || !m_plugin || !parent()) + return; + + // Get the frame rect in window coordinates. + IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); + + m_plugin->geometryDidChange(frameRectInWindowCoordinates, clipRectInWindowCoordinates()); +} + +IntRect PluginView::clipRectInWindowCoordinates() const +{ + ASSERT(parent()); + + // Get the frame rect in window coordinates. + IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); + + // Get the window clip rect for the enclosing layer (in window coordinates). + RenderLayer* layer = m_pluginElement->renderer()->enclosingLayer(); + FrameView* parentView = m_pluginElement->document()->frame()->view(); + IntRect windowClipRect = parentView->windowClipRectForLayer(layer, true); + + // Intersect the two rects to get the view clip rect in window coordinates. + return intersection(frameRectInWindowCoordinates, windowClipRect); +} + +void PluginView::focusPluginElement() +{ + ASSERT(frame()); + + if (Page* page = frame()->page()) + page->focusController()->setFocusedFrame(frame()); + frame()->document()->setFocusedNode(m_pluginElement); +} + +void PluginView::pendingURLRequestsTimerFired() +{ + ASSERT(!m_pendingURLRequests.isEmpty()); + + RefPtr<URLRequest> urlRequest = m_pendingURLRequests.takeFirst(); + + // If there are more requests to perform, reschedule the timer. + if (!m_pendingURLRequests.isEmpty()) + m_pendingURLRequestsTimer.startOneShot(0); + + performURLRequest(urlRequest.get()); +} + +void PluginView::performURLRequest(URLRequest* request) +{ + // First, check if this is a javascript: url. + if (protocolIsJavaScript(request->request().url())) { + performJavaScriptURLRequest(request); + return; + } + + if (!request->target().isNull()) { + performFrameLoadURLRequest(request); + return; + } + + // This request is to load a URL and create a stream. + RefPtr<Stream> stream = PluginView::Stream::create(this, request->requestID(), request->request()); + addStream(stream.get()); + stream->start(); +} + +void PluginView::performFrameLoadURLRequest(URLRequest* request) +{ + ASSERT(!request->target().isNull()); + + Frame* frame = m_pluginElement->document()->frame(); + if (!frame) + return; + + if (!m_pluginElement->document()->securityOrigin()->canDisplay(request->request().url())) { + // We can't load the request, send back a reply to the plug-in. + m_plugin->frameDidFail(request->requestID(), false); + return; + } + + // First, try to find a target frame. + Frame* targetFrame = frame->loader()->findFrameForNavigation(request->target()); + if (!targetFrame) { + // We did not find a target frame. Ask our frame to load the page. This may or may not create a popup window. + frame->loader()->load(request->request(), request->target(), false); + + // FIXME: We don't know whether the window was successfully created here so we just assume that it worked. + // It's better than not telling the plug-in anything. + m_plugin->frameDidFinishLoading(request->requestID()); + return; + } + + // Now ask the frame to load the request. + targetFrame->loader()->load(request->request(), false); + + WebFrame* targetWebFrame = static_cast<WebFrameLoaderClient*>(targetFrame->loader()->client())->webFrame(); + if (WebFrame::LoadListener* loadListener = targetWebFrame->loadListener()) { + // Check if another plug-in view or even this view is waiting for the frame to load. + // If it is, tell it that the load was cancelled because it will be anyway. + loadListener->didFailLoad(targetWebFrame, true); + } + + m_pendingFrameLoads.set(targetWebFrame, request); + targetWebFrame->setLoadListener(this); +} + +void PluginView::performJavaScriptURLRequest(URLRequest* request) +{ + ASSERT(protocolIsJavaScript(request->request().url())); + + RefPtr<Frame> frame = m_pluginElement->document()->frame(); + if (!frame) + return; + + String jsString = decodeURLEscapeSequences(request->request().url().string().substring(sizeof("javascript:") - 1)); + + if (!request->target().isNull()) { + // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. + if (frame->tree()->find(request->target()) != frame) { + // Let the plug-in know that its frame load failed. + m_plugin->frameDidFail(request->requestID(), false); + return; + } + } + + // Evaluate the JavaScript code. Note that running JavaScript here could cause the plug-in to be destroyed, so we + // grab references to the plug-in here. + RefPtr<Plugin> plugin = m_plugin; + + bool oldAllowPopups = frame->script()->allowPopupsFromPlugin(); + frame->script()->setAllowPopupsFromPlugin(request->allowPopups()); + + ScriptValue result = m_pluginElement->document()->frame()->script()->executeScript(jsString); + + frame->script()->setAllowPopupsFromPlugin(oldAllowPopups); + + // Check if evaluating the JavaScript destroyed the plug-in. + if (!plugin->controller()) + return; + + ScriptState* scriptState = m_pluginElement->document()->frame()->script()->globalObject(pluginWorld())->globalExec(); + String resultString; + result.getString(scriptState, resultString); + + if (!request->target().isNull()) { + // Just send back whether the frame load succeeded or not. + if (resultString.isNull()) + m_plugin->frameDidFail(request->requestID(), false); + else + m_plugin->frameDidFinishLoading(request->requestID()); + return; + } + + // Send the result back to the plug-in. + plugin->didEvaluateJavaScript(request->requestID(), decodeURLEscapeSequences(request->request().url()), resultString); +} + +void PluginView::addStream(Stream* stream) +{ + ASSERT(!m_streams.contains(stream->streamID())); + m_streams.set(stream->streamID(), stream); +} + +void PluginView::removeStream(Stream* stream) +{ + ASSERT(m_streams.get(stream->streamID()) == stream); + + m_streams.remove(stream->streamID()); +} + +void PluginView::cancelAllStreams() +{ + Vector<RefPtr<Stream> > streams; + copyValuesToVector(m_streams, streams); + + for (size_t i = 0; i < streams.size(); ++i) + streams[i]->cancel(); + + // Cancelling a stream removes it from the m_streams map, so if we cancel all streams the map should be empty. + ASSERT(m_streams.isEmpty()); +} + +void PluginView::redeliverManualStream() +{ + if (m_manualStreamState == StreamStateInitial) { + // Nothing to do. + return; + } + + if (m_manualStreamState == StreamStateFailed) { + manualLoadDidFail(m_manualStreamError); + return; + } + + // Deliver the response. + manualLoadDidReceiveResponse(m_manualStreamResponse); + + // Deliver the data. + if (m_manualStreamData) { + const char* data; + unsigned position = 0; + + while (unsigned length = m_manualStreamData->getSomeData(data, position)) { + manualLoadDidReceiveData(data, length); + position += length; + } + + m_manualStreamData = nullptr; + } + + if (m_manualStreamState == StreamStateFinished) + manualLoadDidFinishLoading(); +} + +void PluginView::invalidateRect(const IntRect& dirtyRect) +{ + if (!parent() || !m_plugin || !m_isInitialized) + return; + + IntRect dirtyRectInWindowCoordinates = convertToContainingWindow(dirtyRect); + + parent()->hostWindow()->invalidateContentsAndWindow(intersection(dirtyRectInWindowCoordinates, clipRectInWindowCoordinates()), false); +} + +void PluginView::setFocus(bool hasFocus) +{ + Widget::setFocus(hasFocus); + + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->setFocus(hasFocus); +} + +void PluginView::mediaCanStart() +{ + ASSERT(m_isWaitingUntilMediaCanStart); + m_isWaitingUntilMediaCanStart = false; + + initializePlugin(); +} + +void PluginView::invalidate(const IntRect& dirtyRect) +{ + invalidateRect(dirtyRect); +} + +String PluginView::userAgent() +{ + Frame* frame = m_pluginElement->document()->frame(); + if (!frame) + return String(); + + return frame->loader()->client()->userAgent(KURL()); +} + +void PluginView::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, + const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) +{ + FrameLoadRequest frameLoadRequest(m_pluginElement->document()->securityOrigin()); + frameLoadRequest.resourceRequest().setHTTPMethod(method); + frameLoadRequest.resourceRequest().setURL(m_pluginElement->document()->completeURL(urlString)); + frameLoadRequest.resourceRequest().addHTTPHeaderFields(headerFields); + frameLoadRequest.resourceRequest().setHTTPBody(FormData::create(httpBody.data(), httpBody.size())); + frameLoadRequest.setFrameName(target); + + m_pendingURLRequests.append(URLRequest::create(requestID, frameLoadRequest, allowPopups)); + m_pendingURLRequestsTimer.startOneShot(0); +} + +void PluginView::cancelStreamLoad(uint64_t streamID) +{ + // Keep a reference to the stream. Stream::cancel might remove the stream from the map, and thus + // releasing its last reference. + RefPtr<Stream> stream = m_streams.get(streamID).get(); + if (!stream) + return; + + // Cancelling the stream here will remove it from the map. + stream->cancel(); + ASSERT(!m_streams.contains(streamID)); +} + +void PluginView::cancelManualStreamLoad() +{ + if (!frame()) + return; + + DocumentLoader* documentLoader = frame()->loader()->activeDocumentLoader(); + ASSERT(documentLoader); + + if (documentLoader->isLoadingMainResource()) + documentLoader->cancelMainResourceLoad(frame()->loader()->cancelledError(m_parameters.url)); +} + +NPObject* PluginView::windowScriptNPObject() +{ + if (!frame()) + return 0; + + // FIXME: Handle JavaScript being disabled. + ASSERT(frame()->script()->canExecuteScripts(NotAboutToExecuteScript)); + + return m_npRuntimeObjectMap.getOrCreateNPObject(frame()->script()->windowShell(pluginWorld())->window()); +} + +NPObject* PluginView::pluginElementNPObject() +{ + if (!frame()) + return 0; + + // FIXME: Handle JavaScript being disabled. + JSObject* object = frame()->script()->jsObjectForPluginElement(m_pluginElement.get()); + ASSERT(object); + + return m_npRuntimeObjectMap.getOrCreateNPObject(object); +} + +bool PluginView::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups) +{ + if (!frame()) + return false; + + bool oldAllowPopups = frame()->script()->allowPopupsFromPlugin(); + frame()->script()->setAllowPopupsFromPlugin(allowPopups); + + bool returnValue = m_npRuntimeObjectMap.evaluate(npObject, scriptString, result); + + frame()->script()->setAllowPopupsFromPlugin(oldAllowPopups); + + return returnValue; +} + +void PluginView::setStatusbarText(const String& statusbarText) +{ + if (!frame()) + return; + + Page* page = frame()->page(); + if (!page) + return; + + page->chrome()->setStatusbarText(frame(), statusbarText); +} + +bool PluginView::isAcceleratedCompositingEnabled() +{ + if (!frame()) + return false; + + Settings* settings = frame()->settings(); + if (!settings) + return false; + + return settings->acceleratedCompositingEnabled(); +} + +void PluginView::pluginProcessCrashed() +{ + if (!m_pluginElement->renderer()) + return; + + // FIXME: The renderer could also be a RenderApplet, we should handle that. + if (!m_pluginElement->renderer()->isEmbeddedObject()) + return; + + RenderEmbeddedObject* renderer = toRenderEmbeddedObject(m_pluginElement->renderer()); + renderer->setShowsCrashedPluginIndicator(); + + invalidateRect(frameRect()); +} + +#if PLATFORM(WIN) +HWND PluginView::nativeParentWindow() +{ + return m_webPage->nativeWindow(); +} +#endif + +#if PLATFORM(MAC) +void PluginView::setComplexTextInputEnabled(bool complexTextInputEnabled) +{ + m_webPage->send(Messages::WebPageProxy::SetComplexTextInputEnabled(m_plugin->pluginComplexTextInputIdentifier(), complexTextInputEnabled)); +} +#endif + +String PluginView::proxiesForURL(const String& urlString) +{ + const FrameLoader* frameLoader = frame() ? frame()->loader() : 0; + const NetworkingContext* context = frameLoader ? frameLoader->networkingContext() : 0; + Vector<ProxyServer> proxyServers = proxyServersForURL(KURL(KURL(), urlString), context); + return toString(proxyServers); +} + +String PluginView::cookiesForURL(const String& urlString) +{ + return cookies(m_pluginElement->document(), KURL(KURL(), urlString)); +} + +void PluginView::setCookiesForURL(const String& urlString, const String& cookieString) +{ + setCookies(m_pluginElement->document(), KURL(KURL(), urlString), cookieString); +} + +bool PluginView::isPrivateBrowsingEnabled() +{ + // If we can't get the real setting, we'll assume that private browsing is enabled. + if (!frame()) + return true; + + Settings* settings = frame()->settings(); + if (!settings) + return true; + + return settings->privateBrowsingEnabled(); +} + +void PluginView::didFinishLoad(WebFrame* webFrame) +{ + RefPtr<URLRequest> request = m_pendingFrameLoads.take(webFrame); + ASSERT(request); + webFrame->setLoadListener(0); + + m_plugin->frameDidFinishLoading(request->requestID()); +} + +void PluginView::didFailLoad(WebFrame* webFrame, bool wasCancelled) +{ + RefPtr<URLRequest> request = m_pendingFrameLoads.take(webFrame); + ASSERT(request); + webFrame->setLoadListener(0); + + m_plugin->frameDidFail(request->requestID(), wasCancelled); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.h b/Source/WebKit2/WebProcess/Plugins/PluginView.h new file mode 100644 index 0000000..07511d7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.h @@ -0,0 +1,185 @@ +/* + * 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. + */ + +#ifndef PluginView_h +#define PluginView_h + +#include "NPRuntimeObjectMap.h" +#include "Plugin.h" +#include "PluginController.h" +#include "RunLoop.h" +#include "WebFrame.h" + +#include <WebCore/MediaCanStartListener.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceResponse.h> +#include <WebCore/PluginViewBase.h> +#include <wtf/Deque.h> + +// FIXME: Eventually this should move to WebCore. + +namespace WebCore { + class Frame; + class HTMLPlugInElement; +} + +namespace WebKit { + +class PluginView : public WebCore::PluginViewBase, WebCore::MediaCanStartListener, PluginController, WebFrame::LoadListener { +public: + static PassRefPtr<PluginView> create(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters&); + + WebCore::Frame* frame(); + + bool isBeingDestroyed() const { return m_isBeingDestroyed; } + + void manualLoadDidReceiveResponse(const WebCore::ResourceResponse&); + void manualLoadDidReceiveData(const char* bytes, int length); + void manualLoadDidFinishLoading(); + void manualLoadDidFail(const WebCore::ResourceError&); + +#if PLATFORM(MAC) + void setWindowIsVisible(bool); + void setWindowIsFocused(bool); + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); + bool sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput); +#endif + +private: + PluginView(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters& parameters); + virtual ~PluginView(); + + void initializePlugin(); + void destroyPlugin(); + + void viewGeometryDidChange(); + WebCore::IntRect clipRectInWindowCoordinates() const; + void focusPluginElement(); + + void pendingURLRequestsTimerFired(); + class URLRequest; + void performURLRequest(URLRequest*); + + // Perform a URL request where the frame target is not null. + void performFrameLoadURLRequest(URLRequest*); + + // Perform a URL request where the URL protocol is "javascript:". + void performJavaScriptURLRequest(URLRequest*); + + class Stream; + void addStream(Stream*); + void removeStream(Stream*); + void cancelAllStreams(); + + void redeliverManualStream(); + + // WebCore::PluginViewBase +#if PLATFORM(MAC) + virtual PlatformLayer* platformLayer() const; +#endif + virtual JSC::JSObject* scriptObject(JSC::JSGlobalObject*); + virtual void privateBrowsingStateChanged(bool); + + // WebCore::Widget + virtual void setFrameRect(const WebCore::IntRect&); + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect&); + virtual void invalidateRect(const WebCore::IntRect&); + virtual void setFocus(bool); + virtual void frameRectsChanged(); + virtual void setParent(WebCore::ScrollView*); + virtual void handleEvent(WebCore::Event*); + + // WebCore::MediaCanStartListener + virtual void mediaCanStart(); + + // PluginController + virtual void invalidate(const WebCore::IntRect&); + virtual String userAgent(); + virtual void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, + const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups); + virtual void cancelStreamLoad(uint64_t streamID); + virtual void cancelManualStreamLoad(); + virtual NPObject* windowScriptNPObject(); + virtual NPObject* pluginElementNPObject(); + virtual bool evaluate(NPObject*, const String&scriptString, NPVariant* result, bool allowPopups); + virtual void setStatusbarText(const String&); + virtual bool isAcceleratedCompositingEnabled(); + virtual void pluginProcessCrashed(); +#if PLATFORM(WIN) + virtual HWND nativeParentWindow(); +#endif +#if PLATFORM(MAC) + virtual void setComplexTextInputEnabled(bool); +#endif + virtual String proxiesForURL(const String&); + virtual String cookiesForURL(const String&); + virtual void setCookiesForURL(const String& urlString, const String& cookieString); + virtual bool isPrivateBrowsingEnabled(); + + // WebFrame::LoadListener + virtual void didFinishLoad(WebFrame*); + virtual void didFailLoad(WebFrame*, bool wasCancelled); + + RefPtr<WebCore::HTMLPlugInElement> m_pluginElement; + RefPtr<Plugin> m_plugin; + WebPage* m_webPage; + Plugin::Parameters m_parameters; + + bool m_isInitialized; + bool m_isWaitingUntilMediaCanStart; + bool m_isBeingDestroyed; + + // Pending URLRequests that the plug-in has made. + Deque<RefPtr<URLRequest> > m_pendingURLRequests; + RunLoop::Timer<PluginView> m_pendingURLRequestsTimer; + + // Pending frame loads that the plug-in has made. + typedef HashMap<RefPtr<WebFrame>, RefPtr<URLRequest> > FrameLoadMap; + FrameLoadMap m_pendingFrameLoads; + + // Streams that the plug-in has requested to load. + HashMap<uint64_t, RefPtr<Stream> > m_streams; + + // A map of all related NPObjects for this plug-in view. + NPRuntimeObjectMap m_npRuntimeObjectMap; + + // The manual stream state. This is used so we can deliver a manual stream to a plug-in + // when it is initialized. + enum ManualStreamState { + StreamStateInitial, + StreamStateHasReceivedResponse, + StreamStateFinished, + StreamStateFailed + }; + ManualStreamState m_manualStreamState; + + WebCore::ResourceResponse m_manualStreamResponse; + WebCore::ResourceError m_manualStreamError; + RefPtr<WebCore::SharedBuffer> m_manualStreamData; +}; + +} // namespace WebKit + +#endif // PluginView_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp new file mode 100644 index 0000000..ffca3fa --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp @@ -0,0 +1,686 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * 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 "WebChromeClient.h" + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +#include "DrawingArea.h" +#include "InjectedBundleUserMessageCoders.h" +#include "WebContextMenu.h" +#include "WebCoreArgumentCoders.h" +#include "WebFrame.h" +#include "WebFrameLoaderClient.h" +#include "WebOpenPanelParameters.h" +#include "WebOpenPanelResultListener.h" +#include "WebPage.h" +#include "WebPageCreationParameters.h" +#include "WebPageProxyMessages.h" +#include "WebPopupMenu.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include "WebProcessProxyMessageKinds.h" +#include "WebSearchPopupMenu.h" +#include <WebCore/DatabaseTracker.h> +#include <WebCore/FileChooser.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoader.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLPlugInImageElement.h> +#include <WebCore/Page.h> +#include <WebCore/SecurityOrigin.h> + +using namespace WebCore; +using namespace HTMLNames; + +namespace WebKit { + +static double area(WebFrame* frame) +{ + IntSize size = frame->size(); + return static_cast<double>(size.height()) * size.width(); +} + + +static WebFrame* findLargestFrameInFrameSet(WebPage* page) +{ + WebFrame* mainFrame = page->mainFrame(); + if (!mainFrame->isFrameSet()) + return 0; + + WebFrame* largestSoFar = 0; + + RefPtr<ImmutableArray> frameChildren = mainFrame->childFrames(); + size_t count = frameChildren->size(); + for (size_t i = 0; i < count; ++i) { + WebFrame* childFrame = frameChildren->at<WebFrame>(i); + if (!largestSoFar || area(childFrame) > area(largestSoFar)) + largestSoFar = childFrame; + } + + return largestSoFar; +} + +void WebChromeClient::chromeDestroyed() +{ + delete this; +} + +void WebChromeClient::setWindowRect(const FloatRect& windowFrame) +{ + m_page->send(Messages::WebPageProxy::SetWindowFrame(windowFrame)); +} + +FloatRect WebChromeClient::windowRect() +{ + FloatRect newWindowFrame; + + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetWindowFrame(), Messages::WebPageProxy::GetWindowFrame::Reply(newWindowFrame), m_page->pageID())) + return FloatRect(); + + return newWindowFrame; +} + +FloatRect WebChromeClient::pageRect() +{ + return FloatRect(FloatPoint(), m_page->size()); +} + +float WebChromeClient::scaleFactor() +{ + notImplemented(); + return 1.0; +} + +void WebChromeClient::focus() +{ + notImplemented(); +} + +void WebChromeClient::unfocus() +{ + notImplemented(); +} + +bool WebChromeClient::canTakeFocus(FocusDirection) +{ + notImplemented(); + return true; +} + +void WebChromeClient::takeFocus(FocusDirection direction) +{ + m_page->send(Messages::WebPageProxy::TakeFocus(direction == FocusDirectionForward ? true : false)); +} + +void WebChromeClient::focusedNodeChanged(Node*) +{ + notImplemented(); +} + +void WebChromeClient::focusedFrameChanged(Frame* frame) +{ + WebFrame* webFrame = frame ? static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame() : 0; + + WebProcess::shared().connection()->send(Messages::WebPageProxy::FocusedFrameChanged(webFrame ? webFrame->frameID() : 0), m_page->pageID()); +} + +Page* WebChromeClient::createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures& windowFeatures, const NavigationAction& navigationAction) +{ + uint32_t modifiers = modifiersForNavigationAction(navigationAction); + int32_t mouseButton = mouseButtonForNavigationAction(navigationAction); + + uint64_t newPageID = 0; + WebPageCreationParameters parameters; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::CreateNewPage(windowFeatures, modifiers, mouseButton), Messages::WebPageProxy::CreateNewPage::Reply(newPageID, parameters), m_page->pageID())) + return 0; + + if (!newPageID) + return 0; + + WebProcess::shared().createWebPage(newPageID, parameters); + return WebProcess::shared().webPage(newPageID)->corePage(); +} + +void WebChromeClient::show() +{ + m_page->show(); +} + +bool WebChromeClient::canRunModal() +{ + notImplemented(); + return false; +} + +void WebChromeClient::runModal() +{ + notImplemented(); +} + +void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible) +{ + m_page->send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible)); +} + +bool WebChromeClient::toolbarsVisible() +{ + bool toolbarsAreVisible = true; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetToolbarsAreVisible(), Messages::WebPageProxy::GetToolbarsAreVisible::Reply(toolbarsAreVisible), m_page->pageID())) + return true; + + return toolbarsAreVisible; +} + +void WebChromeClient::setStatusbarVisible(bool statusBarIsVisible) +{ + m_page->send(Messages::WebPageProxy::SetStatusBarIsVisible(statusBarIsVisible)); +} + +bool WebChromeClient::statusbarVisible() +{ + bool statusBarIsVisible = true; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetStatusBarIsVisible(), Messages::WebPageProxy::GetStatusBarIsVisible::Reply(statusBarIsVisible), m_page->pageID())) + return true; + + return statusBarIsVisible; +} + +void WebChromeClient::setScrollbarsVisible(bool) +{ + notImplemented(); +} + +bool WebChromeClient::scrollbarsVisible() +{ + notImplemented(); + return true; +} + +void WebChromeClient::setMenubarVisible(bool menuBarVisible) +{ + m_page->send(Messages::WebPageProxy::SetMenuBarIsVisible(menuBarVisible)); +} + +bool WebChromeClient::menubarVisible() +{ + bool menuBarIsVisible = true; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetMenuBarIsVisible(), Messages::WebPageProxy::GetMenuBarIsVisible::Reply(menuBarIsVisible), m_page->pageID())) + return true; + + return menuBarIsVisible; +} + +void WebChromeClient::setResizable(bool resizable) +{ + m_page->send(Messages::WebPageProxy::SetIsResizable(resizable)); +} + +void WebChromeClient::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned int lineNumber, const String& sourceID) +{ + // Notify the bundle client. + m_page->injectedBundleUIClient().willAddMessageToConsole(m_page, message, lineNumber); + + notImplemented(); +} + +bool WebChromeClient::canRunBeforeUnloadConfirmPanel() +{ + bool canRun = false; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::CanRunBeforeUnloadConfirmPanel(), Messages::WebPageProxy::CanRunBeforeUnloadConfirmPanel::Reply(canRun), m_page->pageID())) + return false; + + return canRun; +} + +bool WebChromeClient::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) +{ + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + + bool shouldClose = false; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunBeforeUnloadConfirmPanel(message, webFrame->frameID()), Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::Reply(shouldClose), m_page->pageID())) + return false; + + return shouldClose; +} + +void WebChromeClient::closeWindowSoon() +{ + // FIXME: This code assumes that the client will respond to a close page + // message by actually closing the page. Safari does this, but there is + // no guarantee that other applications will, which will leave this page + // half detached. This approach is an inherent limitation making parts of + // a close execute synchronously as part of window.close, but other parts + // later on. + + m_page->corePage()->setGroupName(String()); + + if (WebFrame* frame = m_page->mainFrame()) { + if (Frame* coreFrame = frame->coreFrame()) + coreFrame->loader()->stopForUserCancel(); + } + + m_page->sendClose(); +} + +void WebChromeClient::runJavaScriptAlert(Frame* frame, const String& alertText) +{ + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + + // Notify the bundle client. + m_page->injectedBundleUIClient().willRunJavaScriptAlert(m_page, alertText, webFrame); + + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), m_page->pageID()); +} + +bool WebChromeClient::runJavaScriptConfirm(Frame* frame, const String& message) +{ + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + + // Notify the bundle client. + m_page->injectedBundleUIClient().willRunJavaScriptConfirm(m_page, message, webFrame); + + bool result = false; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), m_page->pageID())) + return false; + + return result; +} + +bool WebChromeClient::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result) +{ + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + + // Notify the bundle client. + m_page->injectedBundleUIClient().willRunJavaScriptPrompt(m_page, message, defaultValue, webFrame); + + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), m_page->pageID())) + return false; + + return !result.isNull(); +} + +void WebChromeClient::setStatusbarText(const String& statusbarText) +{ + // Notify the bundle client. + m_page->injectedBundleUIClient().willSetStatusbarText(m_page, statusbarText); + + m_page->send(Messages::WebPageProxy::SetStatusText(statusbarText)); +} + +bool WebChromeClient::shouldInterruptJavaScript() +{ + notImplemented(); + return false; +} + +bool WebChromeClient::tabsToLinks() const +{ + return m_page->tabsToLinks(); +} + +IntRect WebChromeClient::windowResizerRect() const +{ + return m_page->windowResizerRect(); +} + +void WebChromeClient::invalidateWindow(const IntRect&, bool) +{ + // Do nothing here, there's no concept of invalidating the window in the web process. +} + +void WebChromeClient::invalidateContentsAndWindow(const IntRect& rect, bool) +{ + m_page->drawingArea()->setNeedsDisplay(rect); +} + +void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect, bool) +{ + m_page->pageDidScroll(); + m_page->drawingArea()->setNeedsDisplay(rect); +} + +void WebChromeClient::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect&) +{ + m_page->pageDidScroll(); + m_page->drawingArea()->scroll(scrollRect, scrollDelta); +} + +#if ENABLE(TILED_BACKING_STORE) +void WebChromeClient::delegatedScrollRequested(const IntSize& scrollDelta) +{ + m_page->pageDidRequestScroll(scrollDelta); +} +#endif + +IntPoint WebChromeClient::screenToWindow(const IntPoint&) const +{ + notImplemented(); + return IntPoint(); +} + +IntRect WebChromeClient::windowToScreen(const IntRect&) const +{ + notImplemented(); + return IntRect(); +} + +PlatformPageClient WebChromeClient::platformPageClient() const +{ + notImplemented(); + return 0; +} + +void WebChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) const +{ +#if PLATFORM(QT) +#if ENABLE(TILED_BACKING_STORE) + if (frame->page()->mainFrame() == frame) + m_page->resizeToContentsIfNeeded(); +#endif + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + + if (!m_page->mainFrame() || m_page->mainFrame() != webFrame) + return; + + m_page->send(Messages::WebPageProxy::DidChangeContentsSize(size)); +#endif + + WebFrame* largestFrame = findLargestFrameInFrameSet(m_page); + if (largestFrame != m_cachedFrameSetLargestFrame.get()) { + m_cachedFrameSetLargestFrame = largestFrame; + WebProcess::shared().connection()->send(Messages::WebPageProxy::FrameSetLargestFrameChanged(largestFrame ? largestFrame->frameID() : 0), m_page->pageID()); + } +} + +void WebChromeClient::scrollRectIntoView(const IntRect&, const ScrollView*) const +{ + notImplemented(); +} + +bool WebChromeClient::shouldMissingPluginMessageBeButton() const +{ + // FIXME: <rdar://problem/8794397> We should only return true when there is a + // missingPluginButtonClicked callback defined on the Page UI client. + return true; +} + +void WebChromeClient::missingPluginButtonClicked(Element* element) const +{ + ASSERT(element->hasTagName(objectTag) || element->hasTagName(embedTag)); + + HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(element); + + m_page->send(Messages::WebPageProxy::MissingPluginButtonClicked(pluginElement->serviceType(), pluginElement->url())); +} + +void WebChromeClient::scrollbarsModeDidChange() const +{ + notImplemented(); +} + +void WebChromeClient::mouseDidMoveOverElement(const HitTestResult& hitTestResult, unsigned modifierFlags) +{ + RefPtr<APIObject> userData; + + // Notify the bundle client. + m_page->injectedBundleUIClient().mouseDidMoveOverElement(m_page, hitTestResult, static_cast<WebEvent::Modifiers>(modifierFlags), userData); + + // Notify the UIProcess. + m_page->send(Messages::WebPageProxy::MouseDidMoveOverElement(modifierFlags, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebChromeClient::setToolTip(const String& toolTip, TextDirection) +{ + // Only send a tool tip to the WebProcess if it has changed since the last time this function was called. + + if (toolTip == m_cachedToolTip) + return; + m_cachedToolTip = toolTip; + + m_page->send(Messages::WebPageProxy::SetToolTip(m_cachedToolTip)); +} + +void WebChromeClient::print(Frame*) +{ + notImplemented(); +} + +#if ENABLE(DATABASE) +void WebChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseName) +{ + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + SecurityOrigin* origin = frame->document()->securityOrigin(); + + DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseName, origin); + uint64_t currentQuota = DatabaseTracker::tracker().quotaForOrigin(origin); + uint64_t newQuota = 0; + WebProcess::shared().connection()->sendSync( + Messages::WebPageProxy::ExceededDatabaseQuota(webFrame->frameID(), origin->databaseIdentifier(), databaseName, details.displayName(), currentQuota, details.currentUsage(), details.expectedUsage()), + Messages::WebPageProxy::ExceededDatabaseQuota::Reply(newQuota), m_page->pageID()); + + DatabaseTracker::tracker().setQuota(origin, newQuota); +} +#endif + + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +void WebChromeClient::reachedMaxAppCacheSize(int64_t) +{ + notImplemented(); +} + +void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin*) +{ + notImplemented(); +} +#endif + +#if ENABLE(DASHBOARD_SUPPORT) +void WebChromeClient::dashboardRegionsChanged() +{ + notImplemented(); +} +#endif + +void WebChromeClient::populateVisitedLinks() +{ +} + +FloatRect WebChromeClient::customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect) +{ + notImplemented(); + return FloatRect(); +} + +void WebChromeClient::paintCustomHighlight(Node*, const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect, + bool behindText, bool entireLine) +{ + notImplemented(); +} + +bool WebChromeClient::shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename) +{ + notImplemented(); + return false; +} + +String WebChromeClient::generateReplacementFile(const String& path) +{ + notImplemented(); + return String(); +} + +bool WebChromeClient::paintCustomScrollbar(GraphicsContext*, const FloatRect&, ScrollbarControlSize, + ScrollbarControlState, ScrollbarPart pressedPart, bool vertical, + float value, float proportion, ScrollbarControlPartMask) +{ + notImplemented(); + return false; +} + +bool WebChromeClient::paintCustomScrollCorner(GraphicsContext*, const FloatRect&) +{ + notImplemented(); + return false; +} + +void WebChromeClient::requestGeolocationPermissionForFrame(Frame*, Geolocation*) +{ + notImplemented(); +} + +void WebChromeClient::cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) +{ + notImplemented(); +} + +void WebChromeClient::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser) +{ + if (m_page->activeOpenPanelResultListener()) + return; + + RefPtr<FileChooser> fileChooser = prpFileChooser; + + m_page->setActiveOpenPanelResultListener(WebOpenPanelResultListener::create(m_page, fileChooser.get())); + + WebOpenPanelParameters::Data parameters; + parameters.allowMultipleFiles = fileChooser->allowsMultipleFiles(); +#if ENABLE(DIRECTORY_UPLOAD) + parameters.allowsDirectoryUpload = fileChooser->allowsDirectoryUpload(); +#else + parameters.allowsDirectoryUpload = false; +#endif + parameters.acceptTypes = fileChooser->acceptTypes(); + parameters.filenames = fileChooser->filenames(); + + m_page->send(Messages::WebPageProxy::RunOpenPanel(static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame()->frameID(), parameters)); +} + +void WebChromeClient::chooseIconForFiles(const Vector<String>&, FileChooser*) +{ + notImplemented(); +} + +void WebChromeClient::setCursor(const WebCore::Cursor& cursor) +{ +#if USE(LAZY_NATIVE_CURSOR) + m_page->send(Messages::WebPageProxy::SetCursor(cursor)); +#endif +} + +void WebChromeClient::formStateDidChange(const Node*) +{ + notImplemented(); +} + +void WebChromeClient::formDidFocus(const Node*) +{ + notImplemented(); +} + +void WebChromeClient::formDidBlur(const Node*) +{ + notImplemented(); +} + +bool WebChromeClient::selectItemWritingDirectionIsNatural() +{ + return true; +} + +PassRefPtr<WebCore::PopupMenu> WebChromeClient::createPopupMenu(WebCore::PopupMenuClient* client) const +{ + return WebPopupMenu::create(m_page, client); +} + +PassRefPtr<WebCore::SearchPopupMenu> WebChromeClient::createSearchPopupMenu(WebCore::PopupMenuClient* client) const +{ + return WebSearchPopupMenu::create(m_page, client); +} + +#if ENABLE(CONTEXT_MENUS) +void WebChromeClient::showContextMenu() +{ + m_page->contextMenu()->show(); +} +#endif + +PassOwnPtr<HTMLParserQuirks> WebChromeClient::createHTMLParserQuirks() +{ + notImplemented(); + return 0; +} + +#if USE(ACCELERATED_COMPOSITING) +void WebChromeClient::attachRootGraphicsLayer(Frame*, GraphicsLayer* layer) +{ + if (layer) + m_page->enterAcceleratedCompositingMode(layer); + else + m_page->exitAcceleratedCompositingMode(); +} + +void WebChromeClient::setNeedsOneShotDrawingSynchronization() +{ + notImplemented(); +} + +void WebChromeClient::scheduleCompositingLayerSync() +{ + if (m_page->drawingArea()) + m_page->drawingArea()->scheduleCompositingLayerSync(); +} + +#endif + +#if ENABLE(NOTIFICATIONS) +WebCore::NotificationPresenter* WebChromeClient::notificationPresenter() const +{ + return 0; +} +#endif + +#if ENABLE(TOUCH_EVENTS) +void WebChromeClient::needTouchEvents(bool) +{ +} +#endif + +#if PLATFORM(WIN) +void WebChromeClient::setLastSetCursorToCurrentCursor() +{ +} +#endif + +void WebChromeClient::dispatchViewportDataDidChange(const ViewportArguments& args) const +{ + m_page->send(Messages::WebPageProxy::DidChangeViewportData(args)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h new file mode 100644 index 0000000..44c3658 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * 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 WebChromeClient_h +#define WebChromeClient_h + +#include <WebCore/ChromeClient.h> +#include <WebCore/ViewportArguments.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +class WebFrame; +class WebPage; + +class WebChromeClient : public WebCore::ChromeClient { +public: + WebChromeClient(WebPage* page) + : m_page(page) + { + } + + WebPage* page() const { return m_page; } +private: + virtual void chromeDestroyed(); + + virtual void setWindowRect(const WebCore::FloatRect&); + virtual WebCore::FloatRect windowRect(); + + virtual WebCore::FloatRect pageRect(); + + virtual float scaleFactor(); + + virtual void focus(); + virtual void unfocus(); + + virtual bool canTakeFocus(WebCore::FocusDirection); + virtual void takeFocus(WebCore::FocusDirection); + + virtual void focusedNodeChanged(WebCore::Node*); + virtual void focusedFrameChanged(WebCore::Frame*); + + // The Frame pointer provides the ChromeClient with context about which + // Frame wants to create the new Page. Also, the newly created window + // should not be shown to the user until the ChromeClient of the newly + // created Page has its show method called. + virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&); + virtual void show(); + + virtual bool canRunModal(); + virtual void runModal(); + + virtual void setToolbarsVisible(bool); + virtual bool toolbarsVisible(); + + virtual void setStatusbarVisible(bool); + virtual bool statusbarVisible(); + + virtual void setScrollbarsVisible(bool); + virtual bool scrollbarsVisible(); + + virtual void setMenubarVisible(bool); + virtual bool menubarVisible(); + + virtual void setResizable(bool); + + virtual void addMessageToConsole(WebCore::MessageSource, WebCore::MessageType, WebCore::MessageLevel, const String& message, unsigned int lineNumber, const String& sourceID); + + virtual bool canRunBeforeUnloadConfirmPanel(); + virtual bool runBeforeUnloadConfirmPanel(const String& message, WebCore::Frame* frame); + + virtual void closeWindowSoon(); + + virtual void runJavaScriptAlert(WebCore::Frame*, const String&); + virtual bool runJavaScriptConfirm(WebCore::Frame*, const String&); + virtual bool runJavaScriptPrompt(WebCore::Frame*, const String& message, const String& defaultValue, String& result); + virtual void setStatusbarText(const String&); + virtual bool shouldInterruptJavaScript(); + virtual bool tabsToLinks() const; + + virtual WebCore::IntRect windowResizerRect() const; + + // Methods used by HostWindow. + virtual void invalidateWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); + virtual void scroll(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& scrollRect, const WebCore::IntRect& clipRect); +#if ENABLE(TILED_BACKING_STORE) + virtual void delegatedScrollRequested(const WebCore::IntSize& scrollDelta); +#endif + virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&) const; + virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&) const; + virtual PlatformPageClient platformPageClient() const; + virtual void contentsSizeChanged(WebCore::Frame*, const WebCore::IntSize&) const; + virtual void scrollRectIntoView(const WebCore::IntRect&, const WebCore::ScrollView*) const; // Currently only Mac has a non empty implementation. + // End methods used by HostWindow. + + virtual bool shouldMissingPluginMessageBeButton() const; + virtual void missingPluginButtonClicked(WebCore::Element*) const; + + virtual void scrollbarsModeDidChange() const; + virtual void mouseDidMoveOverElement(const WebCore::HitTestResult&, unsigned modifierFlags); + + virtual void setToolTip(const String&, WebCore::TextDirection); + + virtual void print(WebCore::Frame*); + +#if ENABLE(DATABASE) + virtual void exceededDatabaseQuota(WebCore::Frame*, const String& databaseName); +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); + virtual void reachedApplicationCacheOriginQuota(WebCore::SecurityOrigin*); +#endif + +#if ENABLE(DASHBOARD_SUPPORT) + virtual void dashboardRegionsChanged(); +#endif + + virtual void populateVisitedLinks(); + + virtual WebCore::FloatRect customHighlightRect(WebCore::Node*, const WTF::AtomicString& type, const WebCore::FloatRect& lineRect); + virtual void paintCustomHighlight(WebCore::Node*, const WTF::AtomicString& type, const WebCore::FloatRect& boxRect, const WebCore::FloatRect& lineRect, + bool behindText, bool entireLine); + + virtual bool shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename); + virtual String generateReplacementFile(const String& path); + + virtual bool paintCustomScrollbar(WebCore::GraphicsContext*, const WebCore::FloatRect&, WebCore::ScrollbarControlSize, + WebCore::ScrollbarControlState, WebCore::ScrollbarPart pressedPart, bool vertical, + float value, float proportion, WebCore::ScrollbarControlPartMask); + virtual bool paintCustomScrollCorner(WebCore::GraphicsContext*, const WebCore::FloatRect&); + + // This is an asynchronous call. The ChromeClient can display UI asking the user for permission + // to use Geolococation. The ChromeClient must call Geolocation::setShouldClearCache() appropriately. + virtual void requestGeolocationPermissionForFrame(WebCore::Frame*, WebCore::Geolocation*); + virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*); + + virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>); + virtual void chooseIconForFiles(const Vector<String>&, WebCore::FileChooser*); + + virtual void setCursor(const WebCore::Cursor&); + + // Notification that the given form element has changed. This function + // will be called frequently, so handling should be very fast. + virtual void formStateDidChange(const WebCore::Node*); + + virtual void formDidFocus(const WebCore::Node*); + virtual void formDidBlur(const WebCore::Node*); + + virtual PassOwnPtr<WebCore::HTMLParserQuirks> createHTMLParserQuirks(); + + virtual bool selectItemWritingDirectionIsNatural(); + virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const; + virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const; + +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu(); +#endif + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*); + virtual void setNeedsOneShotDrawingSynchronization(); + virtual void scheduleCompositingLayerSync(); +#endif + +#if ENABLE(NOTIFICATIONS) + virtual WebCore::NotificationPresenter* notificationPresenter() const; +#endif + +#if ENABLE(TOUCH_EVENTS) + virtual void needTouchEvents(bool); +#endif + +#if PLATFORM(WIN) + virtual void setLastSetCursorToCurrentCursor(); +#endif + + virtual void dispatchViewportDataDidChange(const WebCore::ViewportArguments&) const; + + String m_cachedToolTip; + mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame; + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebChromeClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp new file mode 100644 index 0000000..42b60a5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp @@ -0,0 +1,89 @@ +/* + * 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 "WebContextMenuClient.h" + +#include "WebContextMenuItemData.h" +#include "WebPage.h" +#include <WebCore/ContextMenu.h> +#include <WebCore/Frame.h> +#include <WebCore/Page.h> +#include <WebCore/UserGestureIndicator.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +void WebContextMenuClient::contextMenuDestroyed() +{ + delete this; +} + +#if USE(CROSS_PLATFORM_CONTEXT_MENUS) +PassOwnPtr<ContextMenu> WebContextMenuClient::customizeMenu(PassOwnPtr<ContextMenu> menu) +{ + // WebKit2 ignores this client callback and does context menu customization when it is told to show the menu. + return menu; +} +#else +PlatformMenuDescription WebContextMenuClient::getCustomMenuFromDefaultItems(ContextMenu* menu) +{ + // WebKit2 ignores this client callback and does context menu customization when it is told to show the menu. + return menu->platformDescription(); +} +#endif + +void WebContextMenuClient::contextMenuItemSelected(ContextMenuItem*, const ContextMenu*) +{ + notImplemented(); +} + +void WebContextMenuClient::downloadURL(const KURL& url) +{ + // This is handled in the UI process. + ASSERT_NOT_REACHED(); +} + +void WebContextMenuClient::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); + url.append("&ie=UTF-8&oe=UTF-8"); + + if (Page* page = frame->page()) { + UserGestureIndicator indicator(DefinitelyProcessingUserGesture); + page->mainFrame()->loader()->urlSelected(KURL(ParsedURLString, url), String(), 0, false, false, SendReferrer); + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h new file mode 100644 index 0000000..0545a7d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h @@ -0,0 +1,68 @@ +/* + * 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. + */ + +#ifndef WebContextMenuClient_h +#define WebContextMenuClient_h + +#include <WebCore/ContextMenuClient.h> + +namespace WebKit { + +class WebPage; + +class WebContextMenuClient : public WebCore::ContextMenuClient { +public: + WebContextMenuClient(WebPage* page) + : m_page(page) + { + } + +private: + virtual void contextMenuDestroyed(); + +#if USE(CROSS_PLATFORM_CONTEXT_MENUS) + virtual PassOwnPtr<WebCore::ContextMenu> customizeMenu(PassOwnPtr<WebCore::ContextMenu>); +#else + virtual WebCore::PlatformMenuDescription getCustomMenuFromDefaultItems(WebCore::ContextMenu*); +#endif + virtual void contextMenuItemSelected(WebCore::ContextMenuItem*, const WebCore::ContextMenu*); + + virtual void downloadURL(const WebCore::KURL& url); + virtual void searchWithGoogle(const WebCore::Frame*); + virtual void lookUpInDictionary(WebCore::Frame*); + virtual bool isSpeaking(); + virtual void speak(const String&); + virtual void stopSpeaking(); + +#if PLATFORM(MAC) + virtual void searchWithSpotlight(); +#endif + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebContextMenuClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp new file mode 100644 index 0000000..cc61b04 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp @@ -0,0 +1,166 @@ +/* + * 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 "WebDatabaseManager.h" + +#include "Connection.h" +#include "MessageID.h" +#include "OriginAndDatabases.h" +#include "WebCoreArgumentCoders.h" +#include "WebDatabaseManagerProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/DatabaseDetails.h> +#include <WebCore/DatabaseTracker.h> +#include <WebCore/SecurityOrigin.h> + +using namespace WebCore; + +namespace WebKit { + +WebDatabaseManager& WebDatabaseManager::shared() +{ + static WebDatabaseManager& shared = *new WebDatabaseManager; + return shared; +} + +WebDatabaseManager::WebDatabaseManager() +{ + DatabaseTracker::initializeTracker(databaseDirectory()); + DatabaseTracker::tracker().setClient(this); +} + +WebDatabaseManager::~WebDatabaseManager() +{ +} + +void WebDatabaseManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebDatabaseManagerMessage(connection, messageID, arguments); +} + +void WebDatabaseManager::getDatabasesByOrigin(uint64_t callbackID) const +{ + // FIXME: This could be made more efficient by adding a function to DatabaseTracker + // to get both the origins and the Vector of DatabaseDetails for each origin in one + // shot. That would avoid taking the numerous locks this requires. + + Vector<RefPtr<SecurityOrigin> > origins; + DatabaseTracker::tracker().origins(origins); + + Vector<OriginAndDatabases> originAndDatabasesVector; + originAndDatabasesVector.reserveInitialCapacity(origins.size()); + + for (size_t i = 0; i < origins.size(); ++i) { + OriginAndDatabases originAndDatabases; + + Vector<String> nameVector; + if (!DatabaseTracker::tracker().databaseNamesForOrigin(origins[i].get(), nameVector)) + continue; + + Vector<DatabaseDetails> detailsVector; + detailsVector.reserveInitialCapacity(nameVector.size()); + for (size_t j = 0; j < nameVector.size(); j++) { + DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(nameVector[j], origins[i].get()); + if (details.name().isNull()) + continue; + + detailsVector.append(details); + } + + if (detailsVector.isEmpty()) + continue; + + originAndDatabases.originIdentifier = origins[i]->databaseIdentifier(); + originAndDatabases.originQuota = DatabaseTracker::tracker().quotaForOrigin(origins[i].get()); + originAndDatabases.originUsage = DatabaseTracker::tracker().usageForOrigin(origins[i].get()); + originAndDatabases.databases.swap(detailsVector); + originAndDatabasesVector.append(originAndDatabases); + } + + WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidGetDatabasesByOrigin(originAndDatabasesVector, callbackID), 0); +} + +void WebDatabaseManager::getDatabaseOrigins(uint64_t callbackID) const +{ + Vector<RefPtr<SecurityOrigin> > origins; + DatabaseTracker::tracker().origins(origins); + + size_t numOrigins = origins.size(); + + Vector<String> identifiers(numOrigins); + for (size_t i = 0; i < numOrigins; ++i) + identifiers[i] = origins[i]->databaseIdentifier(); + WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidGetDatabaseOrigins(identifiers, callbackID), 0); +} + +void WebDatabaseManager::deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, const String& originIdentifier) const +{ + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); + if (!origin) + return; + + DatabaseTracker::tracker().deleteDatabase(origin.get(), databaseIdentifier); +} + +void WebDatabaseManager::deleteDatabasesForOrigin(const String& originIdentifier) const +{ + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); + if (!origin) + return; + + DatabaseTracker::tracker().deleteOrigin(origin.get()); +} + +void WebDatabaseManager::deleteAllDatabases() const +{ + DatabaseTracker::tracker().deleteAllDatabases(); +} + +void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const +{ + // If the quota is set to a value lower than the current usage, that quota will + // "stick" but no data will be purged to meet the new quota. This will simply + // prevent new data from being added to databases in that origin. + + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); + if (!origin) + return; + + DatabaseTracker::tracker().setQuota(origin.get(), quota); +} + +void WebDatabaseManager::dispatchDidModifyOrigin(SecurityOrigin* origin) +{ + // NOTE: This may be called on a non-main thread. + WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidModifyOrigin(origin->databaseIdentifier()), 0); +} + +void WebDatabaseManager::dispatchDidModifyDatabase(WebCore::SecurityOrigin* origin, const String& databaseIdentifier) +{ + // NOTE: This may be called on a non-main thread. + WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidModifyDatabase(origin->databaseIdentifier(), databaseIdentifier), 0); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h new file mode 100644 index 0000000..4701645 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h @@ -0,0 +1,72 @@ +/* + * 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. + */ + +#ifndef WebDatabaseManager_h +#define WebDatabaseManager_h + +#include "Arguments.h" +#include <WebCore/DatabaseTrackerClient.h> +#include <wtf/Noncopyable.h> +#include <wtf/text/WTFString.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +class MessageID; +} + +namespace WebKit { + +class WebDatabaseManager : public WebCore::DatabaseTrackerClient { + WTF_MAKE_NONCOPYABLE(WebDatabaseManager); +public: + static WebDatabaseManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + WebDatabaseManager(); + virtual ~WebDatabaseManager(); + + // Implemented in generated WebDatabaseManagerMessageReceiver.cpp + void didReceiveWebDatabaseManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void getDatabasesByOrigin(uint64_t callbackID) const; + void getDatabaseOrigins(uint64_t callbackID) const; + void deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, const String& originIdentifier) const; + void deleteDatabasesForOrigin(const String& originIdentifier) const; + void deleteAllDatabases() const; + void setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const; + + // WebCore::DatabaseTrackerClient + virtual void dispatchDidModifyOrigin(WebCore::SecurityOrigin*); + virtual void dispatchDidModifyDatabase(WebCore::SecurityOrigin*, const String& databaseIdentifier); + + String databaseDirectory() const; +}; + +} // namespace WebKit + +#endif // WebDatabaseManager_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.messages.in b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.messages.in new file mode 100644 index 0000000..e928ef6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.messages.in @@ -0,0 +1,30 @@ +# 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. + +messages -> WebDatabaseManager { + void GetDatabasesByOrigin(uint64_t callbackID) + void GetDatabaseOrigins(uint64_t callbackID) + void DeleteDatabaseWithNameForOrigin(WTF::String databaseIdentifier, WTF::String originIdentifier) + void DeleteDatabasesForOrigin(WTF::String originIdentifier) + void DeleteAllDatabases() + void SetQuotaForOrigin(WTF::String originIdentifier, uint64_t quota) +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp new file mode 100644 index 0000000..d11017f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp @@ -0,0 +1,68 @@ +/* + * 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 "WebDragClient.h" + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +void WebDragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*) +{ +} + +void WebDragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) +{ +} + +DragDestinationAction WebDragClient::actionMaskForDrag(DragData*) +{ + return DragDestinationActionAny; +} + +DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint& windowPoint) +{ + return DragSourceActionAny; +} + +void WebDragClient::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) +{ +} + +DragImageRef WebDragClient::createDragImageForLink(KURL&, const String&, Frame*) +{ + notImplemented(); + return 0; +} + +void WebDragClient::dragControllerDestroyed() +{ + delete this; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.h new file mode 100644 index 0000000..ce123c8 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#ifndef WebDragClient_h +#define WebDragClient_h + +#include <WebCore/DragClient.h> + +namespace WebKit { + +class WebPage; + +class WebDragClient : public WebCore::DragClient { +public: + WebDragClient(WebPage* page) + : m_page(page) + { + } + +private: + virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*); + virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*); + virtual WebCore::DragDestinationAction actionMaskForDrag(WebCore::DragData*); + virtual WebCore::DragSourceAction dragSourceActionMaskForPoint(const WebCore::IntPoint& windowPoint); + + virtual void startDrag(WebCore::DragImageRef dragImage, const WebCore::IntPoint& dragImageOrigin, const WebCore::IntPoint& eventPos, WebCore::Clipboard*, WebCore::Frame*, bool linkDrag = false); + virtual WebCore::DragImageRef createDragImageForLink(WebCore::KURL&, const String& label, WebCore::Frame*); + + virtual void dragControllerDestroyed(); + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebDragClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp new file mode 100644 index 0000000..e3db967 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp @@ -0,0 +1,438 @@ +/* + * 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 "WebEditorClient.h" + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +#include "SelectionState.h" +#include "WebFrameLoaderClient.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/ArchiveResource.h> +#include <WebCore/DocumentFragment.h> +#include <WebCore/EditCommand.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/HTMLInputElement.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLTextAreaElement.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/UserTypingGestureIndicator.h> + +using namespace WebCore; +using namespace HTMLNames; + +namespace WebKit { + +void WebEditorClient::pageDestroyed() +{ + delete this; +} + +bool WebEditorClient::shouldDeleteRange(Range* range) +{ + bool result = m_page->injectedBundleEditorClient().shouldDeleteRange(m_page, range); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldShowDeleteInterface(HTMLElement*) +{ + notImplemented(); + return false; +} + +bool WebEditorClient::smartInsertDeleteEnabled() +{ + // FIXME: Why isn't this Mac specific like toggleSmartInsertDeleteEnabled? +#if PLATFORM(MAC) + return m_page->isSmartInsertDeleteEnabled(); +#else + return true; +#endif +} + +bool WebEditorClient::isSelectTrailingWhitespaceEnabled() +{ + notImplemented(); + return false; +} + +bool WebEditorClient::isContinuousSpellCheckingEnabled() +{ + return WebProcess::shared().textCheckerState().isContinuousSpellCheckingEnabled; +} + +void WebEditorClient::toggleContinuousSpellChecking() +{ + notImplemented(); +} + +bool WebEditorClient::isGrammarCheckingEnabled() +{ + return WebProcess::shared().textCheckerState().isGrammarCheckingEnabled; +} + +void WebEditorClient::toggleGrammarChecking() +{ + notImplemented(); +} + +int WebEditorClient::spellCheckerDocumentTag() +{ + notImplemented(); + return false; +} + + +bool WebEditorClient::isEditable() +{ + notImplemented(); + return false; +} + + +bool WebEditorClient::shouldBeginEditing(Range* range) +{ + bool result = m_page->injectedBundleEditorClient().shouldBeginEditing(m_page, range); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldEndEditing(Range* range) +{ + bool result = m_page->injectedBundleEditorClient().shouldEndEditing(m_page, range); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldInsertNode(Node* node, Range* rangeToReplace, EditorInsertAction action) +{ + bool result = m_page->injectedBundleEditorClient().shouldInsertNode(m_page, node, rangeToReplace, action); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldInsertText(const String& text, Range* rangeToReplace, EditorInsertAction action) +{ + bool result = m_page->injectedBundleEditorClient().shouldInsertText(m_page, text.impl(), rangeToReplace, action); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity affinity, bool stillSelecting) +{ + bool result = m_page->injectedBundleEditorClient().shouldChangeSelectedRange(m_page, fromRange, toRange, affinity, stillSelecting); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldApplyStyle(CSSStyleDeclaration* style, Range* range) +{ + bool result = m_page->injectedBundleEditorClient().shouldApplyStyle(m_page, style, range); + notImplemented(); + return result; +} + +bool WebEditorClient::shouldMoveRangeAfterDelete(Range*, Range*) +{ + notImplemented(); + return true; +} + +void WebEditorClient::didBeginEditing() +{ + // FIXME: What good is a notification name, if it's always the same? + static const String WebViewDidBeginEditingNotification = "WebViewDidBeginEditingNotification"; + m_page->injectedBundleEditorClient().didBeginEditing(m_page, WebViewDidBeginEditingNotification.impl()); + notImplemented(); +} + +void WebEditorClient::respondToChangedContents() +{ + static const String WebViewDidChangeNotification = "WebViewDidChangeNotification"; + m_page->injectedBundleEditorClient().didChange(m_page, WebViewDidChangeNotification.impl()); + notImplemented(); +} + +void WebEditorClient::respondToChangedSelection() +{ + static const String WebViewDidChangeSelectionNotification = "WebViewDidChangeSelectionNotification"; + m_page->injectedBundleEditorClient().didChangeSelection(m_page, WebViewDidChangeSelectionNotification.impl()); + Frame* frame = m_page->corePage()->focusController()->focusedFrame(); + if (!frame) + return; + + SelectionState selectionState; + selectionState.isNone = frame->selection()->isNone(); + selectionState.isContentEditable = frame->selection()->isContentEditable(); + selectionState.isInPasswordField = frame->selection()->isInPasswordField(); + selectionState.hasComposition = frame->editor()->hasComposition(); + + WebPage::getLocationAndLengthFromRange(frame->selection()->toNormalizedRange().get(), selectionState.selectedRangeStart, selectionState.selectedRangeLength); + + m_page->send(Messages::WebPageProxy::SelectionStateChanged(selectionState)); + +#if PLATFORM(WIN) + // FIXME: This should also go into the selection state. + if (!frame->editor()->hasComposition() || frame->editor()->ignoreCompositionSelectionChange()) + return; + + unsigned start; + unsigned end; + m_page->send(Messages::WebPageProxy::DidChangeCompositionSelection(frame->editor()->getCompositionSelection(start, end))); +#endif +} + +void WebEditorClient::didEndEditing() +{ + static const String WebViewDidEndEditingNotification = "WebViewDidEndEditingNotification"; + m_page->injectedBundleEditorClient().didEndEditing(m_page, WebViewDidEndEditingNotification.impl()); + notImplemented(); +} + +void WebEditorClient::didWriteSelectionToPasteboard() +{ + notImplemented(); +} + +void WebEditorClient::didSetSelectionTypesForPasteboard() +{ + notImplemented(); +} + +void WebEditorClient::registerCommandForUndo(PassRefPtr<EditCommand> command) +{ + // FIXME: Add assertion that the command being reapplied is the same command that is + // being passed to us. + if (m_page->isInRedo()) + return; + + RefPtr<WebEditCommand> webCommand = WebEditCommand::create(command); + m_page->addWebEditCommand(webCommand->commandID(), webCommand.get()); + uint32_t editAction = static_cast<uint32_t>(webCommand->command()->editingAction()); + + m_page->send(Messages::WebPageProxy::RegisterEditCommandForUndo(webCommand->commandID(), editAction)); +} + +void WebEditorClient::registerCommandForRedo(PassRefPtr<EditCommand>) +{ +} + +void WebEditorClient::clearUndoRedoOperations() +{ + m_page->send(Messages::WebPageProxy::ClearAllEditCommands()); +} + +bool WebEditorClient::canUndo() const +{ + notImplemented(); + return false; +} + +bool WebEditorClient::canRedo() const +{ + notImplemented(); + return false; +} + +void WebEditorClient::undo() +{ + notImplemented(); +} + +void WebEditorClient::redo() +{ + notImplemented(); +} + +#if !PLATFORM(MAC) +void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) +{ + if (m_page->handleEditingKeyboardEvent(event)) + event->setDefaultHandled(); +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent*) +{ + notImplemented(); +} +#endif + +void WebEditorClient::textFieldDidBeginEditing(Element* element) +{ + if (!element->hasTagName(inputTag)) + return; + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame(); + m_page->injectedBundleFormClient().textFieldDidBeginEditing(m_page, static_cast<HTMLInputElement*>(element), webFrame); +} + +void WebEditorClient::textFieldDidEndEditing(Element* element) +{ + if (!element->hasTagName(inputTag)) + return; + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame(); + m_page->injectedBundleFormClient().textFieldDidEndEditing(m_page, static_cast<HTMLInputElement*>(element), webFrame); +} + +void WebEditorClient::textDidChangeInTextField(Element* element) +{ + if (!element->hasTagName(inputTag)) + return; + + if (!UserTypingGestureIndicator::processingUserTypingGesture() || UserTypingGestureIndicator::focusedElementAtGestureStart() != element) + return; + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame(); + m_page->injectedBundleFormClient().textDidChangeInTextField(m_page, static_cast<HTMLInputElement*>(element), webFrame); +} + +void WebEditorClient::textDidChangeInTextArea(Element* element) +{ + if (!element->hasTagName(textareaTag)) + return; + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame(); + m_page->injectedBundleFormClient().textDidChangeInTextArea(m_page, static_cast<HTMLTextAreaElement*>(element), webFrame); +} + +static bool getActionTypeForKeyEvent(KeyboardEvent* event, WKInputFieldActionType& type) +{ + String key = event->keyIdentifier(); + if (key == "Up") + type = WKInputFieldActionTypeMoveUp; + else if (key == "Down") + type = WKInputFieldActionTypeMoveDown; + else if (key == "U+001B") + type = WKInputFieldActionTypeCancel; + else if (key == "U+0009") { + if (event->shiftKey()) + type = WKInputFieldActionTypeInsertBacktab; + else + type = WKInputFieldActionTypeInsertTab; + } else if (key == "Enter") + type = WKInputFieldActionTypeInsertNewline; + else + return false; + + return true; +} + +bool WebEditorClient::doTextFieldCommandFromEvent(Element* element, KeyboardEvent* event) +{ + if (!element->hasTagName(inputTag)) + return false; + + WKInputFieldActionType actionType = static_cast<WKInputFieldActionType>(0); + if (!getActionTypeForKeyEvent(event, actionType)) + return false; + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame(); + return m_page->injectedBundleFormClient().shouldPerformActionInTextField(m_page, static_cast<HTMLInputElement*>(element), actionType, webFrame); +} + +void WebEditorClient::textWillBeDeletedInTextField(Element* element) +{ + if (!element->hasTagName(inputTag)) + return; + + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame(); + m_page->injectedBundleFormClient().shouldPerformActionInTextField(m_page, static_cast<HTMLInputElement*>(element), WKInputFieldActionTypeInsertDelete, webFrame); +} + +void WebEditorClient::ignoreWordInSpellDocument(const String& word) +{ + m_page->send(Messages::WebPageProxy::IgnoreWord(word)); +} + +void WebEditorClient::learnWord(const String& word) +{ + m_page->send(Messages::WebPageProxy::LearnWord(word)); +} + +void WebEditorClient::checkSpellingOfString(const UChar*, int, int*, int*) +{ + notImplemented(); +} + +String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&) +{ + notImplemented(); + return String(); +} + +void WebEditorClient::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*) +{ + notImplemented(); +} + +void WebEditorClient::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) +{ + notImplemented(); +} + +void WebEditorClient::updateSpellingUIWithMisspelledWord(const String& misspelledWord) +{ + m_page->send(Messages::WebPageProxy::UpdateSpellingUIWithMisspelledWord(misspelledWord)); +} + +void WebEditorClient::showSpellingUI(bool) +{ + notImplemented(); +} + +bool WebEditorClient::spellingUIIsShowing() +{ + notImplemented(); + return false; +} + +void WebEditorClient::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) +{ + m_page->sendSync(Messages::WebPageProxy::GetGuessesForWord(word, context), Messages::WebPageProxy::GetGuessesForWord::Reply(guesses)); +} + +void WebEditorClient::willSetInputMethodState() +{ + notImplemented(); +} + +void WebEditorClient::setInputMethodState(bool) +{ + notImplemented(); +} + +void WebEditorClient::requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&) +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h new file mode 100644 index 0000000..40bd8c6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h @@ -0,0 +1,149 @@ +/* + * 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. + */ + +#ifndef WebEditorClient_h +#define WebEditorClient_h + +#include <WebCore/EditorClient.h> + +namespace WebKit { + +class WebPage; + +class WebEditorClient : public WebCore::EditorClient { +public: + WebEditorClient(WebPage* page) + : m_page(page) + { + } + +private: + virtual void pageDestroyed(); + + virtual bool shouldDeleteRange(WebCore::Range*); + virtual bool shouldShowDeleteInterface(WebCore::HTMLElement*); + virtual bool smartInsertDeleteEnabled(); + virtual bool isSelectTrailingWhitespaceEnabled(); + virtual bool isContinuousSpellCheckingEnabled(); + virtual void toggleContinuousSpellChecking(); + virtual bool isGrammarCheckingEnabled(); + virtual void toggleGrammarChecking(); + virtual int spellCheckerDocumentTag(); + + virtual bool isEditable(); + + virtual bool shouldBeginEditing(WebCore::Range*); + virtual bool shouldEndEditing(WebCore::Range*); + virtual bool shouldInsertNode(WebCore::Node*, WebCore::Range*, WebCore::EditorInsertAction); + virtual bool shouldInsertText(const String&, WebCore::Range*, WebCore::EditorInsertAction); + virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity, bool stillSelecting); + + virtual bool shouldApplyStyle(WebCore::CSSStyleDeclaration*, WebCore::Range*); + virtual bool shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*); + + virtual void didBeginEditing(); + virtual void respondToChangedContents(); + virtual void respondToChangedSelection(); + virtual void didEndEditing(); + virtual void didWriteSelectionToPasteboard(); + virtual void didSetSelectionTypesForPasteboard(); + + virtual void registerCommandForUndo(PassRefPtr<WebCore::EditCommand>); + virtual void registerCommandForRedo(PassRefPtr<WebCore::EditCommand>); + virtual void clearUndoRedoOperations(); + + virtual bool canUndo() const; + virtual bool canRedo() const; + + virtual void undo(); + virtual void redo(); + + virtual void handleKeyboardEvent(WebCore::KeyboardEvent*); + virtual void handleInputMethodKeydown(WebCore::KeyboardEvent*); + + virtual void textFieldDidBeginEditing(WebCore::Element*); + virtual void textFieldDidEndEditing(WebCore::Element*); + virtual void textDidChangeInTextField(WebCore::Element*); + virtual bool doTextFieldCommandFromEvent(WebCore::Element*, WebCore::KeyboardEvent*); + virtual void textWillBeDeletedInTextField(WebCore::Element*); + virtual void textDidChangeInTextArea(WebCore::Element*); + +#if PLATFORM(MAC) + virtual NSString *userVisibleString(NSURL *); + virtual WebCore::DocumentFragment* documentFragmentFromAttributedString(NSAttributedString *, Vector< RefPtr<WebCore::ArchiveResource> >&); + virtual void setInsertionPasteboard(NSPasteboard *); + virtual NSURL* canonicalizeURL(NSURL*); + virtual NSURL* canonicalizeURLString(NSString*); +#ifdef BUILDING_ON_TIGER + virtual NSArray *pasteboardTypesForSelection(WebCore::Frame*); +#endif +#endif + +#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + virtual void uppercaseWord(); + virtual void lowercaseWord(); + virtual void capitalizeWord(); + virtual void showSubstitutionsPanel(bool show); + virtual bool substitutionsPanelIsShowing(); + virtual void toggleSmartInsertDelete(); + virtual bool isAutomaticQuoteSubstitutionEnabled(); + virtual void toggleAutomaticQuoteSubstitution(); + virtual bool isAutomaticLinkDetectionEnabled(); + virtual void toggleAutomaticLinkDetection(); + virtual bool isAutomaticDashSubstitutionEnabled(); + virtual void toggleAutomaticDashSubstitution(); + virtual bool isAutomaticTextReplacementEnabled(); + virtual void toggleAutomaticTextReplacement(); + virtual bool isAutomaticSpellingCorrectionEnabled(); + virtual void toggleAutomaticSpellingCorrection(); +#endif + + virtual void ignoreWordInSpellDocument(const String&); + virtual void learnWord(const String&); + virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength); + virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord); + virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength); +#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<WebCore::TextCheckingResult>& results); +#endif + virtual void updateSpellingUIWithGrammarString(const String&, const WebCore::GrammarDetail& detail); + virtual void updateSpellingUIWithMisspelledWord(const String&); + virtual void showSpellingUI(bool show); + virtual bool spellingUIIsShowing(); + virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses); + virtual void willSetInputMethodState(); + virtual void setInputMethodState(bool enabled); + virtual void requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&); +#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings, WebCore::Editor*); + virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel); + virtual bool isShowingCorrectionPanel(); +#endif + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebEditorClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebErrors.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebErrors.h new file mode 100644 index 0000000..ed43c57 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebErrors.h @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#ifndef WebErrors_h +#define WebErrors_h + +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +namespace WebKit { + +WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&); +WebCore::ResourceError blockedError(const WebCore::ResourceRequest&); +WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&); +WebCore::ResourceError interruptForPolicyChangeError(const WebCore::ResourceRequest&); +WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&); +WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&); +WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&); + +} // namespace WebKit + +#endif // WebErrors_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp new file mode 100644 index 0000000..49ce240 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp @@ -0,0 +1,1300 @@ +/* + * 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 "WebFrameLoaderClient.h" + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +#include "AuthenticationManager.h" +#include "DataReference.h" +#include "InjectedBundleUserMessageCoders.h" +#include "PlatformCertificateInfo.h" +#include "PluginView.h" +#include "StringPairVector.h" +#include "WebContextMessages.h" +#include "WebCoreArgumentCoders.h" +#include "WebErrors.h" +#include "WebEvent.h" +#include "WebFrame.h" +#include "WebFrameNetworkingContext.h" +#include "WebNavigationDataStore.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include "WebProcessProxyMessageKinds.h" +#include "WebProcessProxyMessages.h" +#include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSObject.h> +#include <WebCore/Chrome.h> +#include <WebCore/DOMWrapperWorld.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/FormState.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoadRequest.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLAppletElement.h> +#include <WebCore/HTMLFormElement.h> +#include <WebCore/MIMETypeRegistry.h> +#include <WebCore/MouseEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PluginData.h> +#include <WebCore/ProgressTracker.h> +#include <WebCore/ResourceError.h> +#include <WebCore/UIEventWithKeyState.h> +#include <WebCore/Widget.h> +#include <WebCore/WindowFeatures.h> + +using namespace WebCore; + +namespace WebKit { + +WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame) + : m_frame(frame) + , m_hasSentResponseToPluginView(false) + , m_frameHasCustomRepresentation(false) +{ +} + +WebFrameLoaderClient::~WebFrameLoaderClient() +{ +} + +void WebFrameLoaderClient::frameLoaderDestroyed() +{ + m_frame->invalidate(); + + // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe. + m_frame->deref(); +} + +bool WebFrameLoaderClient::hasHTMLView() const +{ + return !m_frameHasCustomRepresentation; +} + +bool WebFrameLoaderClient::hasWebView() const +{ + return m_frame->page(); +} + +void WebFrameLoaderClient::makeRepresentation(DocumentLoader*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::forceLayout() +{ + notImplemented(); +} + +void WebFrameLoaderClient::forceLayoutForNonHTML() +{ + notImplemented(); +} + +void WebFrameLoaderClient::setCopiesOnScroll() +{ + notImplemented(); +} + +void WebFrameLoaderClient::detachedFromParent2() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); + +} + +void WebFrameLoaderClient::detachedFromParent3() +{ + notImplemented(); +} + +void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest& request) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request)); +} + +void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (!webPage->injectedBundleLoaderClient().shouldLoadResourceForFrame(webPage, m_frame, request.url().string())) { + request = ResourceRequest(); + // FIXME: We should probably send a message saying we cancelled the request for the resource. + return; + } + + webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse)); +} + +bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier) +{ + return true; +} + +void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge) +{ + // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet. + // Once we do, we might need to make sure authentication fits with our solution. + + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge); +} + +void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) +{ + notImplemented(); +} + +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) +bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace) +{ + // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet. + // Once we do, we might need to make sure authentication fits with our solution. + + WebPage* webPage = m_frame->page(); + if (!webPage) + return false; + + bool canAuthenticate; + if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate))) + return false; + + return canAuthenticate; +} +#endif + +void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response)); +} + +void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, lengthReceived)); +} + +void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier)); +} + +void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error)); +} + +bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length) +{ + notImplemented(); + return false; +} + +void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String&) +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchDidHandleOnloadEvents() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame); +} + +void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader(); + const String& url = provisionalLoader->url().string(); + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidCancelClientRedirect() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame); +} + +void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double interval, double fireDate) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate); +} + +void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidPushStateWithinPage() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidPopStateWithinPage() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchWillClose() +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchDidReceiveIcon() +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + webPage->findController().hideFindUI(); + + DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader(); + const String& url = provisionalLoader->url().string(); + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData); + + bool loadingSubstituteDataForUnreachableURL = !provisionalLoader->unreachableURL().isNull(); + + webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, loadingSubstituteDataForUnreachableURL, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidChangeIcons() +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchDidCommitLoad() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response(); + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData); + + webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData); + + webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get()))); + + // If we have a load listener, notify it. + if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) + loadListener->didFailLoad(m_frame, error.isCancellation()); +} + +void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get()))); + + // If we have a load listener, notify it. + if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) + loadListener->didFailLoad(m_frame, error.isCancellation()); +} + +void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidFinishLoad() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); + + // If we have a load listener, notify it. + if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) + loadListener->didFinishLoad(m_frame); +} + +void WebFrameLoaderClient::dispatchDidFirstLayout() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return 0; + + // Just call through to the chrome client. + Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction); + if (!newPage) + return 0; + + return newPage->mainFrame(); +} + +void WebFrameLoaderClient::dispatchShow() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->show(); +} + +uint32_t modifiersForNavigationAction(const NavigationAction& navigationAction) +{ + uint32_t modifiers = 0; + if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(navigationAction.event()))) { + if (keyStateEvent->shiftKey()) + modifiers |= WebEvent::ShiftKey; + if (keyStateEvent->ctrlKey()) + modifiers |= WebEvent::ControlKey; + if (keyStateEvent->altKey()) + modifiers |= WebEvent::AltKey; + if (keyStateEvent->metaKey()) + modifiers |= WebEvent::MetaKey; + } + + return modifiers; +} + +static const MouseEvent* findMouseEvent(const Event* event) +{ + for (const Event* e = event; e; e = e->underlyingEvent()) { + if (e->isMouseEvent()) + return static_cast<const MouseEvent*>(e); + } + return 0; +} + +int32_t mouseButtonForNavigationAction(const NavigationAction& navigationAction) +{ + const MouseEvent* mouseEvent = findMouseEvent(navigationAction.event()); + if (!mouseEvent) + return -1; + + if (!mouseEvent->buttonDown()) + return -1; + + return mouseEvent->button(); +} + +void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& MIMEType, const ResourceRequest& request) +{ + if (m_frame->coreFrame()->loader()->documentLoader()->url().isEmpty() && request.url() == blankURL()) { + // WebKit2 loads initial about:blank documents synchronously, without consulting the policy delegate + ASSERT(m_frame->coreFrame()->loader()->stateMachine()->committingFirstRealLoad()); + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); + return; + } + + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + const String& url = request.url().string(); // FIXME: Pass entire request. + + bool receivedPolicyAction; + uint64_t policyAction; + uint64_t downloadID; + if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForMIMEType(m_frame->frameID(), MIMEType, url, listenerID), Messages::WebPageProxy::DecidePolicyForMIMEType::Reply(receivedPolicyAction, policyAction, downloadID))) + return; + + // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback. + if (receivedPolicyAction) + m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); +} + +void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState>, const String& frameName) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + + // FIXME: Pass more than just the navigation action type. + // FIXME: Pass the frame name. + const String& url = request.url().string(); // FIXME: Pass entire request. + + uint32_t navigationType = static_cast<uint32_t>(navigationAction.type()); + uint32_t modifiers = modifiersForNavigationAction(navigationAction); + int32_t mouseButton = mouseButtonForNavigationAction(navigationAction); + + webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), navigationType, modifiers, mouseButton, url, listenerID)); +} + +void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState>) +{ + if (m_frame->coreFrame()->loader()->documentLoader()->url().isEmpty() && request.url() == blankURL()) { + // WebKit2 loads initial about:blank documents synchronously, without consulting the policy delegate + ASSERT(m_frame->coreFrame()->loader()->stateMachine()->committingFirstRealLoad()); + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); + return; + } + + // Always ignore requests with empty URLs. + if (request.isEmpty()) { + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore); + return; + } + + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + + // FIXME: Pass more than just the navigation action type. + const String& url = request.url().string(); // FIXME: Pass entire request. + + uint32_t navigationType = static_cast<uint32_t>(navigationAction.type()); + uint32_t modifiers = modifiersForNavigationAction(navigationAction); + int32_t mouseButton = mouseButtonForNavigationAction(navigationAction); + + webPage->send(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), navigationType, modifiers, mouseButton, url, listenerID)); +} + +void WebFrameLoaderClient::cancelPolicyCheck() +{ + m_frame->invalidatePolicyListener(); +} + +void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError&) +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + // FIXME: Pass more of the form state. + RefPtr<FormState> formState = prpFormState; + + HTMLFormElement* form = formState->form(); + WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame(); + const Vector<std::pair<String, String> >& values = formState->textFieldValues(); + + RefPtr<APIObject> userData; + webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData); + + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + StringPairVector valuesVector(values); + + webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error) +{ + if (!m_pluginView) + return; + + m_pluginView->manualLoadDidFail(error); + m_pluginView = 0; + m_hasSentResponseToPluginView = false; +} + +void WebFrameLoaderClient::willChangeEstimatedProgress() +{ + notImplemented(); +} + +void WebFrameLoaderClient::didChangeEstimatedProgress() +{ + notImplemented(); +} + +void WebFrameLoaderClient::postProgressStartedNotification() +{ + if (WebPage* webPage = m_frame->page()) + webPage->send(Messages::WebPageProxy::DidStartProgress()); +} + +void WebFrameLoaderClient::postProgressEstimateChangedNotification() +{ + if (WebPage* webPage = m_frame->page()) { + double progress = webPage->corePage()->progress()->estimatedProgress(); + webPage->send(Messages::WebPageProxy::DidChangeProgress(progress)); + + } +} + +void WebFrameLoaderClient::postProgressFinishedNotification() +{ + if (WebPage* webPage = m_frame->page()) + webPage->send(Messages::WebPageProxy::DidFinishProgress()); +} + +void WebFrameLoaderClient::setMainFrameDocumentReady(bool) +{ + notImplemented(); +} + +void WebFrameLoaderClient::startDownload(const ResourceRequest& request) +{ + m_frame->startDownload(request); +} + +void WebFrameLoaderClient::willChangeTitle(DocumentLoader*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::didChangeTitle(DocumentLoader*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length) +{ + // If we're loading a custom representation, we don't want to hand off the data to WebCore. + if (m_frameHasCustomRepresentation) + return; + + if (!m_pluginView) + loader->commitData(data, length); + + // If the document is a stand-alone media document, now is the right time to cancel the WebKit load. + // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>. + if (m_frame->coreFrame()->document()->isMediaDocument()) + loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); + + // Calling commitData did not create the plug-in view. + if (!m_pluginView) + return; + + if (!m_hasSentResponseToPluginView) { + m_pluginView->manualLoadDidReceiveResponse(loader->response()); + // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in + // setting up this stream can cause the main document load to be cancelled, setting m_pluginView + // to null + if (!m_pluginView) + return; + m_hasSentResponseToPluginView = true; + } + m_pluginView->manualLoadDidReceiveData(data, length); +} + +void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) +{ + if (!m_pluginView) { + committedLoad(loader, 0, 0); + + if (m_frameHasCustomRepresentation) { + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData(); + CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0); + + webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(dataReference)); + } + + return; + } + + m_pluginView->manualLoadDidFinishLoading(); + m_pluginView = 0; + m_hasSentResponseToPluginView = false; +} + +void WebFrameLoaderClient::updateGlobalHistory() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); + + WebNavigationDataStore data; + data.url = loader->urlForHistory().string(); + data.title = loader->title(); + + WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0); +} + +void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); + ASSERT(loader->unreachableURL().isEmpty()); + + // Client redirect + if (!loader->clientRedirectSourceForHistory().isNull()) { + WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(), + loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0); + } + + // Server redirect + if (!loader->serverRedirectSourceForHistory().isNull()) { + WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(), + loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0); + } +} + +bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const +{ + notImplemented(); + return true; +} + +void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const +{ + notImplemented(); +} + +void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const +{ + notImplemented(); +} + +void WebFrameLoaderClient::didDisplayInsecureContent() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData); + + webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData); + + webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request) +{ + return WebKit::cancelledError(request); +} + +ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request) +{ + return WebKit::blockedError(request); +} + +ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request) +{ + return WebKit::cannotShowURLError(request); +} + +ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request) +{ + return WebKit::interruptForPolicyChangeError(request); +} + +ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response) +{ + return WebKit::cannotShowMIMETypeError(response); +} + +ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response) +{ + return WebKit::fileDoesNotExistError(response); +} + +ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response) +{ + return WebKit::pluginWillHandleLoadError(response); +} + +bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error) +{ + DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest()))); + DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse()))); + + if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain()) + return false; + + if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain()) + return false; + + return true; +} + +bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const +{ + notImplemented(); + return true; +} + +bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const +{ + notImplemented(); + return true; +} + +bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const +{ + return true; +} + +bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const +{ + notImplemented(); + return false; +} + +String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const +{ + notImplemented(); + return String(); +} + +void WebFrameLoaderClient::frameLoadCompleted() +{ + notImplemented(); +} + +void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::restoreViewState() +{ + notImplemented(); +} + +void WebFrameLoaderClient::provisionalLoadStarted() +{ + notImplemented(); +} + +void WebFrameLoaderClient::didFinishLoad() +{ + // If we have a load listener, notify it. + if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) + loadListener->didFinishLoad(m_frame); +} + +void WebFrameLoaderClient::prepareForDataSourceReplacement() +{ + notImplemented(); +} + +PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data) +{ + return DocumentLoader::create(request, data); +} + +void WebFrameLoaderClient::setTitle(const String& title, const KURL& url) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(), + title, url.string(), m_frame->frameID()), 0); +} + +String WebFrameLoaderClient::userAgent(const KURL&) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return String(); + + return webPage->userAgent(); +} + +void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*) +{ +} + +void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) +{ +} + +void WebFrameLoaderClient::transitionToCommittedForNewPage() +{ + WebPage* webPage = m_frame->page(); + Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white; + + bool isMainFrame = webPage->mainFrame() == m_frame; + +#if ENABLE(TILED_BACKING_STORE) + IntSize currentVisibleContentSize = m_frame->coreFrame()->view() ? m_frame->coreFrame()->view()->actualVisibleContentRect().size() : IntSize(); + m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, webPage->resizesToContentsLayoutSize(), isMainFrame && webPage->resizesToContentsEnabled()); + + if (isMainFrame && webPage->resizesToContentsEnabled()) { + m_frame->coreFrame()->view()->setDelegatesScrolling(true); + m_frame->coreFrame()->view()->setPaintsEntireContents(true); + } + + // The HistoryController will update the scroll position later if needed. + m_frame->coreFrame()->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize)); +#else + const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType(); + m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType); + + m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, IntSize(), false); +#endif + + m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground()); +} + +void WebFrameLoaderClient::didSaveToPageCache() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (m_frame->isMainFrame()) + return; + + webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID())); +} + +void WebFrameLoaderClient::didRestoreFromPageCache() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (m_frame->isMainFrame()) + return; + + WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame(); + webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID())); +} + +void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value)); +} + +bool WebFrameLoaderClient::canCachePage() const +{ + // We cannot cache frames that have custom representations because they are + // rendered in the UIProcess. + return !m_frameHasCustomRepresentation; +} + +void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response) +{ + m_frame->convertHandleToDownload(handle, request, initialRequest, response); +} + +PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, + const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) +{ + WebPage* webPage = m_frame->page(); + + RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement); + + Frame* coreSubframe = subframe->coreFrame(); + + // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. + m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe); + + // The frame's onload handler may have removed it from the document. + if (!coreSubframe->tree()->parent()) + return 0; + + return coreSubframe; +} + +void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) +{ + notImplemented(); +} + +PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) +{ + ASSERT(paramNames.size() == paramValues.size()); + + WebPage* webPage = m_frame->page(); + ASSERT(webPage); + + Plugin::Parameters parameters; + parameters.url = url; + parameters.names = paramNames; + parameters.values = paramValues; + parameters.mimeType = mimeType; + parameters.loadManually = loadManually; + + // <rdar://problem/8440903>: AppleConnect has a bug where it does not + // understand the parameter names specified in the <object> element that + // embeds its plug-in. This hack works around the issue by converting the + // parameter names to lowercase before passing them to the plug-in. + // FIXME: This workaround should be dependent on site-specific quirks being + // enabled. This requires adding this setting to WebKit2's WebPreferences + // implementation. See <https://bugs.webkit.org/show_bug.cgi?id=46076>. + if (equalIgnoringCase(mimeType, "application/x-snkp")) { + for (size_t i = 0; i < paramNames.size(); ++i) + parameters.names[i] = paramNames[i].lower(); + } + + RefPtr<Plugin> plugin = webPage->createPlugin(parameters); + if (!plugin) + return 0; + + return PluginView::create(pluginElement, plugin.release(), parameters); +} + +void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) +{ + ASSERT(!m_pluginView); + ASSERT(pluginWidget); + + m_pluginView = static_cast<PluginView*>(pluginWidget); +} + +PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) +{ + return createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, "application/x-java-applet", false); +} + +ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn) +{ + // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code + // is consolidated. + + String mimeType = mimeTypeIn; + if (mimeType.isEmpty()) + mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1)); + + if (mimeType.isEmpty()) + return ObjectContentFrame; + + if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) + return WebCore::ObjectContentImage; + + if (WebPage* webPage = m_frame->page()) { + if (PluginData* pluginData = webPage->corePage()->pluginData()) { + if (pluginData->supportsMimeType(mimeType)) + return ObjectContentNetscapePlugin; + } + } + + if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) + return ObjectContentFrame; + + return ObjectContentNone; +} + +String WebFrameLoaderClient::overrideMediaType() const +{ + notImplemented(); + return String(); +} + +void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world); +} + +void WebFrameLoaderClient::documentElementAvailable() +{ + notImplemented(); +} + +void WebFrameLoaderClient::didPerformFirstNavigation() const +{ + notImplemented(); +} + +void WebFrameLoaderClient::registerForIconNotification(bool listen) +{ + notImplemented(); +} + +#if PLATFORM(MAC) + +RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() +{ + return m_frame->page()->accessibilityRemoteObject(); +} + +#if ENABLE(MAC_JAVA_BRIDGE) +jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; } +#endif +NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const +{ + return response; +} + +#endif +#if USE(CFNETWORK) +bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length) +{ + return true; +} + +#endif + +bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const +{ + notImplemented(); + return false; +} + +PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext() +{ + return WebFrameNetworkingContext::create(m_frame->coreFrame()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h new file mode 100644 index 0000000..29c8bdd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h @@ -0,0 +1,230 @@ +/* + * 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. + */ + +#ifndef WebFrameLoaderClient_h +#define WebFrameLoaderClient_h + +#include <WebCore/FrameLoaderClient.h> + +namespace WebKit { + +class PluginView; +class WebFrame; + +class WebFrameLoaderClient : public WebCore::FrameLoaderClient { +public: + WebFrameLoaderClient(WebFrame*); + ~WebFrameLoaderClient(); + + WebFrame* webFrame() const { return m_frame; } + + bool frameHasCustomRepresentation() const { return m_frameHasCustomRepresentation; } + +private: + virtual void frameLoaderDestroyed(); + + virtual bool hasHTMLView() const; + virtual bool hasWebView() const; + + virtual void makeRepresentation(WebCore::DocumentLoader*); + virtual void forceLayout(); + virtual void forceLayoutForNonHTML(); + + virtual void setCopiesOnScroll(); + + virtual void detachedFromParent2(); + virtual void detachedFromParent3(); + + virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&); + + virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse); + virtual bool shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long identifier); + virtual void dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&); + virtual void dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&); +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + virtual bool canAuthenticateAgainstProtectionSpace(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ProtectionSpace&); +#endif + virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&); + virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived); + virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier); + virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&); + virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length); + virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const WTF::String&); + + virtual void dispatchDidHandleOnloadEvents(); + virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); + virtual void dispatchDidCancelClientRedirect(); + virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate); + virtual void dispatchDidChangeLocationWithinPage(); + virtual void dispatchDidPushStateWithinPage(); + virtual void dispatchDidReplaceStateWithinPage(); + virtual void dispatchDidPopStateWithinPage(); + virtual void dispatchWillClose(); + virtual void dispatchDidReceiveIcon(); + virtual void dispatchDidStartProvisionalLoad(); + virtual void dispatchDidReceiveTitle(const String& title); + virtual void dispatchDidChangeIcons(); + virtual void dispatchDidCommitLoad(); + virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&); + virtual void dispatchDidFailLoad(const WebCore::ResourceError&); + virtual void dispatchDidFinishDocumentLoad(); + virtual void dispatchDidFinishLoad(); + virtual void dispatchDidFirstLayout(); + virtual void dispatchDidFirstVisuallyNonEmptyLayout(); + + virtual WebCore::Frame* dispatchCreatePage(const WebCore::NavigationAction&); + virtual void dispatchShow(); + + virtual void dispatchDecidePolicyForMIMEType(WebCore::FramePolicyFunction, const String& MIMEType, const WebCore::ResourceRequest&); + virtual void dispatchDecidePolicyForNewWindowAction(WebCore::FramePolicyFunction, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<WebCore::FormState>, const String& frameName); + virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<WebCore::FormState>); + virtual void cancelPolicyCheck(); + + virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&); + + virtual void dispatchWillSendSubmitEvent(WebCore::HTMLFormElement*) { } + virtual void dispatchWillSubmitForm(WebCore::FramePolicyFunction, PassRefPtr<WebCore::FormState>); + + virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*); + virtual void revertToProvisionalState(WebCore::DocumentLoader*); + virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&); + + // Maybe these should go into a ProgressTrackerClient some day + virtual void willChangeEstimatedProgress(); + virtual void didChangeEstimatedProgress(); + virtual void postProgressStartedNotification(); + virtual void postProgressEstimateChangedNotification(); + virtual void postProgressFinishedNotification(); + + virtual void setMainFrameDocumentReady(bool); + + virtual void startDownload(const WebCore::ResourceRequest&); + + virtual void willChangeTitle(WebCore::DocumentLoader*); + virtual void didChangeTitle(WebCore::DocumentLoader*); + + virtual void committedLoad(WebCore::DocumentLoader*, const char*, int); + virtual void finishedLoading(WebCore::DocumentLoader*); + + virtual void updateGlobalHistory(); + virtual void updateGlobalHistoryRedirectLinks(); + + virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const; + virtual void dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const; + virtual void dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const; + virtual void dispatchDidChangeBackForwardIndex() const; + + virtual void didDisplayInsecureContent(); + virtual void didRunInsecureContent(WebCore::SecurityOrigin*); + + virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&); + virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&); + virtual WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&); + virtual WebCore::ResourceError interruptForPolicyChangeError(const WebCore::ResourceRequest&); + + virtual WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&); + virtual WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&); + virtual WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&); + + virtual bool shouldFallBack(const WebCore::ResourceError&); + + virtual bool canHandleRequest(const WebCore::ResourceRequest&) const; + virtual bool canShowMIMEType(const String& MIMEType) const; + virtual bool canShowMIMETypeAsHTML(const String& MIMEType) const; + virtual bool representationExistsForURLScheme(const String& URLScheme) const; + virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const; + + virtual void frameLoadCompleted(); + virtual void saveViewStateToItem(WebCore::HistoryItem*); + virtual void restoreViewState(); + virtual void provisionalLoadStarted(); + virtual void didFinishLoad(); + virtual void prepareForDataSourceReplacement(); + + virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); + virtual void setTitle(const String& title, const WebCore::KURL&); + + virtual String userAgent(const WebCore::KURL&); + + virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*); + virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*); + virtual void transitionToCommittedForNewPage(); + + virtual void didSaveToPageCache(); + virtual void didRestoreFromPageCache(); + + virtual void dispatchDidBecomeFrameset(bool); + + virtual bool canCachePage() const; + virtual void download(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&); + + virtual PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL& url, const String& name, WebCore::HTMLFrameOwnerElement* ownerElement, + const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); + virtual void didTransferChildFrameToNewDocument(WebCore::Page*); + virtual void transferLoadingResourceFromPage(unsigned long, WebCore::DocumentLoader*, const WebCore::ResourceRequest&, WebCore::Page*); + + virtual PassRefPtr<WebCore::Widget> createPlugin(const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually); + virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget); + + virtual PassRefPtr<WebCore::Widget> createJavaAppletWidget(const WebCore::IntSize&, WebCore::HTMLAppletElement*, const WebCore::KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues); + + virtual WebCore::ObjectContentType objectContentType(const WebCore::KURL& url, const String& mimeType); + virtual String overrideMediaType() const; + + virtual void dispatchDidClearWindowObjectInWorld(WebCore::DOMWrapperWorld*); + + virtual void documentElementAvailable(); + virtual void didPerformFirstNavigation() const; // "Navigation" here means a transition from one page to another that ends up in the back/forward list. + + virtual void registerForIconNotification(bool listen = true); + +#if PLATFORM(MAC) + virtual RemoteAXObjectRef accessibilityRemoteObject(); + +#if ENABLE(MAC_JAVA_BRIDGE) + virtual jobject javaApplet(NSView*); +#endif + virtual NSCachedURLResponse* willCacheResponse(WebCore::DocumentLoader*, unsigned long identifier, NSCachedURLResponse*) const; +#endif +#if USE(CFNETWORK) + virtual bool shouldCacheResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&, const unsigned char* data, unsigned long long length); +#endif + + virtual bool shouldUsePluginDocument(const String& /*mimeType*/) const; + + virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext(); + + WebFrame* m_frame; + RefPtr<PluginView> m_pluginView; + bool m_hasSentResponseToPluginView; + bool m_frameHasCustomRepresentation; +}; + +uint32_t modifiersForNavigationAction(const WebCore::NavigationAction&); +int32_t mouseButtonForNavigationAction(const WebCore::NavigationAction&); + +} // namespace WebKit + +#endif // WebFrameLoaderClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.cpp new file mode 100644 index 0000000..8701022 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 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 "WebGeolocationClient.h" + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +#include "WebGeolocationManager.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Geolocation.h> +#include <WebCore/GeolocationPosition.h> + +using namespace WebCore; + +namespace WebKit { + +WebGeolocationClient::~WebGeolocationClient() +{ +} + +void WebGeolocationClient::geolocationDestroyed() +{ + WebProcess::shared().geolocationManager().unregisterWebPage(m_page); + delete this; +} + +void WebGeolocationClient::startUpdating() +{ + WebProcess::shared().geolocationManager().registerWebPage(m_page); +} + +void WebGeolocationClient::stopUpdating() +{ + WebProcess::shared().geolocationManager().unregisterWebPage(m_page); +} + +void WebGeolocationClient::setEnableHighAccuracy(bool) +{ +} + +GeolocationPosition* WebGeolocationClient::lastPosition() +{ + // FIXME: Implement this. + return 0; +} + +void WebGeolocationClient::requestPermission(Geolocation* geolocation) +{ + m_page->geolocationPermissionRequestManager().startRequestForGeolocation(geolocation); +} + +void WebGeolocationClient::cancelPermissionRequest(Geolocation* geolocation) +{ + m_page->geolocationPermissionRequestManager().cancelRequestForGeolocation(geolocation); +} + +} // namespace WebKit + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.h new file mode 100644 index 0000000..e72124d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2011 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 WebGeolocationClient_h +#define WebGeolocationClient_h + +#if ENABLE(CLIENT_BASED_GEOLOCATION) + +#include <WebCore/GeolocationClient.h> + +namespace WebKit { + +class WebPage; + +class WebGeolocationClient : public WebCore::GeolocationClient { +public: + WebGeolocationClient(WebPage* page) + : m_page(page) + { + } + + virtual ~WebGeolocationClient(); + +private: + virtual void geolocationDestroyed(); + + virtual void startUpdating(); + virtual void stopUpdating(); + virtual void setEnableHighAccuracy(bool); + + virtual WebCore::GeolocationPosition* lastPosition(); + + virtual void requestPermission(WebCore::Geolocation*); + virtual void cancelPermissionRequest(WebCore::Geolocation*); + + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) + +#endif // WebGeolocationClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp new file mode 100644 index 0000000..ddd1fa8 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp @@ -0,0 +1,91 @@ +/* + * 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 "WebInspectorClient.h" + +#if ENABLE(INSPECTOR) + +#include "WebInspectorFrontendClient.h" +#include "WebInspector.h" +#include "WebPage.h" +#include <WebCore/InspectorController.h> +#include <WebCore/Page.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +void WebInspectorClient::inspectorDestroyed() +{ + delete this; +} + +void WebInspectorClient::openInspectorFrontend(InspectorController*) +{ + WebPage* inspectorPage = m_page->inspector()->createInspectorPage(); + ASSERT(inspectorPage); + if (!inspectorPage) + return; + + inspectorPage->corePage()->inspectorController()->setInspectorFrontendClient(adoptPtr(new WebInspectorFrontendClient(m_page, inspectorPage))); +} + +void WebInspectorClient::highlight(Node*) +{ + notImplemented(); +} + +void WebInspectorClient::hideHighlight() +{ + notImplemented(); +} + +void WebInspectorClient::populateSetting(const String& key, String*) +{ + notImplemented(); +} + +void WebInspectorClient::storeSetting(const String&, const String&) +{ + notImplemented(); +} + +bool WebInspectorClient::sendMessageToFrontend(const String& message) +{ + WebInspector* inspector = m_page->inspector(); + if (!inspector) + return false; + WebPage* inspectorPage = inspector->inspectorPage(); + if (!inspectorPage) + return false; + return doDispatchMessageOnFrontendPage(inspectorPage->corePage(), message); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h new file mode 100644 index 0000000..7a12206 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#ifndef WebInspectorClient_h +#define WebInspectorClient_h + +#if ENABLE(INSPECTOR) + +#include <WebCore/InspectorClient.h> + +namespace WebKit { + +class WebPage; + +class WebInspectorClient : public WebCore::InspectorClient { +public: + WebInspectorClient(WebPage* page) + : m_page(page) + { + } + +private: + virtual void inspectorDestroyed(); + + virtual void openInspectorFrontend(WebCore::InspectorController*); + + virtual void highlight(WebCore::Node*); + virtual void hideHighlight(); + + virtual void populateSetting(const String& key, String* value); + virtual void storeSetting(const String& key, const String& value); + + virtual bool sendMessageToFrontend(const String&); + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) + +#endif // WebInspectorClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.cpp new file mode 100644 index 0000000..28d3b3d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.cpp @@ -0,0 +1,103 @@ +/* + * 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 "WebInspectorFrontendClient.h" + +#if ENABLE(INSPECTOR) + +#include "WebInspector.h" +#include "WebPage.h" +#include <WebCore/Page.h> +#include <wtf/text/WTFString.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebKit { + +WebInspectorFrontendClient::WebInspectorFrontendClient(WebPage* page, WebPage* inspectorPage) + : InspectorFrontendClientLocal(page->corePage()->inspectorController(), inspectorPage->corePage()) + , m_page(page) +{ +} + +void WebInspectorFrontendClient::frontendLoaded() +{ + InspectorFrontendClientLocal::frontendLoaded(); + + m_page->inspector()->didLoadInspectorPage(); +} + +String WebInspectorFrontendClient::localizedStringsURL() +{ + return m_page->inspector()->localizedStringsURL(); +} + +String WebInspectorFrontendClient::hiddenPanels() +{ + notImplemented(); + return String(); +} + +void WebInspectorFrontendClient::bringToFront() +{ + notImplemented(); +} + +void WebInspectorFrontendClient::closeWindow() +{ + m_page->inspector()->didClose(); +} + +void WebInspectorFrontendClient::disconnectFromBackend() +{ + m_page->inspector()->didClose(); +} + +void WebInspectorFrontendClient::attachWindow() +{ + notImplemented(); +} + +void WebInspectorFrontendClient::detachWindow() +{ + notImplemented(); +} + +void WebInspectorFrontendClient::setAttachedWindowHeight(unsigned) +{ + notImplemented(); +} + +void WebInspectorFrontendClient::inspectedURLChanged(const String&) +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.h new file mode 100644 index 0000000..48b4de9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#ifndef WebInspectorFrontendClient_h +#define WebInspectorFrontendClient_h + +#if ENABLE(INSPECTOR) + +#include <WebCore/InspectorFrontendClientLocal.h> + +namespace WebKit { + +class WebPage; + +class WebInspectorFrontendClient : public WebCore::InspectorFrontendClientLocal { +public: + WebInspectorFrontendClient(WebPage* page, WebPage* inspectorPage); + +private: + virtual void frontendLoaded(); + + virtual String localizedStringsURL(); + virtual String hiddenPanels(); + + virtual void bringToFront(); + virtual void closeWindow(); + virtual void disconnectFromBackend(); + + virtual void attachWindow(); + virtual void detachWindow(); + virtual void setAttachedWindowHeight(unsigned); + + virtual void inspectedURLChanged(const String&); + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) + +#endif // WebInspectorFrontendClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp new file mode 100644 index 0000000..4567f35 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp @@ -0,0 +1,908 @@ +/* + * 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 "WebPlatformStrategies.h" + +#if USE(PLATFORM_STRATEGIES) + +#include "NotImplemented.h" +#include "PluginInfoStore.h" +#include "WebContextMessages.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcess.h" +#include <WebCore/Page.h> +#include <WebCore/PageGroup.h> +#include <wtf/MathExtras.h> +#include <wtf/text/CString.h> + +#if PLATFORM(CF) +#include <wtf/RetainPtr.h> +#endif + +// FIXME (WebKit2) <rdar://problem/8728860> WebKit2 needs to be localized +#define UI_STRING(string, description) String::fromUTF8(string, strlen(string)) +#define UI_STRING_KEY(string, key, description) String::fromUTF8(string, strlen(string)) + +using namespace WebCore; + +namespace WebKit { + +// We can't use String::format for two reasons: +// 1) It doesn't handle non-ASCII characters in the format string. +// 2) It doesn't handle the %2$d syntax. +// Note that because |format| is used as the second parameter to va_start, it cannot be a reference +// type according to section 18.7/3 of the C++ N1905 standard. +static String formatLocalizedString(String format, ...) +{ +#if PLATFORM(CF) + va_list arguments; + va_start(arguments, format); + RetainPtr<CFStringRef> formatCFString(AdoptCF, format.createCFString()); + RetainPtr<CFStringRef> result(AdoptCF, CFStringCreateWithFormatAndArguments(0, 0, formatCFString.get(), arguments)); + va_end(arguments); + return result.get(); +#else + notImplemented(); + return format; +#endif +} + +void WebPlatformStrategies::initialize() +{ + DEFINE_STATIC_LOCAL(WebPlatformStrategies, platformStrategies, ()); + setPlatformStrategies(&platformStrategies); +} + +WebPlatformStrategies::WebPlatformStrategies() + : m_pluginCacheIsPopulated(false) + , m_shouldRefreshPlugins(false) +{ +} + +// PluginStrategy + +PluginStrategy* WebPlatformStrategies::createPluginStrategy() +{ + return this; +} + +LocalizationStrategy* WebPlatformStrategies::createLocalizationStrategy() +{ + return this; +} + +VisitedLinkStrategy* WebPlatformStrategies::createVisitedLinkStrategy() +{ + return this; +} + +// PluginStrategy + +void WebPlatformStrategies::populatePluginCache() +{ + if (m_pluginCacheIsPopulated) + return; + + ASSERT(m_cachedPlugins.isEmpty()); + + Vector<PluginInfo> plugins; + + // FIXME: Should we do something in case of error here? + WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPlugins(m_shouldRefreshPlugins), + Messages::WebContext::GetPlugins::Reply(plugins), 0); + + m_cachedPlugins.swap(plugins); + + m_shouldRefreshPlugins = false; + m_pluginCacheIsPopulated = true; +} + +void WebPlatformStrategies::refreshPlugins() +{ + m_cachedPlugins.clear(); + m_pluginCacheIsPopulated = false; + m_shouldRefreshPlugins = true; + + populatePluginCache(); +} + +void WebPlatformStrategies::getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>& plugins) +{ + populatePluginCache(); + plugins = m_cachedPlugins; +} + +// LocalizationStrategy + +String WebPlatformStrategies::inputElementAltText() +{ + return UI_STRING_KEY("Submit", "Submit (input element)", "alt text for <input> elements with no alt, title, or value"); +} + +String WebPlatformStrategies::resetButtonDefaultLabel() +{ + return UI_STRING("Reset", "default label for Reset buttons in forms on web pages"); +} + +String WebPlatformStrategies::searchableIndexIntroduction() +{ + return UI_STRING("This is a searchable index. Enter search keywords: ", + "text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'"); +} + +String WebPlatformStrategies::submitButtonDefaultLabel() +{ + return UI_STRING("Submit", "default label for Submit buttons in forms on web pages"); +} + +String WebPlatformStrategies::fileButtonChooseFileLabel() +{ + return UI_STRING("Choose File", "title for file button used in HTML forms"); +} + +String WebPlatformStrategies::fileButtonNoFileSelectedLabel() +{ + return UI_STRING("no file selected", "text to display in file button used in HTML forms when no file is selected"); +} + +#if PLATFORM(MAC) +String WebPlatformStrategies::copyImageUnknownFileLabel() +{ + return UI_STRING("unknown", "Unknown filename"); +} +#endif + +#if ENABLE(CONTEXT_MENUS) + +String WebPlatformStrategies::contextMenuItemTagOpenLinkInNewWindow() +{ + return UI_STRING("Open Link in New Window", "Open in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagDownloadLinkToDisk() +{ + return UI_STRING("Download Linked File", "Download Linked File context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyLinkToClipboard() +{ + return UI_STRING("Copy Link", "Copy Link context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenImageInNewWindow() +{ + return UI_STRING("Open Image in New Window", "Open Image in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagDownloadImageToDisk() +{ + return UI_STRING("Download Image", "Download Image context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyImageToClipboard() +{ + return UI_STRING("Copy Image", "Copy Image context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenVideoInNewWindow() +{ + return UI_STRING("Open Video in New Window", "Open Video in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenAudioInNewWindow() +{ + return UI_STRING("Open Audio in New Window", "Open Audio in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyVideoLinkToClipboard() +{ + return UI_STRING("Copy Video Address", "Copy Video Address Location context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopyAudioLinkToClipboard() +{ + return UI_STRING("Copy Audio Address", "Copy Audio Address Location context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagToggleMediaControls() +{ + return UI_STRING("Controls", "Media Controls context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagToggleMediaLoop() +{ + return UI_STRING("Loop", "Media Loop context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagEnterVideoFullscreen() +{ + return UI_STRING("Enter Fullscreen", "Video Enter Fullscreen context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMediaPlay() +{ + return UI_STRING("Play", "Media Play context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMediaPause() +{ + return UI_STRING("Pause", "Media Pause context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMediaMute() +{ + return UI_STRING("Mute", "Media Mute context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenFrameInNewWindow() +{ + return UI_STRING("Open Frame in New Window", "Open Frame in New Window context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCopy() +{ + return UI_STRING("Copy", "Copy context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagGoBack() +{ + return UI_STRING("Back", "Back context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagGoForward() +{ + return UI_STRING("Forward", "Forward context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagStop() +{ + return UI_STRING("Stop", "Stop context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagReload() +{ + return UI_STRING("Reload", "Reload context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCut() +{ + return UI_STRING("Cut", "Cut context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagPaste() +{ + return UI_STRING("Paste", "Paste context menu item"); +} + +#if PLATFORM(GTK) + +String WebPlatformStrategies::contextMenuItemTagDelete() +{ + notImplemented(); + return "Delete"; +} + +String WebPlatformStrategies::contextMenuItemTagInputMethods() +{ + notImplemented(); + return "Input Methods"; +} + +String WebPlatformStrategies::contextMenuItemTagUnicode() +{ + notImplemented(); + return "Unicode"; +} + +#endif + +#if PLATFORM(GTK) || PLATFORM(QT) + +String WebPlatformStrategies::contextMenuItemTagSelectAll() +{ + notImplemented(); + return "Select All"; +} + +#endif + +String WebPlatformStrategies::contextMenuItemTagNoGuessesFound() +{ + return UI_STRING("No Guesses Found", "No Guesses Found context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagIgnoreSpelling() +{ + return UI_STRING("Ignore Spelling", "Ignore Spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagLearnSpelling() +{ + return UI_STRING("Learn Spelling", "Learn Spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSearchWeb() +{ + return UI_STRING("Search in Google", "Search in Google context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagLookUpInDictionary() +{ + return UI_STRING("Look Up in Dictionary", "Look Up in Dictionary context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOpenLink() +{ + return UI_STRING("Open Link", "Open Link context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagIgnoreGrammar() +{ + return UI_STRING("Ignore Grammar", "Ignore Grammar context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSpellingMenu() +{ + return UI_STRING("Spelling and Grammar", "Spelling and Grammar context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagShowSpellingPanel(bool show) +{ + if (show) + return UI_STRING("Show Spelling and Grammar", "menu item title"); + return UI_STRING("Hide Spelling and Grammar", "menu item title"); +} + +String WebPlatformStrategies::contextMenuItemTagCheckSpelling() +{ + return UI_STRING("Check Document Now", "Check spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCheckSpellingWhileTyping() +{ + return UI_STRING("Check Spelling While Typing", "Check spelling while typing context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCheckGrammarWithSpelling() +{ + return UI_STRING("Check Grammar With Spelling", "Check grammar with spelling context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagFontMenu() +{ + return UI_STRING("Font", "Font context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagBold() +{ + return UI_STRING("Bold", "Bold context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagItalic() +{ + return UI_STRING("Italic", "Italic context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagUnderline() +{ + return UI_STRING("Underline", "Underline context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagOutline() +{ + return UI_STRING("Outline", "Outline context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagWritingDirectionMenu() +{ + return UI_STRING("Paragraph Direction", "Paragraph direction context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagTextDirectionMenu() +{ + return UI_STRING("Selection Direction", "Selection direction context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagDefaultDirection() +{ + return UI_STRING("Default", "Default writing direction context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagLeftToRight() +{ + return UI_STRING("Left to Right", "Left to Right context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagRightToLeft() +{ + return UI_STRING("Right to Left", "Right to Left context menu item"); +} + +#if PLATFORM(MAC) + +String WebPlatformStrategies::contextMenuItemTagSearchInSpotlight() +{ + return UI_STRING("Search in Spotlight", "Search in Spotlight context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagShowFonts() +{ + return UI_STRING("Show Fonts", "Show fonts context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagStyles() +{ + return UI_STRING("Styles...", "Styles context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagShowColors() +{ + return UI_STRING("Show Colors", "Show colors context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSpeechMenu() +{ + return UI_STRING("Speech", "Speech context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagStartSpeaking() +{ + return UI_STRING("Start Speaking", "Start speaking context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagStopSpeaking() +{ + return UI_STRING("Stop Speaking", "Stop speaking context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCorrectSpellingAutomatically() +{ + return UI_STRING("Correct Spelling Automatically", "Correct Spelling Automatically context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSubstitutionsMenu() +{ + return UI_STRING("Substitutions", "Substitutions context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagShowSubstitutions(bool show) +{ + if (show) + return UI_STRING("Show Substitutions", "menu item title"); + return UI_STRING("Hide Substitutions", "menu item title"); +} + +String WebPlatformStrategies::contextMenuItemTagSmartCopyPaste() +{ + return UI_STRING("Smart Copy/Paste", "Smart Copy/Paste context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSmartQuotes() +{ + return UI_STRING("Smart Quotes", "Smart Quotes context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSmartDashes() +{ + return UI_STRING("Smart Dashes", "Smart Dashes context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagSmartLinks() +{ + return UI_STRING("Smart Links", "Smart Links context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagTextReplacement() +{ + return UI_STRING("Text Replacement", "Text Replacement context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagTransformationsMenu() +{ + return UI_STRING("Transformations", "Transformations context sub-menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMakeUpperCase() +{ + return UI_STRING("Make Upper Case", "Make Upper Case context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagMakeLowerCase() +{ + return UI_STRING("Make Lower Case", "Make Lower Case context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagCapitalize() +{ + return UI_STRING("Capitalize", "Capitalize context menu item"); +} + +String WebPlatformStrategies::contextMenuItemTagChangeBack(const String& replacedString) +{ + notImplemented(); + return replacedString; +} + +#endif + +String WebPlatformStrategies::contextMenuItemTagInspectElement() +{ + return UI_STRING("Inspect Element", "Inspect Element context menu item"); +} + +#endif // ENABLE(CONTEXT_MENUS) + +String WebPlatformStrategies::searchMenuNoRecentSearchesText() +{ + return UI_STRING("No recent searches", "Label for only item in menu that appears when clicking on the search field image, when no searches have been performed"); +} + +String WebPlatformStrategies::searchMenuRecentSearchesText() +{ + return UI_STRING("Recent Searches", "label for first item in the menu that appears when clicking on the search field image, used as embedded menu title"); +} + +String WebPlatformStrategies::searchMenuClearRecentSearchesText() +{ + return UI_STRING("Clear Recent Searches", "menu item in Recent Searches menu that empties menu's contents"); +} + +String WebPlatformStrategies::AXWebAreaText() +{ + return UI_STRING("HTML content", "accessibility role description for web area"); +} + +String WebPlatformStrategies::AXLinkText() +{ + return UI_STRING("link", "accessibility role description for link"); +} + +String WebPlatformStrategies::AXListMarkerText() +{ + return UI_STRING("list marker", "accessibility role description for list marker"); +} + +String WebPlatformStrategies::AXImageMapText() +{ + return UI_STRING("image map", "accessibility role description for image map"); +} + +String WebPlatformStrategies::AXHeadingText() +{ + return UI_STRING("heading", "accessibility role description for headings"); +} + +String WebPlatformStrategies::AXDefinitionListTermText() +{ + return UI_STRING("term", "term word of a definition"); +} + +String WebPlatformStrategies::AXDefinitionListDefinitionText() +{ + return UI_STRING("definition", "definition phrase"); +} + +#if PLATFORM(MAC) +String WebPlatformStrategies::AXARIAContentGroupText(const String& ariaType) +{ + if (ariaType == "ARIAApplicationAlert") + return UI_STRING("alert", "An ARIA accessibility group that acts as an alert."); + if (ariaType == "ARIAApplicationAlertDialog") + return UI_STRING("alert dialog", "An ARIA accessibility group that acts as an alert dialog."); + if (ariaType == "ARIAApplicationDialog") + return UI_STRING("dialog", "An ARIA accessibility group that acts as an dialog."); + if (ariaType == "ARIAApplicationLog") + return UI_STRING("log", "An ARIA accessibility group that acts as a console log."); + if (ariaType == "ARIAApplicationMarquee") + return UI_STRING("marquee", "An ARIA accessibility group that acts as a marquee."); + if (ariaType == "ARIAApplicationStatus") + return UI_STRING("application status", "An ARIA accessibility group that acts as a status update."); + if (ariaType == "ARIAApplicationTimer") + return UI_STRING("timer", "An ARIA accessibility group that acts as an updating timer."); + if (ariaType == "ARIADocument") + return UI_STRING("document", "An ARIA accessibility group that acts as a document."); + if (ariaType == "ARIADocumentArticle") + return UI_STRING("article", "An ARIA accessibility group that acts as an article."); + if (ariaType == "ARIADocumentNote") + return UI_STRING("note", "An ARIA accessibility group that acts as a note in a document."); + if (ariaType == "ARIADocumentRegion") + return UI_STRING("region", "An ARIA accessibility group that acts as a distinct region in a document."); + if (ariaType == "ARIALandmarkApplication") + return UI_STRING("application", "An ARIA accessibility group that acts as an application."); + if (ariaType == "ARIALandmarkBanner") + return UI_STRING("banner", "An ARIA accessibility group that acts as a banner."); + if (ariaType == "ARIALandmarkComplementary") + return UI_STRING("complementary", "An ARIA accessibility group that acts as a region of complementary information."); + if (ariaType == "ARIALandmarkContentInfo") + return UI_STRING("content", "An ARIA accessibility group that contains content."); + if (ariaType == "ARIALandmarkMain") + return UI_STRING("main", "An ARIA accessibility group that is the main portion of the website."); + if (ariaType == "ARIALandmarkNavigation") + return UI_STRING("navigation", "An ARIA accessibility group that contains the main navigation elements of a website."); + if (ariaType == "ARIALandmarkSearch") + return UI_STRING("search", "An ARIA accessibility group that contains a search feature of a website."); + if (ariaType == "ARIAUserInterfaceTooltip") + return UI_STRING("tooltip", "An ARIA accessibility group that acts as a tooltip."); + if (ariaType == "ARIATabPanel") + return UI_STRING("tab panel", "An ARIA accessibility group that contains the content of a tab."); + if (ariaType == "ARIADocumentMath") + return UI_STRING("math", "An ARIA accessibility group that contains mathematical symbols."); + return String(); +} +#endif + +String WebPlatformStrategies::AXButtonActionVerb() +{ + return UI_STRING("press", "Verb stating the action that will occur when a button is pressed, as used by accessibility"); +} + +String WebPlatformStrategies::AXRadioButtonActionVerb() +{ + return UI_STRING("select", "Verb stating the action that will occur when a radio button is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXTextFieldActionVerb() +{ + return UI_STRING("activate", "Verb stating the action that will occur when a text field is selected, as used by accessibility"); +} + +String WebPlatformStrategies::AXCheckedCheckBoxActionVerb() +{ + return UI_STRING("uncheck", "Verb stating the action that will occur when a checked checkbox is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXUncheckedCheckBoxActionVerb() +{ + return UI_STRING("check", "Verb stating the action that will occur when an unchecked checkbox is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::AXMenuListActionVerb() +{ + notImplemented(); + return "select"; +} + +String WebPlatformStrategies::AXMenuListPopupActionVerb() +{ + notImplemented(); + return "select"; +} + +String WebPlatformStrategies::AXLinkActionVerb() +{ + return UI_STRING("jump", "Verb stating the action that will occur when a link is clicked, as used by accessibility"); +} + +String WebPlatformStrategies::missingPluginText() +{ + return UI_STRING("Missing Plug-in", "Label text to be used when a plugin is missing"); +} + +String WebPlatformStrategies::crashedPluginText() +{ + return UI_STRING("Plug-in Failure", "Label text to be used if plugin host process has crashed"); +} + +String WebPlatformStrategies::multipleFileUploadText(unsigned numberOfFiles) +{ + return formatLocalizedString(UI_STRING("%d files", "Label to describe the number of files selected in a file upload control that allows multiple files"), numberOfFiles); +} + +String WebPlatformStrategies::unknownFileSizeText() +{ + return UI_STRING("Unknown", "Unknown filesize FTP directory listing item"); +} + +#if PLATFORM(WIN) + +String WebPlatformStrategies::uploadFileText() +{ + notImplemented(); + return "upload"; +} + +String WebPlatformStrategies::allFilesText() +{ + notImplemented(); + return "all files"; +} + +#endif + +String WebPlatformStrategies::imageTitle(const String& filename, const IntSize& size) +{ + // FIXME: It would be nice to have the filename inside the format string, but it's not easy to do that in a way that works with non-ASCII characters in the filename. + return filename + formatLocalizedString(UI_STRING(" %d×%d pixels", "window title suffix for a standalone image (uses multiplication symbol, not x)"), size.width(), size.height()); +} + +String WebPlatformStrategies::mediaElementLoadingStateText() +{ + return UI_STRING("Loading...", "Media controller status message when the media is loading"); +} + +String WebPlatformStrategies::mediaElementLiveBroadcastStateText() +{ + return UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast"); +} + +String WebPlatformStrategies::localizedMediaControlElementString(const String& name) +{ + if (name == "AudioElement") + return UI_STRING("audio element controller", "accessibility role description for audio element controller"); + if (name == "VideoElement") + return UI_STRING("video element controller", "accessibility role description for video element controller"); + if (name == "MuteButton") + return UI_STRING("mute", "accessibility role description for mute button"); + if (name == "UnMuteButton") + return UI_STRING("unmute", "accessibility role description for turn mute off button"); + if (name == "PlayButton") + return UI_STRING("play", "accessibility role description for play button"); + if (name == "PauseButton") + return UI_STRING("pause", "accessibility role description for pause button"); + if (name == "Slider") + return UI_STRING("movie time", "accessibility role description for timeline slider"); + if (name == "SliderThumb") + return UI_STRING("timeline slider thumb", "accessibility role description for timeline thumb"); + if (name == "RewindButton") + return UI_STRING("back 30 seconds", "accessibility role description for seek back 30 seconds button"); + if (name == "ReturnToRealtimeButton") + return UI_STRING("return to realtime", "accessibility role description for return to real time button"); + if (name == "CurrentTimeDisplay") + return UI_STRING("elapsed time", "accessibility role description for elapsed time display"); + if (name == "TimeRemainingDisplay") + return UI_STRING("remaining time", "accessibility role description for time remaining display"); + if (name == "StatusDisplay") + return UI_STRING("status", "accessibility role description for movie status"); + if (name == "FullscreenButton") + return UI_STRING("fullscreen", "accessibility role description for enter fullscreen button"); + if (name == "SeekForwardButton") + return UI_STRING("fast forward", "accessibility role description for fast forward button"); + if (name == "SeekBackButton") + return UI_STRING("fast reverse", "accessibility role description for fast reverse button"); + if (name == "ShowClosedCaptionsButton") + return UI_STRING("show closed captions", "accessibility role description for show closed captions button"); + if (name == "HideClosedCaptionsButton") + return UI_STRING("hide closed captions", "accessibility role description for hide closed captions button"); + + // FIXME: the ControlsPanel container should never be visible in the accessibility hierarchy. + if (name == "ControlsPanel") + return String(); + + ASSERT_NOT_REACHED(); + return String(); +} + +String WebPlatformStrategies::localizedMediaControlElementHelpText(const String& name) +{ + if (name == "AudioElement") + return UI_STRING("audio element playback controls and status display", "accessibility role description for audio element controller"); + if (name == "VideoElement") + return UI_STRING("video element playback controls and status display", "accessibility role description for video element controller"); + if (name == "MuteButton") + return UI_STRING("mute audio tracks", "accessibility help text for mute button"); + if (name == "UnMuteButton") + return UI_STRING("unmute audio tracks", "accessibility help text for un mute button"); + if (name == "PlayButton") + return UI_STRING("begin playback", "accessibility help text for play button"); + if (name == "PauseButton") + return UI_STRING("pause playback", "accessibility help text for pause button"); + if (name == "Slider") + return UI_STRING("movie time scrubber", "accessibility help text for timeline slider"); + if (name == "SliderThumb") + return UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb"); + if (name == "RewindButton") + return UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button"); + if (name == "ReturnToRealtimeButton") + return UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button"); + if (name == "CurrentTimeDisplay") + return UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display"); + if (name == "TimeRemainingDisplay") + return UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display"); + if (name == "StatusDisplay") + return UI_STRING("current movie status", "accessibility help text for movie status display"); + if (name == "SeekBackButton") + return UI_STRING("seek quickly back", "accessibility help text for fast rewind button"); + if (name == "SeekForwardButton") + return UI_STRING("seek quickly forward", "accessibility help text for fast forward button"); + if (name == "FullscreenButton") + return UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button"); + if (name == "ShowClosedCaptionsButton") + return UI_STRING("start displaying closed captions", "accessibility help text for show closed captions button"); + if (name == "HideClosedCaptionsButton") + return UI_STRING("stop displaying closed captions", "accessibility help text for hide closed captions button"); + + ASSERT_NOT_REACHED(); + return String(); +} + +String WebPlatformStrategies::localizedMediaTimeDescription(float time) +{ + if (!isfinite(time)) + return UI_STRING("indefinite time", "accessibility help text for an indefinite media controller time value"); + + int seconds = static_cast<int>(fabsf(time)); + int days = seconds / (60 * 60 * 24); + int hours = seconds / (60 * 60); + int minutes = (seconds / 60) % 60; + seconds %= 60; + + if (days) + return formatLocalizedString(UI_STRING("%1$d days %2$d hours %3$d minutes %4$d seconds", "accessibility help text for media controller time value >= 1 day"), days, hours, minutes, seconds); + if (hours) + return formatLocalizedString(UI_STRING("%1$d hours %2$d minutes %3$d seconds", "accessibility help text for media controller time value >= 60 minutes"), hours, minutes, seconds); + if (minutes) + return formatLocalizedString(UI_STRING("%1$d minutes %2$d seconds", "accessibility help text for media controller time value >= 60 seconds"), minutes, seconds); + return formatLocalizedString(UI_STRING("%1$d seconds", "accessibility help text for media controller time value < 60 seconds"), seconds); +} + +String WebPlatformStrategies::validationMessageValueMissingText() +{ + return UI_STRING("value missing", "Validation message for required form control elements that have no value"); +} + +String WebPlatformStrategies::validationMessageTypeMismatchText() +{ + return UI_STRING("type mismatch", "Validation message for input form controls with a value not matching type"); +} + +String WebPlatformStrategies::validationMessagePatternMismatchText() +{ + return UI_STRING("pattern mismatch", "Validation message for input form controls requiring a constrained value according to pattern"); +} + +String WebPlatformStrategies::validationMessageTooLongText() +{ + return UI_STRING("too long", "Validation message for form control elements with a value longer than maximum allowed length"); +} + +String WebPlatformStrategies::validationMessageRangeUnderflowText() +{ + return UI_STRING("range underflow", "Validation message for input form controls with value lower than allowed minimum"); +} + +String WebPlatformStrategies::validationMessageRangeOverflowText() +{ + return UI_STRING("range overflow", "Validation message for input form controls with value higher than allowed maximum"); +} + +String WebPlatformStrategies::validationMessageStepMismatchText() +{ + return UI_STRING("step mismatch", "Validation message for input form controls with value not respecting the step attribute"); +} + +// VisitedLinkStrategy +bool WebPlatformStrategies::isLinkVisited(Page* page, LinkHash linkHash) +{ + return WebProcess::shared().isLinkVisited(linkHash); +} + +void WebPlatformStrategies::addVisitedLink(Page* page, LinkHash linkHash) +{ + WebProcess::shared().addVisitedLink(linkHash); +} + +} // namespace WebKit + +#endif // USE(PLATFORM_STRATEGIES) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h new file mode 100644 index 0000000..b584f8d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.h @@ -0,0 +1,201 @@ +/* + * 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. + */ + +#ifndef WebPlatformStrategies_h +#define WebPlatformStrategies_h + +#if USE(PLATFORM_STRATEGIES) + +#include <WebCore/PlatformStrategies.h> +#include <WebCore/PluginStrategy.h> +#include <WebCore/LocalizationStrategy.h> +#include <WebCore/VisitedLinkStrategy.h> + +namespace WebKit { + +class WebPlatformStrategies : public WebCore::PlatformStrategies, private WebCore::PluginStrategy, private WebCore::LocalizationStrategy, private WebCore::VisitedLinkStrategy { +public: + static void initialize(); + +private: + WebPlatformStrategies(); + + // WebCore::PlatformStrategies + virtual WebCore::PluginStrategy* createPluginStrategy(); + virtual WebCore::LocalizationStrategy* createLocalizationStrategy(); + virtual WebCore::VisitedLinkStrategy* createVisitedLinkStrategy(); + + // WebCore::PluginStrategy + virtual void refreshPlugins(); + virtual void getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>&); + + // WebCore::LocalizationStrategy + virtual String inputElementAltText(); + virtual String resetButtonDefaultLabel(); + virtual String searchableIndexIntroduction(); + virtual String submitButtonDefaultLabel(); + virtual String fileButtonChooseFileLabel(); + virtual String fileButtonNoFileSelectedLabel(); +#if PLATFORM(MAC) + virtual String copyImageUnknownFileLabel(); +#endif +#if ENABLE(CONTEXT_MENUS) + virtual String contextMenuItemTagOpenLinkInNewWindow(); + virtual String contextMenuItemTagDownloadLinkToDisk(); + virtual String contextMenuItemTagCopyLinkToClipboard(); + virtual String contextMenuItemTagOpenImageInNewWindow(); + virtual String contextMenuItemTagDownloadImageToDisk(); + virtual String contextMenuItemTagCopyImageToClipboard(); + virtual String contextMenuItemTagOpenFrameInNewWindow(); + virtual String contextMenuItemTagCopy(); + virtual String contextMenuItemTagGoBack(); + virtual String contextMenuItemTagGoForward(); + virtual String contextMenuItemTagStop(); + virtual String contextMenuItemTagReload(); + virtual String contextMenuItemTagCut(); + virtual String contextMenuItemTagPaste(); +#if PLATFORM(GTK) + virtual String contextMenuItemTagDelete(); + virtual String contextMenuItemTagInputMethods(); + virtual String contextMenuItemTagUnicode(); +#endif +#if PLATFORM(GTK) || PLATFORM(QT) + virtual String contextMenuItemTagSelectAll(); +#endif + virtual String contextMenuItemTagNoGuessesFound(); + virtual String contextMenuItemTagIgnoreSpelling(); + virtual String contextMenuItemTagLearnSpelling(); + virtual String contextMenuItemTagSearchWeb(); + virtual String contextMenuItemTagLookUpInDictionary(); + virtual String contextMenuItemTagOpenLink(); + virtual String contextMenuItemTagIgnoreGrammar(); + virtual String contextMenuItemTagSpellingMenu(); + virtual String contextMenuItemTagShowSpellingPanel(bool show); + virtual String contextMenuItemTagCheckSpelling(); + virtual String contextMenuItemTagCheckSpellingWhileTyping(); + virtual String contextMenuItemTagCheckGrammarWithSpelling(); + virtual String contextMenuItemTagFontMenu(); + virtual String contextMenuItemTagBold(); + virtual String contextMenuItemTagItalic(); + virtual String contextMenuItemTagUnderline(); + virtual String contextMenuItemTagOutline(); + virtual String contextMenuItemTagWritingDirectionMenu(); + virtual String contextMenuItemTagTextDirectionMenu(); + virtual String contextMenuItemTagDefaultDirection(); + virtual String contextMenuItemTagLeftToRight(); + virtual String contextMenuItemTagRightToLeft(); +#if PLATFORM(MAC) + virtual String contextMenuItemTagSearchInSpotlight(); + virtual String contextMenuItemTagShowFonts(); + virtual String contextMenuItemTagStyles(); + virtual String contextMenuItemTagShowColors(); + virtual String contextMenuItemTagSpeechMenu(); + virtual String contextMenuItemTagStartSpeaking(); + virtual String contextMenuItemTagStopSpeaking(); + virtual String contextMenuItemTagCorrectSpellingAutomatically(); + virtual String contextMenuItemTagSubstitutionsMenu(); + virtual String contextMenuItemTagShowSubstitutions(bool show); + virtual String contextMenuItemTagSmartCopyPaste(); + virtual String contextMenuItemTagSmartQuotes(); + virtual String contextMenuItemTagSmartDashes(); + virtual String contextMenuItemTagSmartLinks(); + virtual String contextMenuItemTagTextReplacement(); + virtual String contextMenuItemTagTransformationsMenu(); + virtual String contextMenuItemTagMakeUpperCase(); + virtual String contextMenuItemTagMakeLowerCase(); + virtual String contextMenuItemTagCapitalize(); + virtual String contextMenuItemTagChangeBack(const String& replacedString); +#endif + virtual String contextMenuItemTagInspectElement(); + virtual String contextMenuItemTagOpenVideoInNewWindow(); + virtual String contextMenuItemTagOpenAudioInNewWindow(); + virtual String contextMenuItemTagCopyVideoLinkToClipboard(); + virtual String contextMenuItemTagCopyAudioLinkToClipboard(); + virtual String contextMenuItemTagToggleMediaControls(); + virtual String contextMenuItemTagToggleMediaLoop(); + virtual String contextMenuItemTagEnterVideoFullscreen(); + virtual String contextMenuItemTagMediaPlay(); + virtual String contextMenuItemTagMediaPause(); + virtual String contextMenuItemTagMediaMute(); +#endif // ENABLE(CONTEXT_MENUS) + virtual String searchMenuNoRecentSearchesText(); + virtual String searchMenuRecentSearchesText(); + virtual String searchMenuClearRecentSearchesText(); + virtual String AXWebAreaText(); + virtual String AXLinkText(); + virtual String AXListMarkerText(); + virtual String AXImageMapText(); + virtual String AXHeadingText(); + virtual String AXDefinitionListTermText(); + virtual String AXDefinitionListDefinitionText(); +#if PLATFORM(MAC) + virtual String AXARIAContentGroupText(const String& ariaType); +#endif + virtual String AXButtonActionVerb(); + virtual String AXRadioButtonActionVerb(); + virtual String AXTextFieldActionVerb(); + virtual String AXCheckedCheckBoxActionVerb(); + virtual String AXUncheckedCheckBoxActionVerb(); + virtual String AXMenuListActionVerb(); + virtual String AXMenuListPopupActionVerb(); + virtual String AXLinkActionVerb(); + virtual String missingPluginText(); + virtual String crashedPluginText(); + virtual String multipleFileUploadText(unsigned numberOfFiles); + virtual String unknownFileSizeText(); +#if PLATFORM(WIN) + virtual String uploadFileText(); + virtual String allFilesText(); +#endif + virtual String imageTitle(const String& filename, const WebCore::IntSize& size); + virtual String mediaElementLoadingStateText(); + virtual String mediaElementLiveBroadcastStateText(); + virtual String localizedMediaControlElementString(const String&); + virtual String localizedMediaControlElementHelpText(const String&); + virtual String localizedMediaTimeDescription(float); + virtual String validationMessageValueMissingText(); + virtual String validationMessageTypeMismatchText(); + virtual String validationMessagePatternMismatchText(); + virtual String validationMessageTooLongText(); + virtual String validationMessageRangeUnderflowText(); + virtual String validationMessageRangeOverflowText(); + virtual String validationMessageStepMismatchText(); + + void populatePluginCache(); + + bool m_pluginCacheIsPopulated; + bool m_shouldRefreshPlugins; + Vector<WebCore::PluginInfo> m_cachedPlugins; + + // WebCore::VisitedLinkStrategy + virtual bool isLinkVisited(WebCore::Page*, WebCore::LinkHash); + virtual void addVisitedLink(WebCore::Page*, WebCore::LinkHash); +}; + +} // namespace WebKit + +#endif // USE(PLATFORM_STRATEGIES) + +#endif // WebPlatformStrategies_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp new file mode 100644 index 0000000..ea0ad2d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010 Apple 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 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 "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/FrameView.h> +#include <WebCore/PopupMenuClient.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<WebPopupMenu> WebPopupMenu::create(WebPage* page, PopupMenuClient* client) +{ + return adoptRef(new WebPopupMenu(page, client)); +} + +WebPopupMenu::WebPopupMenu(WebPage* page, PopupMenuClient* client) + : m_popupClient(client) + , m_page(page) +{ +} + +WebPopupMenu::~WebPopupMenu() +{ +} + +void WebPopupMenu::disconnectClient() +{ + m_popupClient = 0; +} + +void WebPopupMenu::didChangeSelectedIndex(int newIndex) +{ + if (!m_popupClient) + return; + + m_popupClient->popupDidHide(); + if (newIndex >= 0) + m_popupClient->valueChanged(newIndex); +} + +void WebPopupMenu::setTextForIndex(int index) +{ + if (!m_popupClient) + return; + + m_popupClient->setTextFromItem(index); +} + +Vector<WebPopupItem> WebPopupMenu::populateItems() +{ + size_t size = m_popupClient->listSize(); + + Vector<WebPopupItem> items; + items.reserveInitialCapacity(size); + + for (size_t i = 0; i < size; ++i) { + if (m_popupClient->itemIsSeparator(i)) + items.append(WebPopupItem(WebPopupItem::Seperator)); + else { + // FIXME: Add support for styling the font. + // FIXME: Add support for styling the foreground and background colors. + // FIXME: Find a way to customize text color when an item is highlighted. + items.append(WebPopupItem(WebPopupItem::Item, m_popupClient->itemText(i), m_popupClient->itemToolTip(i), m_popupClient->itemAccessibilityText(i), m_popupClient->itemIsEnabled(i), m_popupClient->itemIsLabel(i))); + } + } + + return items; +} + +void WebPopupMenu::show(const IntRect& rect, FrameView* view, int index) +{ + // FIXME: We should probably inform the client to also close the menu. + Vector<WebPopupItem> items = populateItems(); + + if (items.isEmpty() || !m_page) { + m_popupClient->popupDidHide(); + return; + } + + m_page->setActivePopupMenu(this); + + // Move to page coordinates + IntRect pageCoordinates(view->contentsToWindow(rect.location()), rect.size()); + + PlatformPopupMenuData platformData; + setUpPlatformData(pageCoordinates, platformData); + + WebProcess::shared().connection()->send(Messages::WebPageProxy::ShowPopupMenu(pageCoordinates, items, index, platformData), m_page->pageID()); +} + +void WebPopupMenu::hide() +{ + if (!m_page || !m_popupClient) + return; + + WebProcess::shared().connection()->send(Messages::WebPageProxy::HidePopupMenu(), m_page->pageID()); + m_page->setActivePopupMenu(0); +} + +void WebPopupMenu::updateFromElement() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h new file mode 100644 index 0000000..3083c94 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010 Apple 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 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 WebPopupMenu_h +#define WebPopupMenu_h + +#include "WebPopupItem.h" +#include <WebCore/PopupMenu.h> +#include <wtf/Forward.h> +#include <wtf/OwnPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { +class PopupMenuClient; +} + +namespace WebKit { + +class WebPage; +struct PlatformPopupMenuData; +struct WebPopupItem; + +class WebPopupMenu : public WebCore::PopupMenu { +public: + static PassRefPtr<WebPopupMenu> create(WebPage*, WebCore::PopupMenuClient*); + ~WebPopupMenu(); + + void disconnectFromPage() { m_page = 0; } + void didChangeSelectedIndex(int newIndex); + void setTextForIndex(int newIndex); + + virtual void show(const WebCore::IntRect&, WebCore::FrameView*, int index); + virtual void hide(); + virtual void updateFromElement(); + virtual void disconnectClient(); + +private: + WebPopupMenu(WebPage*, WebCore::PopupMenuClient*); + + Vector<WebPopupItem> populateItems(); + void setUpPlatformData(const WebCore::IntRect& pageCoordinates, PlatformPopupMenuData&); + + WebCore::PopupMenuClient* m_popupClient; + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebPopupMenu_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp new file mode 100644 index 0000000..acec5f2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010 Apple 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 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 "WebSearchPopupMenu.h" + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<WebSearchPopupMenu> WebSearchPopupMenu::create(WebPage* page, PopupMenuClient* client) +{ + return adoptRef(new WebSearchPopupMenu(page, client)); +} + +WebSearchPopupMenu::WebSearchPopupMenu(WebPage* page, PopupMenuClient* client) + : m_popup(WebPopupMenu::create(page, client)) +{ +} + +PopupMenu* WebSearchPopupMenu::popupMenu() +{ + return m_popup.get(); +} + +void WebSearchPopupMenu::saveRecentSearches(const AtomicString&, const Vector<String>&) +{ +} + +void WebSearchPopupMenu::loadRecentSearches(const AtomicString&, Vector<String>&) +{ +} + +bool WebSearchPopupMenu::enabled() +{ + return false; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.h new file mode 100644 index 0000000..0221571 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010 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 WebSearchPopupMenu_h +#define WebSearchPopupMenu_h + +#include "WebPopupMenu.h" +#include <WebCore/SearchPopupMenu.h> + +namespace WebKit { + +class WebSearchPopupMenu : public WebCore::SearchPopupMenu { +public: + static PassRefPtr<WebSearchPopupMenu> create(WebPage*, WebCore::PopupMenuClient*); + + virtual WebCore::PopupMenu* popupMenu(); + virtual void saveRecentSearches(const WTF::AtomicString& name, const Vector<String>& searchItems); + virtual void loadRecentSearches(const WTF::AtomicString& name, Vector<String>& searchItems); + virtual bool enabled(); + +private: + WebSearchPopupMenu(WebPage*, WebCore::PopupMenuClient*); + + RefPtr<WebPopupMenu> m_popup; +}; + +} + +#endif // WebSearchPopupMenu_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp new file mode 100644 index 0000000..db9500a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "WebContextMenuClient.h" + +#include "NotImplemented.h" + +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 diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebDatabaseManagerGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebDatabaseManagerGtk.cpp new file mode 100644 index 0000000..b3c1289 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebDatabaseManagerGtk.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "WebDatabaseManager.h" + +#include "NotImplemented.h" + +namespace WebKit { + +String WebDatabaseManager::databaseDirectory() const +{ + notImplemented(); + return String(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebFrameNetworkingContext.h new file mode 100644 index 0000000..1a2d611 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebFrameNetworkingContext.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 <WebCore/FrameNetworkingContext.h> + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebCore::Frame*) + { + return 0; + } + +private: + WebFrameNetworkingContext(WebCore::Frame* frame) + : WebCore::FrameNetworkingContext(frame) + { + } + + virtual WTF::String userAgent() const; + virtual WTF::String referrer() const; + + WTF::String m_userAgent; +}; + +#endif // WebFrameNetworkingContext_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebPopupMenuGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebPopupMenuGtk.cpp new file mode 100644 index 0000000..6cda476 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebPopupMenuGtk.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "WebPopupMenu.h" + +#include "NotImplemented.h" +#include "PlatformPopupMenuData.h" + +using namespace WebCore; + +namespace WebKit { + +void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData&) +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm new file mode 100644 index 0000000..32d08b2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm @@ -0,0 +1,85 @@ +/* + * 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 "WebContextMenuClient.h" + +#include "NotImplemented.h" +#include "WebPage.h" +#include <WebCore/Frame.h> +#include <WebCore/Page.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +void WebContextMenuClient::lookUpInDictionary(Frame*) +{ + // FIXME: <rdar://problem/8750610> - Implement + notImplemented(); +} + +bool WebContextMenuClient::isSpeaking() +{ + return m_page->isSpeaking(); +} + +void WebContextMenuClient::speak(const String& string) +{ + m_page->speak(string); +} + +void WebContextMenuClient::stopSpeaking() +{ + m_page->stopSpeaking(); +} + +void WebContextMenuClient::searchWithSpotlight() +{ + // FIXME: Why do we need to search all the frames like this? + // Isn't there any function in WebCore that can do this? + // If not, can we find a place in WebCore to put this? + + Frame* mainFrame = m_page->corePage()->mainFrame(); + + Frame* selectionFrame = mainFrame; + for (; selectionFrame; selectionFrame = selectionFrame->tree()->traverseNext(mainFrame)) { + if (selectionFrame->selection()->isRange()) + break; + } + if (!selectionFrame) + selectionFrame = mainFrame; + + String selectedString = selectionFrame->displayStringModifiedByEncoding(selectionFrame->editor()->selectedText()); + + if (selectedString.isEmpty()) + return; + + NSString *convertedSelectedString = selectedString; + + [[NSWorkspace sharedWorkspace] showSearchResultsForQueryString:convertedSelectedString]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDatabaseManagerMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDatabaseManagerMac.mm new file mode 100644 index 0000000..d4eb3ac --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDatabaseManagerMac.mm @@ -0,0 +1,42 @@ +/* + * 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 "WebDatabaseManager.h" + +namespace WebKit { + +NSString *WebDatabaseDirectoryDefaultsKey = @"WebDatabaseDirectory"; + +String WebDatabaseManager::databaseDirectory() const +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *databasesDirectory = [defaults objectForKey:WebDatabaseDirectoryDefaultsKey]; + if (!databasesDirectory || ![databasesDirectory isKindOfClass:[NSString class]]) + databasesDirectory = @"~/Library/WebKit/Databases"; + + return [databasesDirectory stringByStandardizingPath]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm new file mode 100644 index 0000000..ce33890 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2006, 2010, 2011 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * + * 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. + */ + +#import "WebEditorClient.h" + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebFrame.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/ArchiveResource.h> +#include <WebCore/DocumentFragment.h> +#include <WebCore/DOMDocumentFragmentInternal.h> +#include <WebCore/DOMDocumentInternal.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebKit/WebResource.h> +#include <WebKit/WebNSURLExtras.h> +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +#import <AppKit/NSTextChecker.h> +#endif + +using namespace WebCore; + +@interface NSAttributedString (WebNSAttributedStringDetails) +- (DOMDocumentFragment*)_documentFromRange:(NSRange)range document:(DOMDocument*)document documentAttributes:(NSDictionary *)dict subresources:(NSArray **)subresources; +@end + +@interface WebResource (WebResourceInternal) +- (WebCore::ArchiveResource*)_coreResource; +@end + +namespace WebKit { + +void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) +{ + if (m_page->interceptEditingKeyboardEvent(event, false)) + event->setDefaultHandled(); +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event) +{ + if (m_page->interceptEditingKeyboardEvent(event, true)) + event->setDefaultHandled(); +} + +NSString *WebEditorClient::userVisibleString(NSURL *url) +{ + return [url _web_userVisibleString]; +} + +NSURL *WebEditorClient::canonicalizeURL(NSURL *url) +{ + return [url _webkit_canonicalize]; +} + +NSURL *WebEditorClient::canonicalizeURLString(NSString *URLString) +{ + NSURL *URL = nil; + if ([URLString _webkit_looksLikeAbsoluteURL]) + URL = [[NSURL _web_URLWithUserTypedString:URLString] _webkit_canonicalize]; + return URL; +} + +static NSArray *createExcludedElementsForAttributedStringConversion() +{ + NSArray *elements = [[NSArray alloc] initWithObjects: + // Omit style since we want style to be inline so the fragment can be easily inserted. + @"style", + // Omit xml so the result is not XHTML. + @"xml", + // Omit tags that will get stripped when converted to a fragment anyway. + @"doctype", @"html", @"head", @"body", + // Omit deprecated tags. + @"applet", @"basefont", @"center", @"dir", @"font", @"isindex", @"menu", @"s", @"strike", @"u", + // Omit object so no file attachments are part of the fragment. + @"object", nil]; + CFRetain(elements); + return elements; +} + +DocumentFragment* WebEditorClient::documentFragmentFromAttributedString(NSAttributedString *string, Vector<RefPtr<ArchiveResource> >& resources) +{ + static NSArray *excludedElements = createExcludedElementsForAttributedStringConversion(); + + NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: excludedElements, + NSExcludedElementsDocumentAttribute, nil, @"WebResourceHandler", nil]; + + NSArray *subResources; + DOMDocumentFragment* fragment = [string _documentFromRange:NSMakeRange(0, [string length]) + document:kit(m_page->mainFrame()->coreFrame()->document()) + documentAttributes:dictionary + subresources:&subResources]; + for (WebResource* resource in subResources) + resources.append([resource _coreResource]); + + [dictionary release]; + return core(fragment); +} + +void WebEditorClient::setInsertionPasteboard(NSPasteboard *) +{ + // This is used only by Mail, no need to implement it now. + notImplemented(); +} + +#ifdef BUILDING_ON_TIGER +NSArray *WebEditorClient::pasteboardTypesForSelection(Frame*) +{ + notImplemented(); + return nil; +} +#endif + +static void changeWordCase(WebPage* page, SEL selector) +{ + Frame* frame = page->corePage()->focusController()->focusedOrMainFrame(); + if (!frame->editor()->canEdit()) + return; + + frame->editor()->command("selectWord").execute(); + + NSString *selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText()); + page->replaceSelectionWithText(frame, [selectedString performSelector:selector]); +} + +void WebEditorClient::uppercaseWord() +{ + changeWordCase(m_page, @selector(uppercaseString)); +} + +void WebEditorClient::lowercaseWord() +{ + changeWordCase(m_page, @selector(lowercaseString)); +} + +void WebEditorClient::capitalizeWord() +{ + changeWordCase(m_page, @selector(capitalizedString)); +} + +void WebEditorClient::showSubstitutionsPanel(bool) +{ + notImplemented(); +} + +bool WebEditorClient::substitutionsPanelIsShowing() +{ + notImplemented(); + return false; +} + +void WebEditorClient::toggleSmartInsertDelete() +{ + // This is handled in the UI process. + ASSERT_NOT_REACHED(); +} + +bool WebEditorClient::isAutomaticQuoteSubstitutionEnabled() +{ + return WebProcess::shared().textCheckerState().isAutomaticQuoteSubstitutionEnabled; +} + +void WebEditorClient::toggleAutomaticQuoteSubstitution() +{ + // This is handled in the UI process. + ASSERT_NOT_REACHED(); +} + +bool WebEditorClient::isAutomaticLinkDetectionEnabled() +{ + return WebProcess::shared().textCheckerState().isAutomaticLinkDetectionEnabled; +} + +void WebEditorClient::toggleAutomaticLinkDetection() +{ + // This is handled in the UI process. + ASSERT_NOT_REACHED(); +} + +bool WebEditorClient::isAutomaticDashSubstitutionEnabled() +{ + return WebProcess::shared().textCheckerState().isAutomaticDashSubstitutionEnabled; +} + +void WebEditorClient::toggleAutomaticDashSubstitution() +{ + // This is handled in the UI process. + ASSERT_NOT_REACHED(); +} + +bool WebEditorClient::isAutomaticTextReplacementEnabled() +{ + return WebProcess::shared().textCheckerState().isAutomaticTextReplacementEnabled; +} + +void WebEditorClient::toggleAutomaticTextReplacement() +{ + // This is handled in the UI process. + ASSERT_NOT_REACHED(); +} + +bool WebEditorClient::isAutomaticSpellingCorrectionEnabled() +{ + return WebProcess::shared().textCheckerState().isAutomaticSpellingCorrectionEnabled; +} + +void WebEditorClient::toggleAutomaticSpellingCorrection() +{ + notImplemented(); +} + +void WebEditorClient::checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) +{ + // FIXME: It would be nice if we wouldn't have to copy the text here. + m_page->sendSync(Messages::WebPageProxy::CheckTextOfParagraph(String(text, length), checkingTypes), Messages::WebPageProxy::CheckTextOfParagraph::Reply(results)); +} + +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) +void WebEditorClient::showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType type, const WebCore::FloatRect& boundingBoxOfReplacedString, const WTF::String& replacedString, const WTF::String& replacementString, const Vector<String>& alternativeReplacementStrings, WebCore::Editor*) +{ + notImplemented(); +} + +void WebEditorClient::dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel) +{ + notImplemented(); +} + +bool WebEditorClient::isShowingCorrectionPanel() +{ + notImplemented(); + return false; +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm new file mode 100644 index 0000000..549d7ee --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm @@ -0,0 +1,178 @@ +/* + * 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 "WebErrors.h" + +#include "WKError.h" +#include "WebError.h" +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> +#include <pthread.h> + +using namespace WebCore; +using namespace WebKit; + +// FIXME: We probably don't need to use NSErrors here. + +static NSString * const WebKitErrorMIMETypeKey = @"WebKitErrorMIMETypeKey"; +static NSString * const WebKitErrorPlugInNameKey = @"WebKitErrorPlugInNameKey"; +static NSString * const WebKitErrorPlugInPageURLStringKey = @"WebKitErrorPlugInPageURLStringKey"; + +// FIXME (WebKit2) <rdar://problem/8728860> WebKit2 needs to be localized +#define UI_STRING(__str, __desc) [NSString stringWithUTF8String:__str] + +// Policy errors +#define WebKitErrorDescriptionCannotShowMIMEType UI_STRING("Content with specified MIME type can’t be shown", "WebKitErrorCannotShowMIMEType description") +#define WebKitErrorDescriptionCannotShowURL UI_STRING("The URL can’t be shown", "WebKitErrorCannotShowURL description") +#define WebKitErrorDescriptionFrameLoadInterruptedByPolicyChange UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description") +#define WebKitErrorDescriptionCannotUseRestrictedPort UI_STRING("Not allowed to use restricted network port", "WebKitErrorCannotUseRestrictedPort description") + +// Plug-in and java errors +#define WebKitErrorDescriptionCannotFindPlugin UI_STRING("The plug-in can’t be found", "WebKitErrorCannotFindPlugin description") +#define WebKitErrorDescriptionCannotLoadPlugin UI_STRING("The plug-in can’t be loaded", "WebKitErrorCannotLoadPlugin description") +#define WebKitErrorDescriptionJavaUnavailable UI_STRING("Java is unavailable", "WebKitErrorJavaUnavailable description") +#define WebKitErrorDescriptionPlugInCancelledConnection UI_STRING("Plug-in cancelled", "WebKitErrorPlugInCancelledConnection description") +#define WebKitErrorDescriptionPlugInWillHandleLoad UI_STRING("Plug-in handled load", "WebKitErrorPlugInWillHandleLoad description") + +static pthread_once_t registerErrorsControl = PTHREAD_ONCE_INIT; +static void registerErrors(void); + +@interface NSError (WebKitExtras) ++ (NSError *)_webKitErrorWithDomain:(NSString *)domain code:(int)code URL:(NSURL *)URL; +@end + +@implementation NSError (WebKitExtras) + +static NSMutableDictionary *descriptions = nil; + ++ (void)_registerWebKitErrors +{ + pthread_once(®isterErrorsControl, registerErrors); +} + +-(id)_webkit_initWithDomain:(NSString *)domain code:(int)code URL:(NSURL *)URL +{ + NSDictionary *descriptionsDict; + NSString *localizedDesc; + NSDictionary *dict; + // insert a localized string here for those folks not savvy to our category methods + descriptionsDict = [descriptions objectForKey:domain]; + localizedDesc = descriptionsDict ? [descriptionsDict objectForKey:[NSNumber numberWithInt:code]] : nil; + dict = [NSDictionary dictionaryWithObjectsAndKeys: + URL, @"NSErrorFailingURLKey", + [URL absoluteString], @"NSErrorFailingURLStringKey", + localizedDesc, NSLocalizedDescriptionKey, + nil]; + return [self initWithDomain:domain code:code userInfo:dict]; +} + ++(id)_webkit_errorWithDomain:(NSString *)domain code:(int)code URL:(NSURL *)URL +{ + return [[[self alloc] _webkit_initWithDomain:domain code:code URL:URL] autorelease]; +} + ++ (NSError *)_webKitErrorWithDomain:(NSString *)domain code:(int)code URL:(NSURL *)URL +{ + [self _registerWebKitErrors]; + return [self _webkit_errorWithDomain:domain code:code URL:URL]; +} + ++ (NSError *)_webKitErrorWithCode:(int)code failingURL:(NSString *)URLString +{ + return [self _webKitErrorWithDomain:WebError::webKitErrorDomain() code:code URL:[NSURL URLWithString:URLString]]; +} + ++ (void)_webkit_addErrorsWithCodesAndDescriptions:(NSDictionary *)dictionary inDomain:(NSString *)domain +{ + if (!descriptions) + descriptions = [[NSMutableDictionary alloc] init]; + + [descriptions setObject:dictionary forKey:domain]; +} + +static void registerErrors() +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + // Policy errors + WebKitErrorDescriptionCannotShowMIMEType, [NSNumber numberWithInt: kWKErrorCodeCannotShowMIMEType], + WebKitErrorDescriptionCannotShowURL, [NSNumber numberWithInt: kWKErrorCodeCannotShowURL], + WebKitErrorDescriptionFrameLoadInterruptedByPolicyChange, [NSNumber numberWithInt: kWKErrorCodeFrameLoadInterruptedByPolicyChange], + WebKitErrorDescriptionCannotUseRestrictedPort, [NSNumber numberWithInt: kWKErrorCodeCannotUseRestrictedPort], + + // Plug-in and java errors + WebKitErrorDescriptionCannotFindPlugin, [NSNumber numberWithInt: kWKErrorCodeCannotFindPlugIn], + WebKitErrorDescriptionCannotLoadPlugin, [NSNumber numberWithInt: kWKErrorCodeCannotLoadPlugIn], + WebKitErrorDescriptionJavaUnavailable, [NSNumber numberWithInt: kWKErrorCodeJavaUnavailable], + WebKitErrorDescriptionPlugInCancelledConnection, [NSNumber numberWithInt: kWKErrorCodePlugInCancelledConnection], + WebKitErrorDescriptionPlugInWillHandleLoad, [NSNumber numberWithInt: kWKErrorCodePlugInWillHandleLoad], + nil]; + + [NSError _webkit_addErrorsWithCodesAndDescriptions:dict inDomain:WebError::webKitErrorDomain()]; + + [pool drain]; +} + +@end + +namespace WebKit { + +ResourceError cancelledError(const ResourceRequest& request) +{ + return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled URL:request.url()]; +} + +ResourceError blockedError(const ResourceRequest& request) +{ + return [NSError _webKitErrorWithDomain:WebError::webKitErrorDomain() code:kWKErrorCodeCannotUseRestrictedPort URL:request.url()]; +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return [NSError _webKitErrorWithDomain:WebError::webKitErrorDomain() code:kWKErrorCodeCannotShowURL URL:request.url()]; +} + +ResourceError interruptForPolicyChangeError(const ResourceRequest& request) +{ + return [NSError _webKitErrorWithDomain:WebError::webKitErrorDomain() code:kWKErrorCodeFrameLoadInterruptedByPolicyChange URL:request.url()]; +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:kWKErrorCodeCannotShowMIMEType URL:response.url()]; +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + return [NSError _webKitErrorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist URL:response.url()]; +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + return [NSError _webKitErrorWithDomain:WebError::webKitErrorDomain() code:kWKErrorCodePlugInWillHandleLoad URL:response.url()]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.h new file mode 100644 index 0000000..994d285 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2010 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 WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#import <WebCore/FrameNetworkingContext.h> + +namespace WebKit { + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebCore::Frame* frame) + { + return adoptRef(new WebFrameNetworkingContext(frame)); + } + +private: + WebFrameNetworkingContext(WebCore::Frame* frame) + : WebCore::FrameNetworkingContext(frame) + { + } + + virtual bool needsSiteSpecificQuirks() const; + virtual bool localFileContentSniffingEnabled() const; + virtual WebCore::SchedulePairHashSet* scheduledRunLoopPairs() const; + virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&) const; +}; + +} + +#endif diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm new file mode 100644 index 0000000..570d351 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm @@ -0,0 +1,50 @@ +/* + Copyright (C) 2010 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. +*/ + +#import "WebFrameNetworkingContext.h" + +#import <WebCore/Page.h> +#import <WebCore/ResourceError.h> +#import <WebCore/Settings.h> + +using namespace WebCore; + +namespace WebKit { + +bool WebFrameNetworkingContext::needsSiteSpecificQuirks() const +{ + return frame() && frame()->settings() && frame()->settings()->needsSiteSpecificQuirks(); +} + +bool WebFrameNetworkingContext::localFileContentSniffingEnabled() const +{ + return frame() && frame()->settings() && frame()->settings()->localFileContentSniffingEnabled(); +} + +SchedulePairHashSet* WebFrameNetworkingContext::scheduledRunLoopPairs() const +{ + return frame() && frame()->page() ? frame()->page()->scheduledRunLoopPairs() : 0; +} + +ResourceError WebFrameNetworkingContext::blockedError(const ResourceRequest& request) const +{ + return frame()->loader()->blockedError(request); +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm new file mode 100644 index 0000000..4d3d167 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm @@ -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 "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" + +using namespace WebCore; + +namespace WebKit { + +void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData&) +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.h b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.h new file mode 100644 index 0000000..da0c2dd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.h @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#ifndef WebSystemInterface_h +#define WebSystemInterface_h + +void InitWebCoreSystemInterface(void); + +#endif /* WebSystemInterface_h */ diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm new file mode 100644 index 0000000..90b9a64 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009, 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. + */ + +#import "WebSystemInterface.h" + +#import <WebCore/WebCoreSystemInterface.h> +#import <WebKitSystemInterface.h> + +#define INIT(function) wk##function = WK##function + +void InitWebCoreSystemInterface(void) +{ + static dispatch_once_t initOnce; + + dispatch_once(&initOnce, ^{ + INIT(AdvanceDefaultButtonPulseAnimation); + INIT(CopyCFLocalizationPreferredName); + INIT(CGContextGetShouldSmoothFonts); + INIT(CopyCONNECTProxyResponse); + INIT(CopyNSURLResponseStatusLine); + INIT(CreateCTLineWithUniCharProvider); + INIT(CreateCustomCFReadStream); + INIT(CreateNSURLConnectionDelegateProxy); + INIT(DrawBezeledTextArea); + INIT(DrawBezeledTextFieldCell); + INIT(DrawCapsLockIndicator); + INIT(DrawFocusRing); + INIT(DrawMediaSliderTrack); + INIT(DrawMediaUIPart); + INIT(DrawTextFieldCellFocusRing); + INIT(GetExtensionsForMIMEType); + INIT(GetFontInLanguageForCharacter); + INIT(GetFontInLanguageForRange); + INIT(GetGlyphTransformedAdvances); + INIT(GetGlyphsForCharacters); + INIT(GetMIMETypeForExtension); + INIT(GetNSURLResponseLastModifiedDate); + INIT(GetPreferredExtensionForMIMEType); + INIT(GetUserToBaseCTM); + INIT(GetWheelEventDeltas); + INIT(HitTestMediaUIPart); + INIT(InitializeMaximumHTTPConnectionCountPerHost); + INIT(IsLatchingWheelEvent); + INIT(MeasureMediaUIPart); + INIT(MediaControllerThemeAvailable); + INIT(PopupMenu); + INIT(QTIncludeOnlyModernMediaFileTypes); + INIT(QTMovieDataRate); + INIT(QTMovieDisableComponent); + INIT(QTMovieGetType); + INIT(QTMovieHasClosedCaptions); + INIT(QTMovieMaxTimeLoaded); + INIT(QTMovieMaxTimeLoadedChangeNotification); + INIT(QTMovieMaxTimeSeekable); + INIT(QTMovieSelectPreferredAlternates); + INIT(QTMovieSetShowClosedCaptions); + INIT(QTMovieViewSetDrawSynchronously); + INIT(SetCGFontRenderingMode); + INIT(SetCONNECTProxyAuthorizationForStream); + INIT(SetCONNECTProxyForStream); + INIT(SetCookieStoragePrivateBrowsingEnabled); + INIT(SetDragImage); + INIT(SetNSURLConnectionDefersCallbacks); + INIT(SetNSURLRequestShouldContentSniff); + INIT(SetPatternBaseCTM); + INIT(SetPatternPhaseInUserSpace); + INIT(SetUpFontCache); + INIT(SignalCFReadStreamEnd); + INIT(SignalCFReadStreamError); + INIT(SignalCFReadStreamHasBytes); + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + INIT(CreateCTTypesetterWithUniCharProviderAndOptions); +#else + INIT(GetHyphenationLocationBeforeIndex); +#endif + }); +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp new file mode 100644 index 0000000..abfb70a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp @@ -0,0 +1,55 @@ +/* + * 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 "WebContextMenuClient.h" + +#include "NotImplemented.h" + +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 diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDatabaseManagerQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDatabaseManagerQt.cpp new file mode 100644 index 0000000..11f929c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDatabaseManagerQt.cpp @@ -0,0 +1,36 @@ +/* + * 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 "WebDatabaseManager.h" + +namespace WebKit { + +String WebDatabaseManager::databaseDirectory() const +{ + // FIXME: Implement. + return ""; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp new file mode 100644 index 0000000..cee6842 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 "WebErrors.h" + +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +#include <QCoreApplication> +#include <QNetworkReply> + +using namespace WebCore; + +namespace WebKit { + +// copied from WebKit/Misc/WebKitErrors[Private].h +enum { + WebKitErrorCannotShowMIMEType = 100, + WebKitErrorCannotShowURL = 101, + WebKitErrorFrameLoadInterruptedByPolicyChange = 102, + WebKitErrorCannotUseRestrictedPort = 103, + WebKitErrorCannotFindPlugIn = 200, + WebKitErrorCannotLoadPlugIn = 201, + WebKitErrorJavaUnavailable = 202, + WebKitErrorPluginWillHandleLoad = 203 +}; + +ResourceError cancelledError(const ResourceRequest& request) +{ + ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().prettyURL(), + QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8)); + error.setIsCancellation(true); + return error; +} + +ResourceError blockedError(const ResourceRequest& request) +{ + return ResourceError("WebKit", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(), + QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return ResourceError("WebKit", WebKitErrorCannotShowURL, request.url().string(), + QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError interruptForPolicyChangeError(const ResourceRequest& request) +{ + return ResourceError("WebKit", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), + QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return ResourceError("WebKit", WebKitErrorCannotShowMIMEType, response.url().string(), + QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + return ResourceError("QtNetwork", QNetworkReply::ContentNotFoundError, response.url().string(), + QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + return ResourceError("WebKit", WebKitErrorPluginWillHandleLoad, response.url().string(), + QCoreApplication::translate("QWebFrame", "Loading is handled by the media engine", 0, QCoreApplication::UnicodeUTF8)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp new file mode 100644 index 0000000..55552e1 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp @@ -0,0 +1,51 @@ +/* + Copyright (C) 2010 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 "WebFrameNetworkingContext.h" + +#include "WebProcess.h" +#include <QNetworkAccessManager> +#include <QObject> + +namespace WebCore { + +WebFrameNetworkingContext::WebFrameNetworkingContext(Frame* frame) + : FrameNetworkingContext(frame) + , m_originatingObject(0) +{ +} + +PassRefPtr<WebFrameNetworkingContext> WebFrameNetworkingContext::create(Frame* frame) +{ + return adoptRef(new WebFrameNetworkingContext(frame)); +} + +QObject* WebFrameNetworkingContext::originatingObject() const +{ + return m_originatingObject; +} + +QNetworkAccessManager* WebFrameNetworkingContext::networkAccessManager() const +{ + return WebKit::WebProcess::shared().networkAccessManager(); +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h new file mode 100644 index 0000000..9c87785 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2010 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 WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#include <WebCore/FrameNetworkingContext.h> + +namespace WebCore { + +class WebFrameNetworkingContext : public FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(Frame*); + +private: + WebFrameNetworkingContext(Frame*); + + virtual QObject* originatingObject() const; + virtual QNetworkAccessManager* networkAccessManager() const; + + QObject* m_originatingObject; +}; + +} + +#endif // WebFrameNetworkingContext_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebPopupMenuQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebPopupMenuQt.cpp new file mode 100644 index 0000000..4d3d167 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebPopupMenuQt.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 "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" + +using namespace WebCore; + +namespace WebKit { + +void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData&) +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebContextMenuClientWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebContextMenuClientWin.cpp new file mode 100644 index 0000000..c16a4d6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebContextMenuClientWin.cpp @@ -0,0 +1,54 @@ +/* + * 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 "WebContextMenuClient.h" +#include <WebCore/NotImplemented.h> + +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 diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDatabaseManagerWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDatabaseManagerWin.cpp new file mode 100644 index 0000000..b6d15fd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDatabaseManagerWin.cpp @@ -0,0 +1,39 @@ +/* + * 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 "WebDatabaseManager.h" + +#include <WebCore/FileSystem.h> + +using namespace WebCore; + +namespace WebKit { + +String WebDatabaseManager::databaseDirectory() const +{ + return WebCore::pathByAppendingComponent(WebCore::localUserSpecificStorageDirectory(), "Databases"); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebErrorsWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebErrorsWin.cpp new file mode 100644 index 0000000..b29b461 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebErrorsWin.cpp @@ -0,0 +1,80 @@ +/* + * 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 "WebErrors.h" + +#include "WKError.h" +#include "WebError.h" +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +#if USE(CFNETWORK) +#include <CFNetwork/CFNetworkErrors.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +ResourceError cancelledError(const ResourceRequest& request) +{ +#if USE(CFNETWORK) + return ResourceError(kCFErrorDomainCFNetwork, kCFURLErrorCancelled, request.url().string(), String()); +#else + return ResourceError(); // FIXME +#endif +} + +ResourceError blockedError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotUseRestrictedPort, request.url().string(), String()); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotShowURL, request.url().string(), String()); +} + +ResourceError interruptForPolicyChangeError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeFrameLoadInterruptedByPolicyChange, request.url().string(), String()); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return ResourceError(); +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + return ResourceError(); +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodePlugInWillHandleLoad, response.url().string(), String()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.cpp new file mode 100644 index 0000000..6b20c1f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.cpp @@ -0,0 +1,20 @@ +/* + Copyright (C) 2010 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. +*/ +// Checking this file in empty to get the build system work out of the way. +// Will put the code in here later. diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.h new file mode 100644 index 0000000..016dcce --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2010 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 WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#include <WebCore/FrameNetworkingContext.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceRequest.h> + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebCore::Frame* frame) + { + return adoptRef(new WebFrameNetworkingContext(frame)); + } + +private: + WebFrameNetworkingContext(WebCore::Frame* frame) + : WebCore::FrameNetworkingContext(frame) + { + } + + virtual WTF::String userAgent() const; + virtual WTF::String referrer() const; + virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&) const; + + WTF::String m_userAgent; +}; + +#endif // WebFrameNetworkingContext_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp new file mode 100644 index 0000000..9c23133 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp @@ -0,0 +1,144 @@ +/* + * 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 "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" +#include <WebCore/Font.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/TextRun.h> +#include <WebCore/PopupMenuClient.h> +#include <WebCore/PopupMenuStyle.h> +#include <WebCore/RenderTheme.h> + +using namespace WebCore; + +namespace WebKit { + +static const int separatorPadding = 4; +static const int separatorHeight = 1; +static const int popupWindowBorderWidth = 1; + +void WebPopupMenu::setUpPlatformData(const WebCore::IntRect& pageCoordinates, PlatformPopupMenuData& data) +{ + int itemCount = m_popupClient->listSize(); + + data.m_clientPaddingLeft = m_popupClient->clientPaddingLeft(); + data.m_clientPaddingRight = m_popupClient->clientPaddingRight(); + data.m_clientInsetLeft = m_popupClient->clientInsetLeft(); + data.m_clientInsetRight = m_popupClient->clientInsetRight(); + data.m_itemHeight = m_popupClient->menuStyle().font().height() + 1; + + int popupWidth = 0; + for (size_t i = 0; i < itemCount; ++i) { + String text = m_popupClient->itemText(i); + if (text.isEmpty()) + continue; + + Font itemFont = m_popupClient->menuStyle().font(); + if (m_popupClient->itemIsLabel(i)) { + FontDescription d = itemFont.fontDescription(); + d.setWeight(d.bolderWeight()); + itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing()); + itemFont.update(m_popupClient->fontSelector()); + } + + popupWidth = std::max(popupWidth, itemFont.width(TextRun(text.characters(), text.length()))); + } + + // FIXME: popupWidth should probably take into account monitor constraints as is done with WebPopupMenuProxyWin::calculatePositionAndSize. + + popupWidth += max(0, data.m_clientPaddingRight - data.m_clientInsetRight) + max(0, data.m_clientPaddingLeft - data.m_clientInsetLeft); + popupWidth += 2 * popupWindowBorderWidth; + data.m_popupWidth = popupWidth; + + // The backing stores should be drawn at least as wide as the control on the page to match the width of the popup window we'll create. + int backingStoreWidth = max(pageCoordinates.width() - m_popupClient->clientInsetLeft() - m_popupClient->clientInsetRight(), popupWidth); + + data.m_backingStoreSize = IntSize(backingStoreWidth, (itemCount * data.m_itemHeight)); + data.m_notSelectedBackingStore = ShareableBitmap::createShareable(data.m_backingStoreSize); + data.m_selectedBackingStore = ShareableBitmap::createShareable(data.m_backingStoreSize); + + OwnPtr<GraphicsContext> notSelectedBackingStoreContext = data.m_notSelectedBackingStore->createGraphicsContext(); + OwnPtr<GraphicsContext> selectedBackingStoreContext = data.m_selectedBackingStore->createGraphicsContext(); + + Color activeOptionBackgroundColor = RenderTheme::defaultTheme()->activeListBoxSelectionBackgroundColor(); + Color activeOptionTextColor = RenderTheme::defaultTheme()->activeListBoxSelectionForegroundColor(); + + for (int y = 0; y < data.m_backingStoreSize.height(); y += data.m_itemHeight) { + int index = y / data.m_itemHeight; + + PopupMenuStyle itemStyle = m_popupClient->itemStyle(index); + + Color optionBackgroundColor = itemStyle.backgroundColor(); + Color optionTextColor = itemStyle.foregroundColor(); + + IntRect itemRect(0, y, backingStoreWidth, data.m_itemHeight); + + // Draw the background for this menu item + if (itemStyle.isVisible()) { + notSelectedBackingStoreContext->fillRect(itemRect, optionBackgroundColor, ColorSpaceDeviceRGB); + selectedBackingStoreContext->fillRect(itemRect, activeOptionBackgroundColor, ColorSpaceDeviceRGB); + } + + if (m_popupClient->itemIsSeparator(index)) { + IntRect separatorRect(itemRect.x() + separatorPadding, itemRect.y() + (itemRect.height() - separatorHeight) / 2, itemRect.width() - 2 * separatorPadding, separatorHeight); + + notSelectedBackingStoreContext->fillRect(separatorRect, optionTextColor, ColorSpaceDeviceRGB); + selectedBackingStoreContext->fillRect(separatorRect, activeOptionTextColor, ColorSpaceDeviceRGB); + continue; + } + + String itemText = m_popupClient->itemText(index); + + unsigned length = itemText.length(); + const UChar* string = itemText.characters(); + TextRun textRun(string, length, false, 0, 0, itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft); + + notSelectedBackingStoreContext->setFillColor(optionTextColor, ColorSpaceDeviceRGB); + selectedBackingStoreContext->setFillColor(activeOptionTextColor, ColorSpaceDeviceRGB); + + Font itemFont = m_popupClient->menuStyle().font(); + if (m_popupClient->itemIsLabel(index)) { + FontDescription d = itemFont.fontDescription(); + d.setWeight(d.bolderWeight()); + itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing()); + itemFont.update(m_popupClient->fontSelector()); + } + + // Draw the item text + if (itemStyle.isVisible()) { + int textX = std::max(0, data.m_clientPaddingLeft - data.m_clientInsetLeft); + if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent() && itemStyle.textDirection() == LTR) + textX += itemStyle.textIndent().calcMinValue(itemRect.width()); + int textY = itemRect.y() + itemFont.ascent() + (itemRect.height() - itemFont.height()) / 2; + + notSelectedBackingStoreContext->drawBidiText(itemFont, textRun, IntPoint(textX, textY)); + selectedBackingStoreContext->drawBidiText(itemFont, textRun, IntPoint(textX, textY)); + } + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebKitMain.cpp b/Source/WebKit2/WebProcess/WebKitMain.cpp new file mode 100644 index 0000000..53084a6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebKitMain.cpp @@ -0,0 +1,174 @@ +/* + * 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 "CommandLine.h" + +#include "PluginProcessMain.h" +#include "ProcessLauncher.h" +#include "WebProcessMain.h" +#include <wtf/text/CString.h> + +#if PLATFORM(MAC) +#include <objc/objc-auto.h> +#endif + +using namespace WebKit; + +static int WebKitMain(const CommandLine& commandLine) +{ + ProcessLauncher::ProcessType processType; + if (!ProcessLauncher::getProcessTypeFromString(commandLine["type"].utf8().data(), processType)) + return EXIT_FAILURE; + + switch (processType) { + case ProcessLauncher::WebProcess: + return WebProcessMain(commandLine); + case ProcessLauncher::PluginProcess: +#if ENABLE(PLUGIN_PROCESS) + return PluginProcessMain(commandLine); +#else + break; +#endif + } + + return EXIT_FAILURE; +} + +#if PLATFORM(MAC) + +extern "C" WK_EXPORT int WebKitMain(int argc, char** argv); + +int WebKitMain(int argc, char** argv) +{ + ASSERT(!objc_collectingEnabled()); + + CommandLine commandLine; + if (!commandLine.parse(argc, argv)) + return EXIT_FAILURE; + + return WebKitMain(commandLine); +} + +#elif PLATFORM(WIN) + +#ifndef DEBUG_ALL +#define PROCESS_NAME L"WebKit2WebKitProcess.exe" +#else +#define PROCESS_NAME L"WebKit2WebProcess_debug.exe" +#endif + +static void enableDataExecutionPrevention() +{ + // Enable Data Execution prevention at runtime rather than via /NXCOMPAT + // http://blogs.msdn.com/michael_howard/archive/2008/01/29/new-nx-apis-added-to-windows-vista-sp1-windows-xp-sp3-and-windows-server-2008.aspx + + const DWORD enableDEP = 0x00000001; + + HMODULE hMod = ::GetModuleHandleW(L"Kernel32.dll"); + if (!hMod) + return; + + typedef BOOL (WINAPI *PSETDEP)(DWORD); + + PSETDEP procSet = reinterpret_cast<PSETDEP>(::GetProcAddress(hMod, "SetProcessDEPPolicy")); + if (!procSet) + return; + + // Enable Data Execution Prevention, but allow ATL thunks (for compatibility with the version of ATL that ships with the Platform SDK). + procSet(enableDEP); +} + +static void enableTerminationOnHeapCorruption() +{ + // Enable termination on heap corruption on OSes that support it (Vista and XPSP3). + // http://msdn.microsoft.com/en-us/library/aa366705(VS.85).aspx + + const HEAP_INFORMATION_CLASS heapEnableTerminationOnCorruption = static_cast<HEAP_INFORMATION_CLASS>(1); + + HMODULE hMod = ::GetModuleHandleW(L"kernel32.dll"); + if (!hMod) + return; + + typedef BOOL (WINAPI*HSI)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T); + HSI heapSetInformation = reinterpret_cast<HSI>(::GetProcAddress(hMod, "HeapSetInformation")); + if (!heapSetInformation) + return; + + heapSetInformation(0, heapEnableTerminationOnCorruption, 0, 0); +} + +static void disableUserModeCallbackExceptionFilter() +{ + const DWORD PROCESS_CALLBACK_FILTER_ENABLED = 0x1; + typedef BOOL (NTAPI *getProcessUserModeExceptionPolicyPtr)(LPDWORD lpFlags); + typedef BOOL (NTAPI *setProcessUserModeExceptionPolicyPtr)(DWORD dwFlags); + + HMODULE lib = LoadLibrary(TEXT("kernel32.dll")); + ASSERT(lib); + + getProcessUserModeExceptionPolicyPtr getPolicyPtr = (getProcessUserModeExceptionPolicyPtr)GetProcAddress(lib, "GetProcessUserModeExceptionPolicy"); + setProcessUserModeExceptionPolicyPtr setPolicyPtr = (setProcessUserModeExceptionPolicyPtr)GetProcAddress(lib, "SetProcessUserModeExceptionPolicy"); + + DWORD dwFlags; + if (!getPolicyPtr || !setPolicyPtr || !getPolicyPtr(&dwFlags)) { + FreeLibrary(lib); + return; + } + + // If this flag isn't cleared, exceptions that are thrown when running in a 64-bit version of + // Windows are ignored, possibly leaving Safari in an inconsistent state that could cause an + // unrelated exception to be thrown. + // http://support.microsoft.com/kb/976038 + // http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/ + setPolicyPtr(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); + + FreeLibrary(lib); +} + +extern "C" __declspec(dllexport) +int WebKitMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrCmdLine, int nCmdShow) +{ +#ifndef NDEBUG + // Show an alert when Ctrl-Alt-Shift is held down during launch to give the user time to attach a + // debugger. This is useful for debugging problems that happen early in the web process's lifetime. + const unsigned short highBitMaskShort = 0x8000; + if (getenv("WEBKIT2_PAUSE_WEB_PROCESS_ON_LAUNCH") || (::GetKeyState(VK_CONTROL) & highBitMaskShort) && (::GetKeyState(VK_MENU) & highBitMaskShort) && (::GetKeyState(VK_SHIFT) & highBitMaskShort)) + ::MessageBoxW(0, L"You can now attach a debugger to " PROCESS_NAME L". You can use\nthe same debugger for WebKit2WebProcessand the UI process, if desired.\nClick OK when you are ready for WebKit2WebProcess to continue.", L"WebKit2WebProcess has launched", MB_OK | MB_ICONINFORMATION); +#endif + + enableDataExecutionPrevention(); + + enableTerminationOnHeapCorruption(); + + disableUserModeCallbackExceptionFilter(); + + CommandLine commandLine; + if (!commandLine.parse(lpstrCmdLine)) + return EXIT_FAILURE; + + return WebKitMain(commandLine); +} + +#endif diff --git a/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp new file mode 100644 index 0000000..513621c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.cpp @@ -0,0 +1,221 @@ +/* + * 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 "ChunkedUpdateDrawingArea.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "MessageID.h" +#include "UpdateChunk.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebProcess.h" + +using namespace WebCore; + +namespace WebKit { + +ChunkedUpdateDrawingArea::ChunkedUpdateDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::ChunkedUpdate, identifier, webPage) + , m_isWaitingForUpdate(false) + , m_paintingIsSuspended(false) + , m_displayTimer(WebProcess::shared().runLoop(), this, &ChunkedUpdateDrawingArea::display) +{ +} + +ChunkedUpdateDrawingArea::~ChunkedUpdateDrawingArea() +{ +} + +void ChunkedUpdateDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void ChunkedUpdateDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + // FIXME: Collect a set of rects/region instead of just the union + // of all rects. + m_dirtyRect.unite(rect); + scheduleDisplay(); +} + +void ChunkedUpdateDrawingArea::display() +{ + ASSERT(!m_isWaitingForUpdate); + + if (m_paintingIsSuspended) + return; + + if (m_dirtyRect.isEmpty()) + return; + + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<ChunkedUpdateDrawingArea> protect(this); + + // Layout if necessary. + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + IntRect dirtyRect = m_dirtyRect; + m_dirtyRect = IntRect(); + + // Create a new UpdateChunk and paint into it. + UpdateChunk updateChunk(dirtyRect); + paintIntoUpdateChunk(&updateChunk); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::Update, m_webPage->pageID(), CoreIPC::In(updateChunk)); + + m_isWaitingForUpdate = true; + m_displayTimer.stop(); +} + +void ChunkedUpdateDrawingArea::scheduleDisplay() +{ + if (m_paintingIsSuspended) + return; + + if (m_isWaitingForUpdate) + return; + + if (m_dirtyRect.isEmpty()) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void ChunkedUpdateDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + // We don't want to wait for an update until we display. + m_isWaitingForUpdate = false; + + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<ChunkedUpdateDrawingArea> protect(this); + + m_webPage->setSize(viewSize); + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + if (m_paintingIsSuspended) { + ASSERT(!m_displayTimer.isActive()); + + // Painting is suspended, just send back an empty update chunk. + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(UpdateChunk())); + return; + } + + // Create a new UpdateChunk and paint into it. + UpdateChunk updateChunk(IntRect(0, 0, viewSize.width(), viewSize.height())); + paintIntoUpdateChunk(&updateChunk); + + m_displayTimer.stop(); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(updateChunk)); +} + +void ChunkedUpdateDrawingArea::suspendPainting() +{ + ASSERT(!m_paintingIsSuspended); + + m_paintingIsSuspended = true; + m_displayTimer.stop(); +} + +void ChunkedUpdateDrawingArea::resumePainting(bool forceRepaint) +{ + ASSERT(m_paintingIsSuspended); + + m_paintingIsSuspended = false; + + if (forceRepaint) { + // Just set the dirty rect to the entire page size. + m_dirtyRect = IntRect(IntPoint(0, 0), m_webPage->size()); + } + + // Schedule a display. + scheduleDisplay(); +} + +void ChunkedUpdateDrawingArea::didUpdate() +{ + m_isWaitingForUpdate = false; + + // Display if needed. + display(); +} + +void ChunkedUpdateDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + DrawingAreaInfo::Identifier targetIdentifier; + if (!arguments->decode(CoreIPC::Out(targetIdentifier))) + return; + + // We can switch drawing areas on the fly, so if this message was targetted at an obsolete drawing area, ignore it. + if (targetIdentifier != info().identifier) + return; + + switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) { + case DrawingAreaLegacyMessage::SetSize: { + IntSize size; + if (!arguments->decode(CoreIPC::Out(size))) + return; + + setSize(size); + break; + } + + case DrawingAreaLegacyMessage::SuspendPainting: + suspendPainting(); + break; + + case DrawingAreaLegacyMessage::ResumePainting: { + bool forceRepaint; + if (!arguments->decode(CoreIPC::Out(forceRepaint))) + return; + + resumePainting(forceRepaint); + break; + } + case DrawingAreaLegacyMessage::DidUpdate: + didUpdate(); + break; + + default: + ASSERT_NOT_REACHED(); + break; + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.h new file mode 100644 index 0000000..ac4b424 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ChunkedUpdateDrawingArea.h @@ -0,0 +1,76 @@ +/* + * 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. + */ + +#ifndef ChunkedUpdateDrawingArea_h +#define ChunkedUpdateDrawingArea_h + +#include "DrawingArea.h" +#include "RunLoop.h" +#include <WebCore/IntPoint.h> + +namespace WebKit { + +class UpdateChunk; + +class ChunkedUpdateDrawingArea : public DrawingArea { +public: + ChunkedUpdateDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage*); + virtual ~ChunkedUpdateDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void display(); + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() { } + virtual void detachCompositingContext() { } + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { } + virtual void scheduleCompositingLayerSync() { } + virtual void syncCompositingLayers() { } +#endif + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + void scheduleDisplay(); + + // CoreIPC message handlers. + void setSize(const WebCore::IntSize& viewSize); + void suspendPainting(); + void resumePainting(bool forceRepaint); + void didUpdate(); + + // Platform overrides + void paintIntoUpdateChunk(UpdateChunk*); + + WebCore::IntRect m_dirtyRect; + bool m_isWaitingForUpdate; + bool m_paintingIsSuspended; + RunLoop::Timer<ChunkedUpdateDrawingArea> m_displayTimer; +}; + +} // namespace WebKit + +#endif // ChunkedUpdateDrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp new file mode 100644 index 0000000..e5de52f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 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 "DecoderAdapter.h" + +#include "WebCoreArgumentCoders.h" + +namespace WebKit { + +DecoderAdapter::DecoderAdapter(const uint8_t* buffer, size_t bufferSize) + : m_decoder(buffer, bufferSize) +{ +} + +bool DecoderAdapter::decodeBytes(Vector<uint8_t>& bytes) +{ + return m_decoder.decodeBytes(bytes); +} + +bool DecoderAdapter::decodeBool(bool& value) +{ + return m_decoder.decodeBool(value); +} + +bool DecoderAdapter::decodeUInt32(uint32_t& value) +{ + return m_decoder.decodeUInt32(value); +} + +bool DecoderAdapter::decodeUInt64(uint64_t& value) +{ + return m_decoder.decodeUInt64(value); +} + +bool DecoderAdapter::decodeInt32(int32_t& value) +{ + return m_decoder.decodeInt32(value); +} + +bool DecoderAdapter::decodeInt64(int64_t& value) +{ + return m_decoder.decodeInt64(value); +} + +bool DecoderAdapter::decodeFloat(float& value) +{ + return m_decoder.decodeFloat(value); +} + +bool DecoderAdapter::decodeDouble(double& value) +{ + return m_decoder.decodeDouble(value); +} + +bool DecoderAdapter::decodeString(String& value) +{ + return m_decoder.decode(value); +} + +} diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h new file mode 100644 index 0000000..bd34ea8 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 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 DecoderAdapter_h +#define DecoderAdapter_h + +#include "ArgumentDecoder.h" +#include <wtf/Decoder.h> +#include <wtf/Forward.h> + +namespace WebKit { + +class DecoderAdapter : public Decoder { +public: + DecoderAdapter(const uint8_t* buffer, size_t bufferSize); + +private: + virtual bool decodeBytes(Vector<uint8_t>&); + virtual bool decodeBool(bool&); + virtual bool decodeUInt32(uint32_t&); + virtual bool decodeUInt64(uint64_t&); + virtual bool decodeInt32(int32_t&); + virtual bool decodeInt64(int64_t&); + virtual bool decodeFloat(float&); + virtual bool decodeDouble(double&); + virtual bool decodeString(String&); + + CoreIPC::ArgumentDecoder m_decoder; +}; + +} // namespace WebKit + +#endif // DecoderAdapter_h diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp new file mode 100644 index 0000000..3b76aaf --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp @@ -0,0 +1,84 @@ +/* + * 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 "DrawingArea.h" + +// Subclasses +#include "ChunkedUpdateDrawingArea.h" + +#ifdef __APPLE__ +#include "DrawingAreaImpl.h" +#endif + +#if USE(ACCELERATED_COMPOSITING) +#include "LayerBackedDrawingArea.h" +#endif + +#if ENABLE(TILED_BACKING_STORE) +#include "TiledDrawingArea.h" +#endif + +namespace WebKit { + +PassRefPtr<DrawingArea> DrawingArea::create(DrawingAreaInfo::Type type, DrawingAreaInfo::Identifier identifier, WebPage* webPage) +{ + switch (type) { + case DrawingAreaInfo::None: + ASSERT_NOT_REACHED(); + break; + + case DrawingAreaInfo::Impl: +#ifdef __APPLE__ + return DrawingAreaImpl::create(identifier, webPage); +#else + return 0; +#endif + case DrawingAreaInfo::ChunkedUpdate: + return adoptRef(new ChunkedUpdateDrawingArea(identifier, webPage)); + +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + case DrawingAreaInfo::LayerBacked: + return adoptRef(new LayerBackedDrawingArea(identifier, webPage)); +#endif +#if ENABLE(TILED_BACKING_STORE) + case DrawingAreaInfo::Tiled: + return adoptRef(new TiledDrawingArea(identifier, webPage)); +#endif + } + + return 0; +} + +DrawingArea::DrawingArea(DrawingAreaInfo::Type type, DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : m_info(type, identifier) + , m_webPage(webPage) +{ +} + +DrawingArea::~DrawingArea() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.h b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h new file mode 100644 index 0000000..75f0b00 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h @@ -0,0 +1,88 @@ +/* + * 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. + */ + +#ifndef DrawingArea_h +#define DrawingArea_h + +#include "DrawingAreaInfo.h" +#include <WebCore/IntRect.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { +#if USE(ACCELERATED_COMPOSITING) + class GraphicsLayer; +#endif +} + +namespace WebKit { + +class WebPage; + +class DrawingArea : public RefCounted<DrawingArea> { +public: + // FIXME: It might make sense to move this create function into a factory style class. + static PassRefPtr<DrawingArea> create(DrawingAreaInfo::Type, DrawingAreaInfo::Identifier, WebPage*); + virtual ~DrawingArea(); + +#ifdef __APPLE__ + void didReceiveDrawingAreaMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +#endif + + virtual void setNeedsDisplay(const WebCore::IntRect&) = 0; + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta) = 0; + + virtual void pageBackgroundTransparencyChanged() { } + + virtual void onPageClose() { } + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() = 0; + virtual void detachCompositingContext() = 0; + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0; + virtual void scheduleCompositingLayerSync() = 0; + virtual void syncCompositingLayers() = 0; +#endif + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*) = 0; + + const DrawingAreaInfo& info() const { return m_info; } + +protected: + DrawingArea(DrawingAreaInfo::Type, DrawingAreaInfo::Identifier, WebPage*); + + DrawingAreaInfo m_info; + WebPage* m_webPage; + +private: + // CoreIPC message handlers. + // FIXME: These should be pure virtual. + virtual void setSize(const WebCore::IntSize&) { } + virtual void didUpdate() { } +}; + +} // namespace WebKit + +#endif // DrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in new file mode 100644 index 0000000..6c628fb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in @@ -0,0 +1,26 @@ +# Copyright (C) 2010, 2011 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. + +messages -> DrawingArea { + SetSize(WebCore::IntSize size) + DidUpdate() +} diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp new file mode 100644 index 0000000..ab4655a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2011 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 "DrawingAreaImpl.h" + +#include "DrawingAreaProxyMessages.h" +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/GraphicsContext.h> + +#ifndef __APPLE__ +#error "This drawing area is not ready for use by other ports yet." +#endif + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<DrawingAreaImpl> DrawingAreaImpl::create(DrawingAreaInfo::Identifier identifier, WebPage* webPage) +{ + return adoptRef(new DrawingAreaImpl(identifier, webPage)); +} + +DrawingAreaImpl::~DrawingAreaImpl() +{ +} + +DrawingAreaImpl::DrawingAreaImpl(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::Impl, identifier, webPage) + , m_isWaitingForDidUpdate(false) + , m_displayTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::display) +{ +} + +void DrawingAreaImpl::setNeedsDisplay(const IntRect& rect) +{ + if (rect.isEmpty()) + return; + + m_dirtyRegion.unite(rect); + scheduleDisplay(); +} + +void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) { + unsigned scrollArea = scrollRect.width() * scrollRect.height(); + unsigned currentScrollArea = m_scrollRect.width() * m_scrollRect.height(); + + if (currentScrollArea >= scrollArea) { + // The rect being scrolled is at least as large as the rect we'd like to scroll. + // Go ahead and just invalidate the scroll rect. + setNeedsDisplay(scrollRect); + return; + } + + // Just repaint the entire current scroll rect, we'll scroll the new rect instead. + setNeedsDisplay(m_scrollRect); + m_scrollRect = IntRect(); + m_scrollDelta = IntSize(); + } + + // Get the part of the dirty region that is in the scroll rect. + Region dirtyRegionInScrollRect = intersect(scrollRect, m_dirtyRegion); + if (!dirtyRegionInScrollRect.isEmpty()) { + // There are parts of the dirty region that are inside the scroll rect. + // We need to subtract them from the region, move them and re-add them. + m_dirtyRegion.subtract(scrollRect); + + // Move the dirty parts. + Region movedDirtyRegionInScrollRect = intersect(translate(dirtyRegionInScrollRect, scrollDelta), scrollRect); + + // And add them back. + m_dirtyRegion.unite(movedDirtyRegionInScrollRect); + } + + // Compute the scroll repaint region. + Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollDelta)); + + m_dirtyRegion.unite(scrollRepaintRegion); + + m_scrollRect = scrollRect; + m_scrollDelta += scrollDelta; +} + +void DrawingAreaImpl::attachCompositingContext() +{ +} + +void DrawingAreaImpl::detachCompositingContext() +{ +} + +void DrawingAreaImpl::setRootCompositingLayer(WebCore::GraphicsLayer*) +{ +} + +void DrawingAreaImpl::scheduleCompositingLayerSync() +{ +} + +void DrawingAreaImpl::syncCompositingLayers() +{ +} + +void DrawingAreaImpl::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*) +{ +} + +void DrawingAreaImpl::setSize(const IntSize& size) +{ + // Set this to false since we're about to call display(). + m_isWaitingForDidUpdate = false; + + m_webPage->setSize(size); + m_webPage->layoutIfNeeded(); + + // FIXME: Repaint. + + m_webPage->send(Messages::DrawingAreaProxy::DidSetSize()); +} + +void DrawingAreaImpl::didUpdate() +{ + m_isWaitingForDidUpdate = false; + + // Display if needed. + display(); +} + +void DrawingAreaImpl::scheduleDisplay() +{ + if (m_isWaitingForDidUpdate) + return; + + if (m_dirtyRegion.isEmpty()) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void DrawingAreaImpl::display() +{ + if (m_dirtyRegion.isEmpty()) + return; + + UpdateInfo updateInfo; + display(updateInfo); + + m_webPage->send(Messages::DrawingAreaProxy::Update(updateInfo)); + m_isWaitingForDidUpdate = true; +} + +static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects) +{ + const size_t rectThreshold = 10; + const float wastedSpaceThreshold = 0.75f; + + if (rects.size() <= 1 || rects.size() > rectThreshold) + return true; + + // Attempt to guess whether or not we should use the region bounds rect or the individual rects. + // We do this by computing the percentage of "wasted space" in the bounds. If that wasted space + // is too large, then we will do individual rect painting instead. + unsigned boundsArea = bounds.width() * bounds.height(); + unsigned rectsArea = 0; + for (size_t i = 0; i < rects.size(); ++i) + rectsArea += rects[i].width() * rects[i].height(); + + float wastedSpace = 1 - (rectsArea / boundsArea); + + return wastedSpace <= wastedSpaceThreshold; +} + +void DrawingAreaImpl::display(UpdateInfo& updateInfo) +{ + // FIXME: It would be better if we could avoid painting altogether when there is a custom representation. + if (m_webPage->mainFrameHasCustomRepresentation()) + return; + + IntRect bounds = m_dirtyRegion.bounds(); + Vector<IntRect> rects = m_dirtyRegion.rects(); + + if (shouldPaintBoundsRect(bounds, rects)) { + rects.clear(); + rects.append(bounds); + } + + updateInfo.scrollRect = m_scrollRect; + updateInfo.scrollDelta = m_scrollDelta; + + m_dirtyRegion = Region(); + m_scrollRect = IntRect(); + m_scrollDelta = IntSize(); + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bounds.size()); + if (!bitmap->createHandle(updateInfo.bitmapHandle)) + return; + + OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + + m_webPage->layoutIfNeeded(); + + updateInfo.viewSize = m_webPage->size(); + updateInfo.updateRectBounds = bounds; + + graphicsContext->translate(-bounds.x(), -bounds.y()); + + for (size_t i = 0; i < rects.size(); ++i) { + m_webPage->drawRect(*graphicsContext, rects[i]); + updateInfo.updateRects.append(rects[i]); + } + + // Layout can trigger more calls to setNeedsDisplay and we don't want to process them + // until the UI process has painted the update, so we stop the timer here. + m_displayTimer.stop(); +} + + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h new file mode 100644 index 0000000..1f1b2e2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2011 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 DrawingAreaImpl_h +#define DrawingAreaImpl_h + +#include "DrawingArea.h" +#include "Region.h" +#include "RunLoop.h" + +namespace WebKit { + +struct UpdateInfo; + +class DrawingAreaImpl : public DrawingArea { +public: + static PassRefPtr<DrawingAreaImpl> create(DrawingAreaInfo::Identifier, WebPage*); + virtual ~DrawingAreaImpl(); + +private: + DrawingAreaImpl(DrawingAreaInfo::Identifier, WebPage*); + + // DrawingArea + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void attachCompositingContext(); + virtual void detachCompositingContext(); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + virtual void scheduleCompositingLayerSync(); + virtual void syncCompositingLayers(); + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + // CoreIPC message handlers. + virtual void setSize(const WebCore::IntSize&); + virtual void didUpdate(); + + void scheduleDisplay(); + void display(); + void display(UpdateInfo&); + + Region m_dirtyRegion; + WebCore::IntRect m_scrollRect; + WebCore::IntSize m_scrollDelta; + + // Whether we're waiting for a DidUpdate message. Used for throttling paints so that the + // web process won't paint more frequent than the UI process can handle. + bool m_isWaitingForDidUpdate; + + RunLoop::Timer<DrawingAreaImpl> m_displayTimer; +}; + +} // namespace WebKit + +#endif // DrawingAreaImpl_h diff --git a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp new file mode 100644 index 0000000..00edcce --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2011 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 "EncoderAdapter.h" + +#include "DataReference.h" +#include "WebCoreArgumentCoders.h" + +namespace WebKit { + +EncoderAdapter::EncoderAdapter() + : m_encoder(CoreIPC::ArgumentEncoder::create(0)) +{ +} + +CoreIPC::DataReference EncoderAdapter::data() const +{ + return CoreIPC::DataReference(m_encoder->buffer(), m_encoder->bufferSize()); +} + +void EncoderAdapter::encodeBytes(const uint8_t* bytes, size_t size) +{ + m_encoder->encodeBytes(bytes, size); +} + +void EncoderAdapter::encodeBool(bool value) +{ + m_encoder->encodeBool(value); +} + +void EncoderAdapter::encodeUInt32(uint32_t value) +{ + m_encoder->encodeUInt32(value); +} + +void EncoderAdapter::encodeUInt64(uint64_t value) +{ + m_encoder->encodeUInt64(value); +} + +void EncoderAdapter::encodeInt32(int32_t value) +{ + m_encoder->encodeInt32(value); +} + +void EncoderAdapter::encodeInt64(int64_t value) +{ + m_encoder->encodeInt64(value); +} + +void EncoderAdapter::encodeFloat(float value) +{ + m_encoder->encodeFloat(value); +} + +void EncoderAdapter::encodeDouble(double value) +{ + m_encoder->encodeDouble(value); +} + +void EncoderAdapter::encodeString(const String& value) +{ + m_encoder->encode(value); +} + +} diff --git a/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h new file mode 100644 index 0000000..ae88a98 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 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 EncoderAdapter_h +#define EncoderAdapter_h + +#include <wtf/Encoder.h> +#include <wtf/Forward.h> +#include <wtf/OwnPtr.h> + +namespace CoreIPC { + class ArgumentEncoder; + class DataReference; +} + +namespace WebKit { + +class EncoderAdapter : public Encoder { +public: + EncoderAdapter(); + + CoreIPC::DataReference data() const; + +private: + virtual void encodeBytes(const uint8_t*, size_t); + virtual void encodeBool(bool); + virtual void encodeUInt32(uint32_t); + virtual void encodeUInt64(uint64_t); + virtual void encodeInt32(int32_t); + virtual void encodeInt64(int64_t); + virtual void encodeFloat(float); + virtual void encodeDouble(double); + virtual void encodeString(const String&); + + OwnPtr<CoreIPC::ArgumentEncoder> m_encoder; +}; + +} // namespace WebKit + +#endif // EncoderAdapter_h diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.cpp b/Source/WebKit2/WebProcess/WebPage/FindController.cpp new file mode 100644 index 0000000..9b8669d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/FindController.cpp @@ -0,0 +1,300 @@ +/* + * 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 "FindController.h" + +#include "ShareableBitmap.h" +#include "WKPage.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/DocumentMarkerController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +static WebCore::FindOptions core(FindOptions options) +{ + return (options & FindOptionsCaseInsensitive ? CaseInsensitive : 0) + | (options & FindOptionsAtWordStarts ? AtWordStarts : 0) + | (options & FindOptionsTreatMedialCapitalAsWordStart ? TreatMedialCapitalAsWordStart : 0) + | (options & FindOptionsBackwards ? Backwards : 0) + | (options & FindOptionsWrapAround ? WrapAround : 0); +} + +FindController::FindController(WebPage* webPage) + : m_webPage(webPage) + , m_findPageOverlay(0) + , m_isShowingFindIndicator(false) +{ +} + +FindController::~FindController() +{ +} + +void FindController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) +{ + unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount); + m_webPage->corePage()->unmarkAllTextMatches(); + + m_webPage->send(Messages::WebPageProxy::DidCountStringMatches(string, matchCount)); +} + +static Frame* frameWithSelection(Page* page) +{ + for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { + if (frame->selection()->isRange()) + return frame; + } + + return 0; +} + +void FindController::findString(const String& string, FindOptions options, unsigned maxMatchCount) +{ + m_webPage->corePage()->unmarkAllTextMatches(); + + bool found = m_webPage->corePage()->findString(string, core(options)); + + Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); + + bool shouldShowOverlay = false; + + if (!found) { + // Clear the selection. + if (selectedFrame) + selectedFrame->selection()->clear(); + + hideFindIndicator(); + + m_webPage->send(Messages::WebPageProxy::DidFailToFindString(string)); + } else { + shouldShowOverlay = options & FindOptionsShowOverlay; + + if (shouldShowOverlay) { + unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1); + + // Check if we have more matches than allowed. + if (matchCount > maxMatchCount) { + shouldShowOverlay = false; + matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount); + } + + m_webPage->send(Messages::WebPageProxy::DidFindString(string, matchCount)); + } + + if (!(options & FindOptionsShowFindIndicator) || !updateFindIndicator(selectedFrame, shouldShowOverlay)) { + // Either we shouldn't show the find indicator, or we couldn't update it. + hideFindIndicator(); + } + } + + if (!shouldShowOverlay) { + if (m_findPageOverlay) { + // Get rid of the overlay. + m_webPage->uninstallPageOverlay(m_findPageOverlay); + } + + ASSERT(!m_findPageOverlay); + return; + } + + if (!m_findPageOverlay) { + RefPtr<PageOverlay> findPageOverlay = PageOverlay::create(this); + m_findPageOverlay = findPageOverlay.get(); + m_webPage->installPageOverlay(findPageOverlay.release()); + } else { + // The page overlay needs to be repainted. + m_findPageOverlay->setNeedsDisplay(); + } +} + +void FindController::hideFindUI() +{ + if (m_findPageOverlay) + m_webPage->uninstallPageOverlay(m_findPageOverlay); + + hideFindIndicator(); +} + +bool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay) +{ + if (!selectedFrame) + return false; + + // We want the selection rect in window coordinates. + IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(enclosingIntRect(selectedFrame->selection()->bounds())); + + Vector<FloatRect> textRects; + selectedFrame->selection()->getClippedVisibleTextRectangles(textRects); + + // Create a backing store and paint the find indicator text into it. + RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(selectionRectInWindowCoordinates.size()); + OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext(); + + graphicsContext->translate(-selectionRectInWindowCoordinates.x(), -selectionRectInWindowCoordinates.y()); + selectedFrame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers); + selectedFrame->document()->updateLayout(); + + graphicsContext->clip(selectionRectInWindowCoordinates); + selectedFrame->view()->paint(graphicsContext.get(), selectionRectInWindowCoordinates); + selectedFrame->view()->setPaintBehavior(PaintBehaviorNormal); + + SharedMemory::Handle handle; + if (!findIndicatorTextBackingStore->createHandle(handle)) + return false; + + // We want the text rects in selection rect coordinates. + Vector<FloatRect> textRectsInSelectionRectCoordinates; + + for (size_t i = 0; i < textRects.size(); ++i) { + IntRect textRectInSelectionRectCoordinates = selectedFrame->view()->contentsToWindow(enclosingIntRect(textRects[i])); + textRectInSelectionRectCoordinates.move(-selectionRectInWindowCoordinates.x(), -selectionRectInWindowCoordinates.y()); + + textRectsInSelectionRectCoordinates.append(textRectInSelectionRectCoordinates); + } + + m_webPage->send(Messages::WebPageProxy::SetFindIndicator(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, handle, !isShowingOverlay)); + m_isShowingFindIndicator = true; + + return true; +} + +void FindController::hideFindIndicator() +{ + if (!m_isShowingFindIndicator) + return; + + SharedMemory::Handle handle; + m_webPage->send(Messages::WebPageProxy::SetFindIndicator(FloatRect(), Vector<FloatRect>(), handle, false)); + m_isShowingFindIndicator = false; +} + +Vector<IntRect> FindController::rectsForTextMatches() +{ + Vector<IntRect> rects; + + for (Frame* frame = m_webPage->corePage()->mainFrame(); frame; frame = frame->tree()->traverseNext()) { + Document* document = frame->document(); + if (!document) + continue; + + IntRect visibleRect = frame->view()->visibleContentRect(); + Vector<IntRect> frameRects = document->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch); + IntPoint frameOffset(-frame->view()->scrollOffset().width(), -frame->view()->scrollOffset().height()); + frameOffset = frame->view()->convertToContainingWindow(frameOffset); + + for (Vector<IntRect>::iterator it = frameRects.begin(), end = frameRects.end(); it != end; ++it) { + it->intersect(visibleRect); + it->move(frameOffset.x(), frameOffset.y()); + rects.append(*it); + } + } + + return rects; +} + +void FindController::pageOverlayDestroyed(PageOverlay*) +{ +} + +void FindController::willMoveToWebPage(PageOverlay*, WebPage* webPage) +{ + if (webPage) + return; + + // The page overlay is moving away from the web page, reset it. + ASSERT(m_findPageOverlay); + m_findPageOverlay = 0; +} + +void FindController::didMoveToWebPage(PageOverlay*, WebPage*) +{ +} + +static const float shadowOffsetX = 0.0; +static const float shadowOffsetY = 1.0; +static const float shadowBlurRadius = 2.0; +static const float whiteFrameThickness = 1.0; + +static const int overlayBackgroundRed = 25; +static const int overlayBackgroundGreen = 25; +static const int overlayBackgroundBlue = 25; +static const int overlayBackgroundAlpha = 63; + +static Color overlayBackgroundColor() +{ + return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha); +} + +void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect) +{ + Vector<IntRect> rects = rectsForTextMatches(); + ASSERT(!rects.isEmpty()); + + // Draw the background. + graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(), ColorSpaceSRGB); + + graphicsContext.save(); + graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB); + + graphicsContext.setFillColor(Color::white, ColorSpaceSRGB); + + // Draw white frames around the holes. + for (size_t i = 0; i < rects.size(); ++i) { + IntRect whiteFrameRect = rects[i]; + whiteFrameRect.inflate(1); + + graphicsContext.fillRect(whiteFrameRect); + } + + graphicsContext.restore(); + + graphicsContext.setFillColor(Color::transparent, ColorSpaceSRGB); + + // Clear out the holes. + for (size_t i = 0; i < rects.size(); ++i) + graphicsContext.fillRect(rects[i]); +} + +bool FindController::mouseEvent(PageOverlay* pageOverlay, const WebMouseEvent& mouseEvent) +{ + // If we get a mouse down event inside the page overlay we should hide the find UI. + if (mouseEvent.type() == WebEvent::MouseDown) { + // Dismiss the overlay. + hideFindUI(); + } + + return false; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.h b/Source/WebKit2/WebProcess/WebPage/FindController.h new file mode 100644 index 0000000..110a7a4 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/FindController.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +#ifndef FindController_h +#define FindController_h + +#include "PageOverlay.h" +#include "WebFindOptions.h" +#include <wtf/Forward.h> +#include <wtf/Noncopyable.h> +#include <wtf/Vector.h> + +namespace WebCore { + class Frame; + class IntRect; +} + +namespace WebKit { + +class WebPage; + +class FindController : private PageOverlay::Client { + WTF_MAKE_NONCOPYABLE(FindController); + +public: + explicit FindController(WebPage*); + virtual ~FindController(); + + void findString(const String&, FindOptions, unsigned maxMatchCount); + void hideFindUI(); + void countStringMatches(const String&, FindOptions, unsigned maxMatchCount); + + void hideFindIndicator(); + +private: + // PageOverlay::Client. + virtual void pageOverlayDestroyed(PageOverlay*); + virtual void willMoveToWebPage(PageOverlay*, WebPage*); + virtual void didMoveToWebPage(PageOverlay*, WebPage*); + virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&); + virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect); + + Vector<WebCore::IntRect> rectsForTextMatches(); + bool updateFindIndicator(WebCore::Frame* selectedFrame, bool isShowingOverlay); + +private: + WebPage* m_webPage; + PageOverlay* m_findPageOverlay; + + // Whether the UI process is showing the find indicator. Note that this can be true even if + // the find indicator isn't showing, but it will never be false when it is showing. + bool m_isShowingFindIndicator; +}; + +} // namespace WebKit + +#endif // FindController_h diff --git a/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.cpp new file mode 100644 index 0000000..8a81cca --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.cpp @@ -0,0 +1,230 @@ +/* + * 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. + */ + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerBackedDrawingArea.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "MessageID.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/GraphicsLayer.h> + +using namespace WebCore; + +namespace WebKit { + +LayerBackedDrawingArea::LayerBackedDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::LayerBacked, identifier, webPage) + , m_syncTimer(WebProcess::shared().runLoop(), this, &LayerBackedDrawingArea::syncCompositingLayers) + , m_attached(false) + , m_shouldPaint(true) +{ + m_backingLayer = GraphicsLayer::create(this); + m_backingLayer->setDrawsContent(true); + m_backingLayer->setContentsOpaque(webPage->drawsBackground() && !webPage->drawsTransparentBackground()); + +#ifndef NDEBUG + m_backingLayer->setName("DrawingArea backing layer"); +#endif + m_backingLayer->setSize(webPage->size()); + platformInit(); +} + +LayerBackedDrawingArea::~LayerBackedDrawingArea() +{ + platformClear(); +} + +void LayerBackedDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void LayerBackedDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + m_backingLayer->setNeedsDisplayInRect(rect); + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::display() +{ + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<LayerBackedDrawingArea> protect(this); + + // Layout if necessary. + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; +} + +void LayerBackedDrawingArea::pageBackgroundTransparencyChanged() +{ + m_backingLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); +} + +void LayerBackedDrawingArea::scheduleDisplay() +{ +} + +void LayerBackedDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT(m_shouldPaint); + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + m_backingLayer->setSize(viewSize); + scheduleCompositingLayerSync(); + + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<LayerBackedDrawingArea> protect(this); + + m_webPage->setSize(viewSize); + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize)); +} + +void LayerBackedDrawingArea::suspendPainting() +{ + ASSERT(m_shouldPaint); + + m_shouldPaint = false; +} + +void LayerBackedDrawingArea::resumePainting() +{ + ASSERT(!m_shouldPaint); + + m_shouldPaint = true; + + // Display if needed. + display(); +} + +void LayerBackedDrawingArea::didUpdate() +{ + // Display if needed. + display(); +} + +void LayerBackedDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + DrawingAreaInfo::Identifier targetIdentifier; + if (!arguments->decode(CoreIPC::Out(targetIdentifier))) + return; + + // We can switch drawing areas on the fly, so if this message was targetted at an obsolete drawing area, ignore it. + if (targetIdentifier != info().identifier) + return; + + switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) { + case DrawingAreaLegacyMessage::SetSize: { + IntSize size; + if (!arguments->decode(CoreIPC::Out(size))) + return; + + setSize(size); + break; + } + + case DrawingAreaLegacyMessage::SuspendPainting: + suspendPainting(); + break; + + case DrawingAreaLegacyMessage::ResumePainting: + resumePainting(); + break; + + case DrawingAreaLegacyMessage::DidUpdate: + didUpdate(); + break; + + default: + ASSERT_NOT_REACHED(); + break; + } +} + +// GraphicsLayerClient methods +void LayerBackedDrawingArea::paintContents(const GraphicsLayer*, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& inClip) +{ + m_webPage->drawRect(graphicsContext, inClip); +} + +bool LayerBackedDrawingArea::showDebugBorders() const +{ + // FIXME: get from settings; + return false; +} + +bool LayerBackedDrawingArea::showRepaintCounter() const +{ + // FIXME: get from settings; + return false; +} + +#if !PLATFORM(MAC) && !PLATFORM(WIN) +void LayerBackedDrawingArea::attachCompositingContext(GraphicsLayer*) +{ +} + +void LayerBackedDrawingArea::detachCompositingContext() +{ +} + +#if !PLATFORM(MAC) +void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer*) +{ +} +#endif + +void LayerBackedDrawingArea::scheduleCompositingLayerSync() +{ +} + +void LayerBackedDrawingArea::syncCompositingLayers() +{ +} + +void LayerBackedDrawingArea::platformInit() +{ +} + +void LayerBackedDrawingArea::platformClear() +{ +} +#endif + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.h new file mode 100644 index 0000000..1b49de2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerBackedDrawingArea.h @@ -0,0 +1,125 @@ +/* + * 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. + */ + +#ifndef LayerBackedDrawingArea_h +#define LayerBackedDrawingArea_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "DrawingArea.h" +#include "RunLoop.h" +#include <WebCore/IntPoint.h> +#include <WebCore/GraphicsLayerClient.h> + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#ifdef __OBJC__ +@class CALayer; +#else +class CALayer; +#endif +typedef struct __WKCARemoteLayerClientRef *WKCARemoteLayerClientRef; +#endif + +namespace WebCore { + class GraphicsContext; + class GraphicsLayer; +} + +namespace WebKit { + +class LayerBackedDrawingArea : public DrawingArea, private WebCore::GraphicsLayerClient { +public: + LayerBackedDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage*); + virtual ~LayerBackedDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void display(); + + virtual void pageBackgroundTransparencyChanged(); + + virtual void attachCompositingContext(); + virtual void detachCompositingContext(); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + virtual void scheduleCompositingLayerSync(); + virtual void syncCompositingLayers(); + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + + // GraphicsLayerClient + virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double /*time*/) { } + virtual void notifySyncRequired(const WebCore::GraphicsLayer*) { } +public: + virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& inClip); +private: + virtual bool showDebugBorders() const; + virtual bool showRepaintCounter() const; + +#if PLATFORM(MAC) + virtual void onPageClose(); +#endif + + void scheduleDisplay(); + + // CoreIPC message handlers. + void setSize(const WebCore::IntSize& viewSize); + void suspendPainting(); + void resumePainting(); + void didUpdate(); + + void platformInit(); + void platformClear(); + +#if PLATFORM(MAC) + void setUpUpdateLayoutRunLoopObserver(); + void scheduleUpdateLayoutRunLoopObserver(); + void removeUpdateLayoutRunLoopObserver(); + + static void updateLayoutRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*); + void updateLayoutRunLoopObserverFired(); +#endif + + RunLoop::Timer<LayerBackedDrawingArea> m_syncTimer; + + OwnPtr<WebCore::GraphicsLayer> m_backingLayer; +#if PLATFORM(MAC) +#if HAVE(HOSTED_CORE_ANIMATION) + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerRef; +#endif + RetainPtr<CFRunLoopObserverRef> m_updateLayoutRunLoopObserver; +#endif + + bool m_attached; + bool m_shouldPaint; +}; + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif // LayerBackedDrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp new file mode 100644 index 0000000..091f460 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp @@ -0,0 +1,111 @@ +/* + * 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 "PageOverlay.h" + +#include "WebPage.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<PageOverlay> PageOverlay::create(Client* client) +{ + return adoptRef(new PageOverlay(client)); +} + +PageOverlay::PageOverlay(Client* client) + : m_client(client) + , m_webPage(0) +{ +} + +PageOverlay::~PageOverlay() +{ +} + +IntRect PageOverlay::bounds() const +{ + FrameView* frameView = webPage()->corePage()->mainFrame()->view(); + + int width = frameView->width(); + if (frameView->verticalScrollbar()) + width -= frameView->verticalScrollbar()->width(); + int height = frameView->height(); + if (frameView->horizontalScrollbar()) + height -= frameView->horizontalScrollbar()->height(); + + return IntRect(0, 0, width, height); +} + +void PageOverlay::setPage(WebPage* webPage) +{ + m_client->willMoveToWebPage(this, webPage); + m_webPage = webPage; + m_client->didMoveToWebPage(this, webPage); +} + +void PageOverlay::setNeedsDisplay(const WebCore::IntRect& dirtyRect) +{ + if (m_webPage) + m_webPage->drawingArea()->setNeedsDisplay(dirtyRect); +} + +void PageOverlay::setNeedsDisplay() +{ + setNeedsDisplay(bounds()); +} + +void PageOverlay::drawRect(GraphicsContext& graphicsContext, const IntRect& dirtyRect) +{ + // If the dirty rect is outside the bounds, ignore it. + IntRect paintRect = intersection(dirtyRect, bounds()); + if (paintRect.isEmpty()) + return; + + graphicsContext.save(); + graphicsContext.beginTransparencyLayer(1); + graphicsContext.setCompositeOperation(CompositeCopy); + + m_client->drawRect(this, graphicsContext, paintRect); + + graphicsContext.endTransparencyLayer(); + graphicsContext.restore(); +} + +bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent) +{ + // Ignore events outside the bounds. + if (!bounds().contains(mouseEvent.position())) + return false; + + return m_client->mouseEvent(this, mouseEvent); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h new file mode 100644 index 0000000..6f1f70f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h @@ -0,0 +1,86 @@ +/* + * 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. + */ + +#ifndef PageOverlay_h +#define PageOverlay_h + +#include "APIObject.h" +#include <wtf/PassRefPtr.h> + +namespace WebCore { + class GraphicsContext; + class IntRect; +} + +namespace WebKit { + +class WebMouseEvent; +class WebPage; + +class PageOverlay : public APIObject { +public: + class Client { + protected: + virtual ~Client() { } + + public: + virtual void pageOverlayDestroyed(PageOverlay*) = 0; + virtual void willMoveToWebPage(PageOverlay*, WebPage*) = 0; + virtual void didMoveToWebPage(PageOverlay*, WebPage*) = 0; + virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) = 0; + virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) = 0; + }; + + static const Type APIType = TypeBundlePageOverlay; + + static PassRefPtr<PageOverlay> create(Client*); + virtual ~PageOverlay(); + + void setPage(WebPage*); + void setNeedsDisplay(const WebCore::IntRect& dirtyRect); + void setNeedsDisplay(); + + void drawRect(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect); + bool mouseEvent(const WebMouseEvent&); + +protected: + explicit PageOverlay(Client*); + + WebPage* webPage() const { return m_webPage; } + +private: + // APIObject + virtual Type type() const { return APIType; } + + WebCore::IntRect bounds() const; + + Client* m_client; + + WebPage* m_webPage; +}; + +} // namespace WebKit + +#endif // PageOverlay_h diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp new file mode 100644 index 0000000..74aa4b2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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. + */ + +#if ENABLE(TILED_BACKING_STORE) + +#include "TiledDrawingArea.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "MessageID.h" +#include "UpdateChunk.h" +#include "WebCore/Frame.h" +#include "WebCore/FrameView.h" +#include "WebCoreArgumentCoders.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebProcess.h" + +using namespace WebCore; + +namespace WebKit { + +TiledDrawingArea::TiledDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage) + : DrawingArea(DrawingAreaInfo::Tiled, identifier, webPage) + , m_isWaitingForUpdate(false) + , m_shouldPaint(true) + , m_displayTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::display) + , m_tileUpdateTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::tileUpdateTimerFired) +{ +} + +TiledDrawingArea::~TiledDrawingArea() +{ +} + +void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void TiledDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + // FIXME: Collect a set of rects/region instead of just the union of all rects. + m_dirtyRect.unite(rect); + scheduleDisplay(); +} + +void TiledDrawingArea::display() +{ + if (!m_shouldPaint) + return; + + if (m_dirtyRect.isEmpty()) + return; + + m_webPage->layoutIfNeeded(); + + IntRect dirtyRect = m_dirtyRect; + m_dirtyRect = IntRect(); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::Invalidate, m_webPage->pageID(), CoreIPC::In(dirtyRect)); + + m_displayTimer.stop(); +} + +void TiledDrawingArea::scheduleDisplay() +{ + if (!m_shouldPaint) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void TiledDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT(m_shouldPaint); + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + m_webPage->setSize(viewSize); + + scheduleDisplay(); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize)); +} + +void TiledDrawingArea::suspendPainting() +{ + ASSERT(m_shouldPaint); + + m_shouldPaint = false; + m_displayTimer.stop(); +} + +void TiledDrawingArea::resumePainting() +{ + ASSERT(!m_shouldPaint); + + m_shouldPaint = true; + + // Display if needed. + display(); +} + +void TiledDrawingArea::didUpdate() +{ + // Display if needed. + display(); +} + +void TiledDrawingArea::updateTile(int tileID, const IntRect& dirtyRect, float scale) +{ + m_webPage->layoutIfNeeded(); + + UpdateChunk updateChunk(dirtyRect); + paintIntoUpdateChunk(&updateChunk, scale); + + unsigned pendingUpdateCount = m_pendingUpdates.size(); + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::TileUpdated, m_webPage->pageID(), CoreIPC::In(tileID, updateChunk, scale, pendingUpdateCount)); +} + +void TiledDrawingArea::tileUpdateTimerFired() +{ + ASSERT(!m_pendingUpdates.isEmpty()); + + UpdateMap::iterator it = m_pendingUpdates.begin(); + TileUpdate update = it->second; + m_pendingUpdates.remove(it); + + updateTile(update.tileID, update.dirtyRect, update.scale); + + if (m_pendingUpdates.isEmpty()) + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In()); + else + m_tileUpdateTimer.startOneShot(0.001); +} + +void TiledDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) { + case DrawingAreaLegacyMessage::SetSize: { + IntSize size; + if (!arguments->decode(CoreIPC::Out(size))) + return; + + setSize(size); + break; + } + case DrawingAreaLegacyMessage::SuspendPainting: + suspendPainting(); + break; + case DrawingAreaLegacyMessage::ResumePainting: + resumePainting(); + break; + case DrawingAreaLegacyMessage::CancelTileUpdate: { + int tileID; + if (!arguments->decode(CoreIPC::Out(tileID))) + return; + UpdateMap::iterator it = m_pendingUpdates.find(tileID); + if (it != m_pendingUpdates.end()) { + m_pendingUpdates.remove(it); + if (m_pendingUpdates.isEmpty()) { + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In()); + m_tileUpdateTimer.stop(); + } + } + break; + } + case DrawingAreaLegacyMessage::RequestTileUpdate: { + TileUpdate update; + if (!arguments->decode(CoreIPC::Out(update.tileID, update.dirtyRect, update.scale))) + return; + UpdateMap::iterator it = m_pendingUpdates.find(update.tileID); + if (it != m_pendingUpdates.end()) + it->second.dirtyRect.unite(update.dirtyRect); + else { + m_pendingUpdates.add(update.tileID, update); + if (!m_tileUpdateTimer.isActive()) + m_tileUpdateTimer.startOneShot(0); + } + break; + } + case DrawingAreaLegacyMessage::TakeSnapshot: { + IntSize targetSize; + IntRect contentsRect; + + if (!arguments->decode(CoreIPC::Out(targetSize, contentsRect))) + return; + + m_webPage->layoutIfNeeded(); + + contentsRect.intersect(IntRect(IntPoint::zero(), m_webPage->mainFrame()->coreFrame()->view()->contentsSize())); + + float targetScale = float(targetSize.width()) / contentsRect.width(); + + UpdateChunk updateChunk(IntRect(IntPoint(contentsRect.x() * targetScale, contentsRect.y() * targetScale), targetSize)); + paintIntoUpdateChunk(&updateChunk, targetScale); + + WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::SnapshotTaken, m_webPage->pageID(), CoreIPC::In(updateChunk)); + break; + } + default: + ASSERT_NOT_REACHED(); + break; + } +} + +} // namespace WebKit + +#endif // TILED_BACKING_STORE diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h new file mode 100644 index 0000000..7b682ca --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 TiledDrawingArea_h +#define TiledDrawingArea_h + +#if ENABLE(TILED_BACKING_STORE) + +#include "DrawingArea.h" +#include "RunLoop.h" +#include <WebCore/IntPoint.h> +#include <WebCore/IntRect.h> +#include <wtf/Vector.h> + +namespace WebKit { + +class UpdateChunk; + +class TiledDrawingArea : public DrawingArea { +public: + TiledDrawingArea(DrawingAreaInfo::Identifier, WebPage*); + virtual ~TiledDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + virtual void display(); + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() { } + virtual void detachCompositingContext() { } + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { } + virtual void scheduleCompositingLayerSync() { } + virtual void syncCompositingLayers() { } +#endif + + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + void scheduleDisplay(); + + // CoreIPC message handlers. + void setSize(const WebCore::IntSize& viewSize); + void suspendPainting(); + void resumePainting(); + void didUpdate(); + void updateTile(int tileID, const WebCore::IntRect& dirtyRect, float scale); + + // Platform overrides + void paintIntoUpdateChunk(UpdateChunk*, float scale); + + void tileUpdateTimerFired(); + + WebCore::IntRect m_dirtyRect; + bool m_isWaitingForUpdate; + bool m_shouldPaint; + RunLoop::Timer<TiledDrawingArea> m_displayTimer; + + struct TileUpdate { + int tileID; + WebCore::IntRect dirtyRect; + float scale; + }; + typedef HashMap<int, TileUpdate> UpdateMap; + UpdateMap m_pendingUpdates; + RunLoop::Timer<TiledDrawingArea> m_tileUpdateTimer; +}; + +} // namespace WebKit + +#endif // TILED_BACKING_STORE + +#endif // TiledDrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp new file mode 100644 index 0000000..21f4fba --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2010, 2011 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 "WebBackForwardListProxy.h" + +#include "DataReference.h" +#include "EncoderAdapter.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/HistoryItem.h> +#include <wtf/HashMap.h> + +using namespace WebCore; + +namespace WebKit { + +static const unsigned DefaultCapacity = 100; +static const unsigned NoCurrentItemIndex = UINT_MAX; + +// FIXME <rdar://problem/8819268>: This leaks all HistoryItems that go into these maps. +// We need to clear up the life time of these objects. + +typedef HashMap<uint64_t, RefPtr<HistoryItem> > IDToHistoryItemMap; +typedef HashMap<RefPtr<HistoryItem>, uint64_t> HistoryItemToIDMap; + +static IDToHistoryItemMap& idToHistoryItemMap() +{ + static IDToHistoryItemMap map; + return map; +} + +static HistoryItemToIDMap& historyItemToIDMap() +{ + static HistoryItemToIDMap map; + return map; +} + +static uint64_t uniqueHistoryItemID = 1; + +static uint64_t generateHistoryItemID() +{ + // These IDs exist in the WebProcess for items created by the WebProcess. + // The IDs generated here need to never collide with the IDs created in WebBackForwardList in the UIProcess. + // We accomplish this by starting from 3, and only ever using odd ids. + uniqueHistoryItemID += 2; + return uniqueHistoryItemID; +} + +void WebBackForwardListProxy::setHighestItemIDFromUIProcess(uint64_t itemID) +{ + if (itemID <= uniqueHistoryItemID) + return; + + if (itemID % 2) + uniqueHistoryItemID = itemID; + else + uniqueHistoryItemID = itemID + 1; +} + +static void updateBackForwardItem(uint64_t itemID, HistoryItem* item) +{ + EncoderAdapter encoder; + item->encodeBackForwardTree(encoder); + + WebProcess::shared().connection()->send(Messages::WebProcessProxy::AddBackForwardItem(itemID, + item->originalURLString(), item->urlString(), item->title(), encoder.data()), 0); +} + +void WebBackForwardListProxy::addItemFromUIProcess(uint64_t itemID, PassRefPtr<WebCore::HistoryItem> prpItem) +{ + RefPtr<HistoryItem> item = prpItem; + + // This item/itemID pair should not already exist in our maps. + ASSERT(!historyItemToIDMap().contains(item.get())); + ASSERT(!idToHistoryItemMap().contains(itemID)); + + historyItemToIDMap().set(item, itemID); + idToHistoryItemMap().set(itemID, item); +} + +static void WK2NotifyHistoryItemChanged(HistoryItem* item) +{ + uint64_t itemID = historyItemToIDMap().get(item); + if (!itemID) + return; + + updateBackForwardItem(itemID, item); +} + +HistoryItem* WebBackForwardListProxy::itemForID(uint64_t itemID) +{ + return idToHistoryItemMap().get(itemID).get(); +} + +void WebBackForwardListProxy::removeItem(uint64_t itemID) +{ + IDToHistoryItemMap::iterator it = idToHistoryItemMap().find(itemID); + if (it == idToHistoryItemMap().end()) + return; + historyItemToIDMap().remove(it->second); + idToHistoryItemMap().remove(it); +} + +WebBackForwardListProxy::WebBackForwardListProxy(WebPage* page) + : m_page(page) +{ + WebCore::notifyHistoryItemChanged = WK2NotifyHistoryItemChanged; +} + +void WebBackForwardListProxy::addItem(PassRefPtr<HistoryItem> prpItem) +{ + RefPtr<HistoryItem> item = prpItem; + + ASSERT(!historyItemToIDMap().contains(item)); + + if (!m_page) + return; + + uint64_t itemID = generateHistoryItemID(); + + ASSERT(!idToHistoryItemMap().contains(itemID)); + + historyItemToIDMap().set(item, itemID); + idToHistoryItemMap().set(itemID, item); + + updateBackForwardItem(itemID, item.get()); + m_page->send(Messages::WebPageProxy::BackForwardAddItem(itemID)); +} + +void WebBackForwardListProxy::goToItem(HistoryItem* item) +{ + if (!m_page) + return; + + m_page->send(Messages::WebPageProxy::BackForwardGoToItem(historyItemToIDMap().get(item))); +} + +HistoryItem* WebBackForwardListProxy::itemAtIndex(int itemIndex) +{ + if (!m_page) + return 0; + + uint64_t itemID = 0; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::BackForwardItemAtIndex(itemIndex), Messages::WebPageProxy::BackForwardItemAtIndex::Reply(itemID), m_page->pageID())) + return 0; + + if (!itemID) + return 0; + + return idToHistoryItemMap().get(itemID).get(); +} + +int WebBackForwardListProxy::backListCount() +{ + if (!m_page) + return 0; + + int backListCount = 0; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::BackForwardBackListCount(), Messages::WebPageProxy::BackForwardBackListCount::Reply(backListCount), m_page->pageID())) + return 0; + + return backListCount; +} + +int WebBackForwardListProxy::forwardListCount() +{ + if (!m_page) + return 0; + + int forwardListCount = 0; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::BackForwardForwardListCount(), Messages::WebPageProxy::BackForwardForwardListCount::Reply(forwardListCount), m_page->pageID())) + return 0; + + return forwardListCount; +} + +void WebBackForwardListProxy::close() +{ + m_page = 0; +} + +bool WebBackForwardListProxy::isActive() +{ + // FIXME: Should check the the list is enabled and has non-zero capacity. + return true; +} + +void WebBackForwardListProxy::clear() +{ + m_page->send(Messages::WebPageProxy::BackForwardClear()); +} + +#if ENABLE(WML) +void WebBackForwardListProxy::clearWMLPageHistory() +{ +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h new file mode 100644 index 0000000..be28739 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010, 2011 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 WebBackForwardListProxy_h +#define WebBackForwardListProxy_h + +#include <WebCore/BackForwardList.h> +#include <wtf/PassRefPtr.h> + +namespace WebKit { + +class WebPage; + +class WebBackForwardListProxy : public WebCore::BackForwardList { +public: + static PassRefPtr<WebBackForwardListProxy> create(WebPage* page) { return adoptRef(new WebBackForwardListProxy(page)); } + + static WebCore::HistoryItem* itemForID(uint64_t); + static void removeItem(uint64_t itemID); + + static void addItemFromUIProcess(uint64_t itemID, PassRefPtr<WebCore::HistoryItem>); + static void setHighestItemIDFromUIProcess(uint64_t itemID); + + void clear(); + +private: + WebBackForwardListProxy(WebPage*); + + virtual void addItem(PassRefPtr<WebCore::HistoryItem>); + + virtual void goToItem(WebCore::HistoryItem*); + + virtual WebCore::HistoryItem* itemAtIndex(int); + virtual int backListCount(); + virtual int forwardListCount(); + + virtual bool isActive(); + + virtual void close(); + +#if ENABLE(WML) + void clearWMLPageHistory(); +#endif + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebBackForwardListProxy_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp new file mode 100644 index 0000000..b496128 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010 Apple 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 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 "WebContextMenu.h" + +#include "ContextMenuState.h" +#include "InjectedBundleHitTestResult.h" +#include "InjectedBundleUserMessageCoders.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/ContextMenu.h> +#include <WebCore/ContextMenuController.h> +#include <WebCore/FrameView.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +WebContextMenu::WebContextMenu(WebPage* page) + : m_page(page) +{ +} + +WebContextMenu::~WebContextMenu() +{ +} + +void WebContextMenu::show() +{ + ContextMenuController* controller = m_page->corePage()->contextMenuController(); + if (!controller) + return; + ContextMenu* menu = controller->contextMenu(); + if (!menu) + return; + Node* node = controller->hitTestResult().innerNonSharedNode(); + if (!node) + return; + Frame* frame = node->document()->frame(); + if (!frame) + return; + FrameView* view = frame->view(); + if (!view) + return; + + // Give the bundle client a chance to process the menu. +#if USE(CROSS_PLATFORM_CONTEXT_MENUS) + const Vector<ContextMenuItem>& coreItems = menu->items(); +#else + Vector<ContextMenuItem> coreItems = contextMenuItemVector(menu->platformDescription()); +#endif + Vector<WebContextMenuItemData> proposedMenu = kitItems(coreItems, menu); + Vector<WebContextMenuItemData> newMenu; + RefPtr<APIObject> userData; + RefPtr<InjectedBundleHitTestResult> hitTestResult = InjectedBundleHitTestResult::create(controller->hitTestResult()); + if (m_page->injectedBundleContextMenuClient().getCustomMenuFromDefaultItems(m_page, hitTestResult.get(), proposedMenu, newMenu, userData)) + proposedMenu = newMenu; + + ContextMenuState contextMenuState; + contextMenuState.absoluteImageURLString = controller->hitTestResult().absoluteImageURL().string(); + contextMenuState.absoluteLinkURLString = controller->hitTestResult().absoluteLinkURL().string(); + + // Notify the UIProcess. + m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(controller->hitTestResult().point()), contextMenuState, proposedMenu, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebContextMenu::itemSelected(const WebContextMenuItemData& item) +{ + ContextMenuItem coreItem(ActionType, static_cast<ContextMenuAction>(item.action()), item.title()); + m_page->corePage()->contextMenuController()->contextMenuItemSelected(&coreItem); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h new file mode 100644 index 0000000..3d9291a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Apple 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 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 WebContextMenu_h +#define WebContextMenu_h + +#include "WebContextMenuItemData.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebKit { + +class WebPage; + +class WebContextMenu : public RefCounted<WebContextMenu> { +public: + static PassRefPtr<WebContextMenu> create(WebPage* page) + { + return adoptRef(new WebContextMenu(page)); + } + + ~WebContextMenu(); + + void show(); + void itemSelected(const WebContextMenuItemData&); + +private: + WebContextMenu(WebPage*); + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // WebPopupMenu_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebEditCommand.cpp b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.cpp new file mode 100644 index 0000000..198cb6d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.cpp @@ -0,0 +1,41 @@ +/* + * 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 "WebEditCommand.h" + +namespace WebKit { + +static uint64_t generateCommandID() +{ + static uint64_t uniqueCommandID = 1; + return uniqueCommandID++; +} + +PassRefPtr<WebEditCommand> WebEditCommand::create(PassRefPtr<WebCore::EditCommand> command) +{ + return adoptRef(new WebEditCommand(command, generateCommandID())); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebEditCommand.h b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.h new file mode 100644 index 0000000..b6844a2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebEditCommand.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#ifndef WebEditCommand_h +#define WebEditCommand_h + +#include <WebCore/EditCommand.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebKit { + +class WebEditCommand : public RefCounted<WebEditCommand> { +public: + static PassRefPtr<WebEditCommand> create(PassRefPtr<WebCore::EditCommand>); + + WebCore::EditCommand* command() const { return m_command.get(); } + uint64_t commandID() const { return m_commandID; } + +private: + WebEditCommand(PassRefPtr<WebCore::EditCommand> command, uint64_t commandID) + : m_command(command) + , m_commandID(commandID) + { + } + + RefPtr<WebCore::EditCommand> m_command; + uint64_t m_commandID; +}; + +} // namespace WebKit + +#endif // WebEditCommand_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp new file mode 100644 index 0000000..c5f117e --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp @@ -0,0 +1,517 @@ +/* + * 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 "WebFrame.h" + +#include "DownloadManager.h" +#include "InjectedBundleNodeHandle.h" +#include "InjectedBundleRangeHandle.h" +#include "InjectedBundleScriptWorld.h" +#include "WebChromeClient.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/JSValueRef.h> +#include <WebCore/AnimationController.h> +#include <WebCore/CSSComputedStyleDeclaration.h> +#include <WebCore/Chrome.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLFrameOwnerElement.h> +#include <WebCore/JSCSSStyleDeclaration.h> +#include <WebCore/JSElement.h> +#include <WebCore/JSRange.h> +#include <WebCore/Page.h> +#include <WebCore/RenderTreeAsText.h> +#include <WebCore/TextIterator.h> +#include <WebCore/TextResourceDecoder.h> +#include <wtf/text/StringBuilder.h> + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +#ifndef NDEBUG +static WTF::RefCountedLeakCounter webFrameCounter("WebFrame"); +#endif + +static uint64_t generateFrameID() +{ + static uint64_t uniqueFrameID = 1; + return uniqueFrameID++; +} + +static uint64_t generateListenerID() +{ + static uint64_t uniqueListenerID = 1; + return uniqueListenerID++; +} + +PassRefPtr<WebFrame> WebFrame::createMainFrame(WebPage* page) +{ + RefPtr<WebFrame> frame = create(); + + page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID())); + + frame->init(page, String(), 0); + + return frame.release(); +} + +PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement) +{ + RefPtr<WebFrame> frame = create(); + + WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(ownerElement->document()->frame()->loader()->client())->webFrame(); + page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID(), parentFrame->frameID())); + + frame->init(page, frameName, ownerElement); + + return frame.release(); +} + +PassRefPtr<WebFrame> WebFrame::create() +{ + RefPtr<WebFrame> frame = adoptRef(new WebFrame); + + // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed(). + frame->ref(); + + return frame.release(); +} + +WebFrame::WebFrame() + : m_coreFrame(0) + , m_policyListenerID(0) + , m_policyFunction(0) + , m_policyDownloadID(0) + , m_frameLoaderClient(this) + , m_loadListener(0) + , m_frameID(generateFrameID()) +{ + WebProcess::shared().addWebFrame(m_frameID, this); + +#ifndef NDEBUG + webFrameCounter.increment(); +#endif +} + +WebFrame::~WebFrame() +{ + ASSERT(!m_coreFrame); + +#ifndef NDEBUG + webFrameCounter.decrement(); +#endif +} + +void WebFrame::init(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement) +{ + RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient); + m_coreFrame = frame.get(); + + frame->tree()->setName(frameName); + + if (ownerElement) { + ASSERT(ownerElement->document()->frame()); + ownerElement->document()->frame()->tree()->appendChild(frame); + } + + frame->init(); +} + +WebPage* WebFrame::page() const +{ + if (!m_coreFrame) + return 0; + + if (WebCore::Page* page = m_coreFrame->page()) + return static_cast<WebChromeClient*>(page->chrome()->client())->page(); + + return 0; +} + +void WebFrame::invalidate() +{ + WebProcess::shared().removeWebFrame(m_frameID); + m_coreFrame = 0; +} + +uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction policyFunction) +{ + // FIXME: <rdar://5634381> We need to support multiple active policy listeners. + + invalidatePolicyListener(); + + m_policyListenerID = generateListenerID(); + m_policyFunction = policyFunction; + return m_policyListenerID; +} + +void WebFrame::invalidatePolicyListener() +{ + if (!m_policyListenerID) + return; + + m_policyDownloadID = 0; + m_policyListenerID = 0; + m_policyFunction = 0; +} + +void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t downloadID) +{ + if (!m_coreFrame) + return; + + if (!m_policyListenerID) + return; + + if (listenerID != m_policyListenerID) + return; + + ASSERT(m_policyFunction); + + FramePolicyFunction function = m_policyFunction; + + invalidatePolicyListener(); + + m_policyDownloadID = downloadID; + + (m_coreFrame->loader()->policyChecker()->*function)(action); +} + +void WebFrame::startDownload(const WebCore::ResourceRequest& request) +{ + ASSERT(m_policyDownloadID); + + DownloadManager::shared().startDownload(m_policyDownloadID, page(), request); + + m_policyDownloadID = 0; +} + +void WebFrame::convertHandleToDownload(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response) +{ + ASSERT(m_policyDownloadID); + + DownloadManager::shared().convertHandleToDownload(m_policyDownloadID, page(), handle, request, initialRequest, response); + m_policyDownloadID = 0; +} + +String WebFrame::source() const +{ + if (!m_coreFrame) + return String(); + Document* document = m_coreFrame->document(); + if (!document) + return String(); + TextResourceDecoder* decoder = document->decoder(); + if (!decoder) + return String(); + DocumentLoader* documentLoader = m_coreFrame->loader()->activeDocumentLoader(); + if (!documentLoader) + return String(); + RefPtr<SharedBuffer> mainResourceData = documentLoader->mainResourceData(); + if (!mainResourceData) + return String(); + return decoder->encoding().decode(mainResourceData->data(), mainResourceData->size()); +} + +String WebFrame::contentsAsString() const +{ + if (!m_coreFrame) + return String(); + + if (isFrameSet()) { + StringBuilder builder; + for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { + if (!builder.isEmpty()) + builder.append(' '); + builder.append(static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame()->contentsAsString()); + } + // FIXME: It may make sense to use toStringPreserveCapacity() here. + return builder.toString(); + } + + Document* document = m_coreFrame->document(); + if (!document) + return String(); + + RefPtr<Element> documentElement = document->documentElement(); + if (!documentElement) + return String(); + + RefPtr<Range> range = document->createRange(); + + ExceptionCode ec = 0; + range->selectNode(documentElement.get(), ec); + if (ec) + return String(); + + return plainText(range.get()); +} + +String WebFrame::selectionAsString() const +{ + if (!m_coreFrame) + return String(); + + return m_coreFrame->displayStringModifiedByEncoding(m_coreFrame->editor()->selectedText()); +} + +IntSize WebFrame::size() const +{ + if (!m_coreFrame) + return IntSize(); + + FrameView* frameView = m_coreFrame->view(); + if (!frameView) + return IntSize(); + + return frameView->contentsSize(); +} + +bool WebFrame::isFrameSet() const +{ + if (!m_coreFrame) + return false; + + Document* document = m_coreFrame->document(); + if (!document) + return false; + return document->isFrameSet(); +} + +bool WebFrame::isMainFrame() const +{ + if (WebPage* p = page()) + return p->mainFrame() == this; + + return false; +} + +String WebFrame::name() const +{ + if (!m_coreFrame) + return String(); + + return m_coreFrame->tree()->uniqueName(); +} + +String WebFrame::url() const +{ + if (!m_coreFrame) + return String(); + + return m_coreFrame->loader()->url().string(); +} + +String WebFrame::innerText() const +{ + if (!m_coreFrame) + return String(); + + if (!m_coreFrame->document()->documentElement()) + return String(); + + return m_coreFrame->document()->documentElement()->innerText(); +} + +PassRefPtr<ImmutableArray> WebFrame::childFrames() +{ + if (!m_coreFrame) + return ImmutableArray::create(); + + size_t size = m_coreFrame->tree()->childCount(); + if (!size) + return ImmutableArray::create(); + + Vector<RefPtr<APIObject> > vector; + vector.reserveInitialCapacity(size); + + for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(child->loader()->client())->webFrame(); + vector.uncheckedAppend(webFrame); + } + + return ImmutableArray::adopt(vector); +} + +unsigned WebFrame::numberOfActiveAnimations() const +{ + if (!m_coreFrame) + return 0; + + AnimationController* controller = m_coreFrame->animation(); + if (!controller) + return 0; + + return controller->numberOfActiveAnimations(); +} + +bool WebFrame::pauseAnimationOnElementWithId(const String& animationName, const String& elementID, double time) +{ + if (!m_coreFrame) + return false; + + AnimationController* controller = m_coreFrame->animation(); + if (!controller) + return false; + + if (!m_coreFrame->document()) + return false; + + Node* coreNode = m_coreFrame->document()->getElementById(elementID); + if (!coreNode || !coreNode->renderer()) + return false; + + return controller->pauseAnimationAtTime(coreNode->renderer(), animationName, time); +} + +void WebFrame::suspendAnimations() +{ + if (!m_coreFrame) + return; + + AnimationController* controller = m_coreFrame->animation(); + if (!controller) + return; + + controller->suspendAnimations(); +} + +void WebFrame::resumeAnimations() +{ + if (!m_coreFrame) + return; + + AnimationController* controller = m_coreFrame->animation(); + if (!controller) + return; + + controller->resumeAnimations(); +} + +String WebFrame::layerTreeAsText() const +{ + if (!m_coreFrame) + return ""; + + return m_coreFrame->layerTreeAsText(); +} + +unsigned WebFrame::pendingUnloadCount() const +{ + if (!m_coreFrame) + return 0; + + return m_coreFrame->domWindow()->pendingUnloadEventListeners(); +} + +bool WebFrame::allowsFollowingLink(const WebCore::KURL& url) const +{ + if (!m_coreFrame) + return true; + + return m_coreFrame->document()->securityOrigin()->canDisplay(url); +} + +JSGlobalContextRef WebFrame::jsContext() +{ + return toGlobalRef(m_coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec()); +} + +JSGlobalContextRef WebFrame::jsContextForWorld(InjectedBundleScriptWorld* world) +{ + return toGlobalRef(m_coreFrame->script()->globalObject(world->coreWorld())->globalExec()); +} + +JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world) +{ + JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld()); + ExecState* exec = globalObject->globalExec(); + + JSLock lock(SilenceAssertionsOnly); + return toRef(exec, toJS(exec, globalObject, nodeHandle->coreNode())); +} + +JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, InjectedBundleScriptWorld* world) +{ + JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld()); + ExecState* exec = globalObject->globalExec(); + + JSLock lock(SilenceAssertionsOnly); + return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange())); +} + +JSValueRef WebFrame::computedStyleIncludingVisitedInfo(JSObjectRef element) +{ + if (!m_coreFrame) + return 0; + + JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(mainThreadNormalWorld()); + ExecState* exec = globalObject->globalExec(); + + if (!toJS(element)->inherits(&JSElement::s_info)) + return JSValueMakeUndefined(toRef(exec)); + + RefPtr<CSSComputedStyleDeclaration> style = computedStyle(static_cast<JSElement*>(toJS(element))->impl(), true); + + JSLock lock(SilenceAssertionsOnly); + return toRef(exec, toJS(exec, globalObject, style.get())); +} + +String WebFrame::counterValue(JSObjectRef element) +{ + if (!toJS(element)->inherits(&JSElement::s_info)) + return String(); + + return counterValueForElement(static_cast<JSElement*>(toJS(element))->impl()); +} + +String WebFrame::markerText(JSObjectRef element) +{ + if (!toJS(element)->inherits(&JSElement::s_info)) + return String(); + + return markerTextForListItem(static_cast<JSElement*>(toJS(element))->impl()); +} + +String WebFrame::provisionalURL() const +{ + if (!m_coreFrame) + return String(); + + return m_coreFrame->loader()->provisionalDocumentLoader()->url().string(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.h b/Source/WebKit2/WebProcess/WebPage/WebFrame.h new file mode 100644 index 0000000..3ded6f6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.h @@ -0,0 +1,144 @@ +/* + * 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. + */ + +#ifndef WebFrame_h +#define WebFrame_h + +#include "APIObject.h" +#include "ImmutableArray.h" +#include "WebFrameLoaderClient.h" +#include <JavaScriptCore/JSBase.h> +#include <WebCore/FrameLoaderClient.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/PolicyChecker.h> +#include <wtf/Forward.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + class Frame; + class HTMLFrameOwnerElement; + class KURL; +} + +namespace WebKit { + +class InjectedBundleNodeHandle; +class InjectedBundleRangeHandle; +class InjectedBundleScriptWorld; +class WebPage; + +class WebFrame : public APIObject { +public: + static const Type APIType = TypeBundleFrame; + + static PassRefPtr<WebFrame> createMainFrame(WebPage*); + static PassRefPtr<WebFrame> createSubframe(WebPage*, const String& frameName, WebCore::HTMLFrameOwnerElement*); + ~WebFrame(); + + // Called when the FrameLoaderClient (and therefore the WebCore::Frame) is being torn down. + void invalidate(); + + WebPage* page() const; + WebCore::Frame* coreFrame() const { return m_coreFrame; } + + uint64_t frameID() const { return m_frameID; } + + uint64_t setUpPolicyListener(WebCore::FramePolicyFunction); + void invalidatePolicyListener(); + void didReceivePolicyDecision(uint64_t listenerID, WebCore::PolicyAction, uint64_t downloadID); + + void startDownload(const WebCore::ResourceRequest&); + void convertHandleToDownload(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest& initialRequest, const WebCore::ResourceResponse&); + + String source() const; + String contentsAsString() const; + String selectionAsString() const; + + WebCore::IntSize size() const; + + // WKBundleFrame API and SPI functions + bool isMainFrame() const; + String name() const; + String url() const; + String innerText() const; + bool isFrameSet() const; + PassRefPtr<ImmutableArray> childFrames(); + JSValueRef computedStyleIncludingVisitedInfo(JSObjectRef element); + JSGlobalContextRef jsContext(); + JSGlobalContextRef jsContextForWorld(InjectedBundleScriptWorld*); + + JSValueRef jsWrapperForWorld(InjectedBundleNodeHandle*, InjectedBundleScriptWorld*); + JSValueRef jsWrapperForWorld(InjectedBundleRangeHandle*, InjectedBundleScriptWorld*); + + static String counterValue(JSObjectRef element); + static String markerText(JSObjectRef element); + + unsigned numberOfActiveAnimations() const; + bool pauseAnimationOnElementWithId(const String& animationName, const String& elementID, double time); + void suspendAnimations(); + void resumeAnimations(); + String layerTreeAsText() const; + + unsigned pendingUnloadCount() const; + + bool allowsFollowingLink(const WebCore::KURL&) const; + + String provisionalURL() const; + + // Simple listener class used by plug-ins to know when frames finish or fail loading. + class LoadListener { + public: + virtual ~LoadListener() { } + + virtual void didFinishLoad(WebFrame*) = 0; + virtual void didFailLoad(WebFrame*, bool wasCancelled) = 0; + }; + void setLoadListener(LoadListener* loadListener) { m_loadListener = loadListener; } + LoadListener* loadListener() const { return m_loadListener; } + +private: + static PassRefPtr<WebFrame> create(); + WebFrame(); + + void init(WebPage*, const String& frameName, WebCore::HTMLFrameOwnerElement*); + + virtual Type type() const { return APIType; } + + WebCore::Frame* m_coreFrame; + + uint64_t m_policyListenerID; + WebCore::FramePolicyFunction m_policyFunction; + uint64_t m_policyDownloadID; + + WebFrameLoaderClient m_frameLoaderClient; + LoadListener* m_loadListener; + + uint64_t m_frameID; +}; + +} // namespace WebKit + +#endif // WebFrame_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp new file mode 100644 index 0000000..559b8b6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp @@ -0,0 +1,141 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include "WebInspectorProxyMessages.h" +#include "WebPage.h" +#include "WebPageCreationParameters.h" +#include "WebProcess.h" +#include <WebCore/InspectorController.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +WebInspector::WebInspector(WebPage* page) + : m_page(page) + , m_inspectorPage(0) +{ +} + +// Called from WebInspectorClient +WebPage* WebInspector::createInspectorPage() +{ + if (!m_page) + return 0; + + uint64_t inspectorPageID = 0; + WebPageCreationParameters parameters; + + if (!WebProcess::shared().connection()->sendSync(Messages::WebInspectorProxy::CreateInspectorPage(), + Messages::WebInspectorProxy::CreateInspectorPage::Reply(inspectorPageID, parameters), + m_page->pageID(), CoreIPC::Connection::NoTimeout)) { + return 0; + } + + if (!inspectorPageID) + return 0; + + WebProcess::shared().createWebPage(inspectorPageID, parameters); + m_inspectorPage = WebProcess::shared().webPage(inspectorPageID); + ASSERT(m_inspectorPage); + + return m_inspectorPage; +} + +// Called from WebInspectorFrontendClient +void WebInspector::didLoadInspectorPage() +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::DidLoadInspectorPage(), m_page->pageID()); +} + +void WebInspector::didClose() +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::DidClose(), m_page->pageID()); +} + +// Called by WebInspector messages +void WebInspector::show() +{ + m_page->corePage()->inspectorController()->show(); +} + +void WebInspector::close() +{ + m_page->corePage()->inspectorController()->close(); +} + +void WebInspector::showConsole() +{ + m_page->corePage()->inspectorController()->showPanel(InspectorController::ConsolePanel); +} + +void WebInspector::startJavaScriptDebugging() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->showAndEnableDebugger(); +#endif +} + +void WebInspector::stopJavaScriptDebugging() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->disableDebugger(); +#endif +} + +void WebInspector::startJavaScriptProfiling() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->startUserInitiatedProfiling(); +#endif +} + +void WebInspector::stopJavaScriptProfiling() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->stopUserInitiatedProfiling(); + m_page->corePage()->inspectorController()->showPanel(InspectorController::ProfilesPanel); +#endif +} + +void WebInspector::startPageProfiling() +{ + m_page->corePage()->inspectorController()->startTimelineProfiler(); +} + +void WebInspector::stopPageProfiling() +{ + m_page->corePage()->inspectorController()->stopTimelineProfiler(); + // FIXME: show the Timeline panel. +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.h b/Source/WebKit2/WebProcess/WebPage/WebInspector.h new file mode 100644 index 0000000..21a7529 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.h @@ -0,0 +1,89 @@ +/* + * 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. + */ + +#ifndef WebInspector_h +#define WebInspector_h + +#if ENABLE(INSPECTOR) + +#include "Connection.h" +#include <wtf/Forward.h> +#include <wtf/Noncopyable.h> + +namespace WebKit { + +class WebPage; +struct WebPageCreationParameters; + +class WebInspector { + WTF_MAKE_NONCOPYABLE(WebInspector); + +public: + explicit WebInspector(WebPage*); + + WebPage* page() const { return m_page; } + WebPage* inspectorPage() const { return m_inspectorPage; } + + // Implemented in generated WebInspectorMessageReceiver.cpp + void didReceiveWebInspectorMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + friend class WebInspectorClient; + friend class WebInspectorFrontendClient; + + // Called from WebInspectorClient + WebPage* createInspectorPage(); + + // Called from WebInspectorFrontendClient + void didLoadInspectorPage(); + void didClose(); + + // Implemented in platform WebInspector file + String localizedStringsURL() const; + + // Called by WebInspector messages + void show(); + void close(); + + void showConsole(); + + void startJavaScriptDebugging(); + void stopJavaScriptDebugging(); + + void startJavaScriptProfiling(); + void stopJavaScriptProfiling(); + + void startPageProfiling(); + void stopPageProfiling(); + + WebPage* m_page; + WebPage* m_inspectorPage; +}; + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) + +#endif // WebInspector_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in b/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in new file mode 100644 index 0000000..dc184b6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.messages.in @@ -0,0 +1,37 @@ +# 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. + +#if ENABLE(INSPECTOR) + +messages -> WebInspector { + Show() + Close() + ShowConsole() + StartJavaScriptDebugging() + StopJavaScriptDebugging() + StartJavaScriptProfiling() + StopJavaScriptProfiling() + StartPageProfiling() + StopPageProfiling() +} + +#endif diff --git a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp new file mode 100644 index 0000000..d42e313 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp @@ -0,0 +1,50 @@ +/* + * 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 "WebOpenPanelResultListener.h" + +namespace WebKit { + +PassRefPtr<WebOpenPanelResultListener> WebOpenPanelResultListener::create(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser) +{ + return adoptRef(new WebOpenPanelResultListener(page, fileChooser)); +} + +WebOpenPanelResultListener::WebOpenPanelResultListener(WebPage* page, PassRefPtr<WebCore::FileChooser> fileChooser) + : m_page(page) + , m_fileChooser(fileChooser) +{ +} + +WebOpenPanelResultListener::~WebOpenPanelResultListener() +{ +} + +void WebOpenPanelResultListener::didChooseFiles(const Vector<String>& files) +{ + m_fileChooser->chooseFiles(files); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h new file mode 100644 index 0000000..073d66a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.h @@ -0,0 +1,54 @@ +/* + * 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. + */ + +#ifndef WebOpenPanelResultListener_h +#define WebOpenPanelResultListener_h + +#include <wtf/RefCounted.h> +#include <WebCore/FileChooser.h> + +namespace WebKit { + +class WebPage; + +class WebOpenPanelResultListener : public RefCounted<WebOpenPanelResultListener> { +public: + static PassRefPtr<WebOpenPanelResultListener> create(WebPage*, PassRefPtr<WebCore::FileChooser>); + ~WebOpenPanelResultListener(); + + void disconnectFromPage() { m_page = 0; } + void didChooseFiles(const Vector<String>&); + +private: + WebOpenPanelResultListener(WebPage*, PassRefPtr<WebCore::FileChooser>); + + WebPage* m_page; + RefPtr<WebCore::FileChooser> m_fileChooser; +}; + +} // namespace WebKit + + +#endif // WebOpenPanelResultListener_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp new file mode 100644 index 0000000..2259387 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp @@ -0,0 +1,1757 @@ +/* + * Copyright (C) 2010, 2011 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 "WebPage.h" + +#include "Arguments.h" +#include "DataReference.h" +#include "DecoderAdapter.h" +#include "DrawingArea.h" +#include "InjectedBundle.h" +#include "InjectedBundleBackForwardList.h" +#include "MessageID.h" +#include "NetscapePlugin.h" +#include "PageOverlay.h" +#include "PluginProxy.h" +#include "PluginView.h" +#include "PrintInfo.h" +#include "SessionState.h" +#include "ShareableBitmap.h" +#include "WebBackForwardList.h" +#include "WebBackForwardListItem.h" +#include "WebBackForwardListProxy.h" +#include "WebChromeClient.h" +#include "WebContextMenu.h" +#include "WebContextMenuClient.h" +#include "WebContextMessages.h" +#include "WebCoreArgumentCoders.h" +#include "WebDragClient.h" +#include "WebEditorClient.h" +#include "WebEvent.h" +#include "WebEventConversion.h" +#include "WebFrame.h" +#include "WebGeolocationClient.h" +#include "WebImage.h" +#include "WebInspector.h" +#include "WebInspectorClient.h" +#include "WebOpenPanelResultListener.h" +#include "WebPageCreationParameters.h" +#include "WebPageGroupProxy.h" +#include "WebPageProxyMessages.h" +#include "WebPopupMenu.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include "WebProcessProxyMessageKinds.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/AbstractDatabase.h> +#include <WebCore/ArchiveResource.h> +#include <WebCore/Chrome.h> +#include <WebCore/ContextMenuController.h> +#include <WebCore/DocumentFragment.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/DocumentMarkerController.h> +#include <WebCore/DragController.h> +#include <WebCore/DragData.h> +#include <WebCore/EventHandler.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/FrameView.h> +#include <WebCore/HistoryItem.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/PrintContext.h> +#include <WebCore/RenderTreeAsText.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/RenderView.h> +#include <WebCore/ReplaceSelectionCommand.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/Settings.h> +#include <WebCore/SharedBuffer.h> +#include <WebCore/SubstituteData.h> +#include <WebCore/TextIterator.h> +#include <WebCore/markup.h> +#include <runtime/JSLock.h> +#include <runtime/JSValue.h> + +#if PLATFORM(MAC) || PLATFORM(WIN) +#include <WebCore/LegacyWebArchive.h> +#endif + +#if ENABLE(PLUGIN_PROCESS) +// FIXME: This is currently Mac-specific! +#include "MachPort.h" +#endif + +#if PLATFORM(QT) +#include "HitTestResult.h" +#endif + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +#ifndef NDEBUG +static WTF::RefCountedLeakCounter webPageCounter("WebPage"); +#endif + +PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters) +{ + RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters)); + + if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) + WebProcess::shared().injectedBundle()->didCreatePage(page.get()); + + return page.release(); +} + +WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) + : m_viewSize(parameters.viewSize) + , m_drawsBackground(true) + , m_drawsTransparentBackground(false) + , m_isInRedo(false) + , m_isClosed(false) + , m_tabToLinks(false) +#if PLATFORM(MAC) + , m_windowIsVisible(false) + , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled) +#elif PLATFORM(WIN) + , m_nativeWindow(parameters.nativeWindow) +#endif + , m_findController(this) + , m_geolocationPermissionRequestManager(this) + , m_pageID(pageID) +{ + ASSERT(m_pageID); + + Page::PageClients pageClients; + pageClients.chromeClient = new WebChromeClient(this); + pageClients.contextMenuClient = new WebContextMenuClient(this); + pageClients.editorClient = new WebEditorClient(this); + pageClients.dragClient = new WebDragClient(this); + pageClients.backForwardClient = WebBackForwardListProxy::create(this); +#if ENABLE(CLIENT_BASED_GEOLOCATION) + pageClients.geolocationClient = new WebGeolocationClient(this); +#endif +#if ENABLE(INSPECTOR) + pageClients.inspectorClient = new WebInspectorClient(this); +#endif + m_page = adoptPtr(new Page(pageClients)); + + // Qt does not yet call setIsInWindow. Until it does, just leave + // this line out so plug-ins and video will work. Eventually all platforms + // should call setIsInWindow and this comment and #if should be removed, + // leaving behind the setCanStartMedia call. +#if !PLATFORM(QT) + m_page->setCanStartMedia(false); +#endif + + updatePreferences(parameters.store); + + m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData); + m_page->setGroupName(m_pageGroup->identifier()); + + platformInitialize(); + Settings::setMinDOMTimerInterval(0.004); + + m_drawingArea = DrawingArea::create(parameters.drawingAreaInfo.type, parameters.drawingAreaInfo.identifier, this); + m_mainFrame = WebFrame::createMainFrame(this); + + setDrawsBackground(parameters.drawsBackground); + setDrawsTransparentBackground(parameters.drawsTransparentBackground); + + setActive(parameters.isActive); + setFocused(parameters.isFocused); + setIsInWindow(parameters.isInWindow); + + m_userAgent = parameters.userAgent; + + WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID); + + if (!parameters.sessionState.isEmpty()) + restoreSession(parameters.sessionState); + +#ifndef NDEBUG + webPageCounter.increment(); +#endif +} + +WebPage::~WebPage() +{ + if (m_backForwardList) + m_backForwardList->detach(); + + ASSERT(!m_page); + + m_sandboxExtensionTracker.invalidate(); + +#if PLATFORM(MAC) + ASSERT(m_pluginViews.isEmpty()); +#endif + +#ifndef NDEBUG + webPageCounter.decrement(); +#endif +} + +void WebPage::dummy(bool&) +{ +} + +CoreIPC::Connection* WebPage::connection() const +{ + return WebProcess::shared().connection(); +} + +void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client) +{ + m_contextMenuClient.initialize(client); +} + +void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client) +{ + m_editorClient.initialize(client); +} + +void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client) +{ + m_formClient.initialize(client); +} + +void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client) +{ + m_loaderClient.initialize(client); +} + +void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) +{ + m_uiClient.initialize(client); +} + +PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters) +{ + String pluginPath; + + if (!WebProcess::shared().connection()->sendSync( + Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()), + Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) { + return 0; + } + + if (pluginPath.isNull()) + return 0; + +#if ENABLE(PLUGIN_PROCESS) + return PluginProxy::create(pluginPath); +#else + return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath)); +#endif +} + +String WebPage::renderTreeExternalRepresentation() const +{ + return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); +} + +void WebPage::executeEditingCommand(const String& commandName, const String& argument) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + frame->editor()->command(commandName).execute(argument); +} + +bool WebPage::isEditingCommandEnabled(const String& commandName) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return false; + + Editor::Command command = frame->editor()->command(commandName); + return command.isSupported() && command.isEnabled(); +} + +void WebPage::clearMainFrameName() +{ + mainFrame()->coreFrame()->tree()->clearName(); +} + +#if USE(ACCELERATED_COMPOSITING) +void WebPage::changeAcceleratedCompositingMode(WebCore::GraphicsLayer* layer) +{ + if (m_isClosed) + return; + + bool compositing = layer; + + // Tell the UI process that accelerated compositing changed. It may respond by changing + // drawing area types. + DrawingAreaInfo newDrawingAreaInfo; + + if (!sendSync(Messages::WebPageProxy::DidChangeAcceleratedCompositing(compositing), Messages::WebPageProxy::DidChangeAcceleratedCompositing::Reply(newDrawingAreaInfo))) + return; + + if (newDrawingAreaInfo.type != drawingArea()->info().type) { + m_drawingArea = 0; + if (newDrawingAreaInfo.type != DrawingAreaInfo::None) { + m_drawingArea = DrawingArea::create(newDrawingAreaInfo.type, newDrawingAreaInfo.identifier, this); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); + } + } +} + +void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer) +{ + changeAcceleratedCompositingMode(layer); + m_drawingArea->setRootCompositingLayer(layer); +} + +void WebPage::exitAcceleratedCompositingMode() +{ + changeAcceleratedCompositingMode(0); +} +#endif + +void WebPage::close() +{ + if (m_isClosed) + return; + + m_isClosed = true; + + if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) + WebProcess::shared().injectedBundle()->willDestroyPage(this); + +#if ENABLE(INSPECTOR) + m_inspector = 0; +#endif + + if (m_activePopupMenu) { + m_activePopupMenu->disconnectFromPage(); + m_activePopupMenu = 0; + } + + if (m_activeOpenPanelResultListener) { + m_activeOpenPanelResultListener->disconnectFromPage(); + m_activeOpenPanelResultListener = 0; + } + + m_sandboxExtensionTracker.invalidate(); + + m_printContext = nullptr; + + m_mainFrame->coreFrame()->loader()->detachFromParent(); + m_page.clear(); + + m_drawingArea->onPageClose(); + m_drawingArea.clear(); + + WebProcess::shared().removeWebPage(m_pageID); +} + +void WebPage::tryClose() +{ + if (!m_mainFrame->coreFrame()->loader()->shouldClose()) + return; + + sendClose(); +} + +void WebPage::sendClose() +{ + send(Messages::WebPageProxy::ClosePage()); +} + +void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle); +} + +void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); + m_mainFrame->coreFrame()->loader()->load(request, false); +} + +void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL) +{ + ResourceRequest request(baseURL); + SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL); + m_mainFrame->coreFrame()->loader()->load(request, substituteData, false); +} + +void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString) +{ + RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar)); + KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); + loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL()); +} + +void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString) +{ + RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar)); + KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString); + KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString) ; + loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL); +} + +void WebPage::loadPlainTextString(const String& string) +{ + RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar)); + loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL()); +} + +void WebPage::stopLoading() +{ + m_mainFrame->coreFrame()->loader()->stopForUserCancel(); +} + +void WebPage::setDefersLoading(bool defersLoading) +{ + m_page->setDefersLoading(defersLoading); +} + +void WebPage::reload(bool reloadFromOrigin) +{ + m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin); +} + +void WebPage::goForward(uint64_t backForwardItemID) +{ + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + m_page->goToItem(item, FrameLoadTypeForward); +} + +void WebPage::goBack(uint64_t backForwardItemID) +{ + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + m_page->goToItem(item, FrameLoadTypeBack); +} + +void WebPage::goToBackForwardItem(uint64_t backForwardItemID) +{ + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + m_page->goToItem(item, FrameLoadTypeIndexedBackForward); +} + +void WebPage::layoutIfNeeded() +{ + if (m_mainFrame->coreFrame()->view()) + m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive(); +} + +void WebPage::setSize(const WebCore::IntSize& viewSize) +{ +#if ENABLE(TILED_BACKING_STORE) + // If we are resizing to content ignore external attempts. + if (!m_resizesToContentsLayoutSize.isEmpty()) + return; +#endif + + if (m_viewSize == viewSize) + return; + + Frame* frame = m_page->mainFrame(); + + frame->view()->resize(viewSize); + frame->view()->setNeedsLayout(); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize)); + + m_viewSize = viewSize; +} + +#if ENABLE(TILED_BACKING_STORE) +void WebPage::setActualVisibleContentRect(const IntRect& rect) +{ + Frame* frame = m_page->mainFrame(); + + frame->view()->setActualVisibleContentRect(rect); +} + +void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize) +{ + if (m_resizesToContentsLayoutSize == targetLayoutSize) + return; + + m_resizesToContentsLayoutSize = targetLayoutSize; + + Frame* frame = m_page->mainFrame(); + if (m_resizesToContentsLayoutSize.isEmpty()) { + frame->view()->setDelegatesScrolling(false); + frame->view()->setUseFixedLayout(false); + frame->view()->setPaintsEntireContents(false); + } else { + frame->view()->setDelegatesScrolling(true); + frame->view()->setUseFixedLayout(true); + frame->view()->setPaintsEntireContents(true); + frame->view()->setFixedLayoutSize(m_resizesToContentsLayoutSize); + } + frame->view()->forceLayout(); +} + +void WebPage::resizeToContentsIfNeeded() +{ + if (m_resizesToContentsLayoutSize.isEmpty()) + return; + + Frame* frame = m_page->mainFrame(); + + IntSize contentSize = frame->view()->contentsSize(); + if (contentSize == m_viewSize) + return; + + m_viewSize = contentSize; + frame->view()->resize(m_viewSize); + frame->view()->setNeedsLayout(); +} +#endif + +void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect) +{ + graphicsContext.save(); + graphicsContext.clip(rect); + m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); + graphicsContext.restore(); + + if (m_pageOverlay) { + graphicsContext.save(); + graphicsContext.clip(rect); + m_pageOverlay->drawRect(graphicsContext, rect); + graphicsContext.restore(); + } +} + +double WebPage::textZoomFactor() const +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return 1; + return frame->textZoomFactor(); +} + +void WebPage::setTextZoomFactor(double zoomFactor) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + frame->setTextZoomFactor(static_cast<float>(zoomFactor)); +} + +double WebPage::pageZoomFactor() const +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return 1; + return frame->pageZoomFactor(); +} + +void WebPage::setPageZoomFactor(double zoomFactor) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + frame->setPageZoomFactor(static_cast<float>(zoomFactor)); +} + +void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor)); +} + +void WebPage::scaleWebView(double scale, const IntPoint& origin) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + frame->scalePage(scale, origin); +} + +double WebPage::viewScaleFactor() const +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return 1; + return frame->pageScaleFactor(); +} + +void WebPage::setUseFixedLayout(bool fixed) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + + FrameView* view = frame->view(); + if (!view) + return; + + view->setUseFixedLayout(fixed); + if (!fixed) + view->setFixedLayoutSize(IntSize()); +} + +void WebPage::setFixedLayoutSize(const IntSize& size) +{ + Frame* frame = m_mainFrame->coreFrame(); + if (!frame) + return; + + FrameView* view = frame->view(); + if (!view) + return; + + view->setFixedLayoutSize(size); + view->forceLayout(); +} + +void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay) +{ + if (m_pageOverlay) + pageOverlay->setPage(0); + + m_pageOverlay = pageOverlay; + m_pageOverlay->setPage(this); + m_pageOverlay->setNeedsDisplay(); +} + +void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay) +{ + if (pageOverlay != m_pageOverlay) + return; + + m_pageOverlay->setPage(0); + m_pageOverlay = nullptr; + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); +} + +PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options) +{ + FrameView* frameView = m_mainFrame->coreFrame()->view(); + if (!frameView) + return 0; + + frameView->updateLayoutAndStyleIfNeededRecursive(); + + PaintBehavior oldBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); + + RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options); + OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); + + graphicsContext->save(); + graphicsContext->translate(-rect.x(), -rect.y()); + frameView->paint(graphicsContext.get(), rect); + graphicsContext->restore(); + + frameView->setPaintBehavior(oldBehavior); + + return snapshot.release(); +} + +PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options) +{ + FrameView* frameView = m_mainFrame->coreFrame()->view(); + if (!frameView) + return 0; + + frameView->updateLayoutAndStyleIfNeededRecursive(); + + PaintBehavior oldBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); + + RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options); + OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); + + graphicsContext->save(); + graphicsContext->translate(-rect.x(), -rect.y()); + frameView->paintContents(graphicsContext.get(), rect); + graphicsContext->restore(); + + frameView->setPaintBehavior(oldBehavior); + + return snapshot.release(); +} + +void WebPage::pageDidScroll() +{ + // Hide the find indicator. + m_findController.hideFindIndicator(); + + m_uiClient.pageDidScroll(this); + + send(Messages::WebPageProxy::PageDidScroll()); +} + +#if ENABLE(TILED_BACKING_STORE) +void WebPage::pageDidRequestScroll(const IntSize& delta) +{ + send(Messages::WebPageProxy::PageDidRequestScroll(delta)); +} +#endif + +WebContextMenu* WebPage::contextMenu() +{ + if (!m_contextMenu) + m_contextMenu = WebContextMenu::create(this); + return m_contextMenu.get(); +} + +void WebPage::getLocationAndLengthFromRange(Range* range, uint64_t& location, uint64_t& length) +{ + location = notFound; + length = 0; + + if (!range || !range->startContainer()) + return; + + Element* selectionRoot = range->ownerDocument()->frame()->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : range->ownerDocument()->documentElement(); + + // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view + // that is not inside the current editable region. These checks ensure we don't produce + // potentially invalid data when responding to such requests. + if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope)) + return; + if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope)) + return; + + RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset()); + ASSERT(testRange->startContainer() == scope); + location = TextIterator::rangeLength(testRange.get()); + + ExceptionCode ec; + testRange->setEnd(range->endContainer(), range->endOffset(), ec); + ASSERT(testRange->startContainer() == scope); + length = TextIterator::rangeLength(testRange.get()) - location; +} + +// Events + +static const WebEvent* g_currentEvent = 0; + +// FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to +// WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct +// platform events passed to the event handler code. +const WebEvent* WebPage::currentEvent() +{ + return g_currentEvent; +} + +class CurrentEvent { +public: + explicit CurrentEvent(const WebEvent& event) + : m_previousCurrentEvent(g_currentEvent) + { + g_currentEvent = &event; + } + + ~CurrentEvent() + { + g_currentEvent = m_previousCurrentEvent; + } + +private: + const WebEvent* m_previousCurrentEvent; +}; + +static bool isContextClick(const PlatformMouseEvent& event) +{ + if (event.button() == WebCore::RightButton) + return true; + +#if PLATFORM(MAC) + // FIXME: this really should be about OSX-style UI, not about the Mac port + if (event.button() == WebCore::LeftButton && event.ctrlKey()) + return true; +#endif + + return false; +} + +static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page) +{ + Frame* frame = page->mainFrame(); + if (!frame->view()) + return false; + + PlatformMouseEvent platformMouseEvent = platform(mouseEvent); + + switch (platformMouseEvent.eventType()) { + case WebCore::MouseEventPressed: + { + if (isContextClick(platformMouseEvent)) + page->contextMenuController()->clearContextMenu(); + + bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent); + + if (isContextClick(platformMouseEvent)) { + handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent); + if (handled) + page->chrome()->showContextMenu(); + } + + return handled; + } + case WebCore::MouseEventReleased: + return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent); + case WebCore::MouseEventMoved: + return frame->eventHandler()->mouseMoved(platformMouseEvent); + + default: + ASSERT_NOT_REACHED(); + return false; + } +} + +void WebPage::mouseEvent(const WebMouseEvent& mouseEvent) +{ + bool handled = false; + + if (m_pageOverlay) { + // Let the page overlay handle the event. + handled = m_pageOverlay->mouseEvent(mouseEvent); + } + + if (!handled) { + CurrentEvent currentEvent(mouseEvent); + + handled = handleMouseEvent(mouseEvent, m_page.get()); + } + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled)); +} + +static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page) +{ + Frame* frame = page->mainFrame(); + if (!frame->view()) + return false; + + PlatformWheelEvent platformWheelEvent = platform(wheelEvent); + return frame->eventHandler()->handleWheelEvent(platformWheelEvent); +} + +void WebPage::wheelEvent(const WebWheelEvent& wheelEvent) +{ + CurrentEvent currentEvent(wheelEvent); + + bool handled = handleWheelEvent(wheelEvent, m_page.get()); + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled)); +} + +static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page) +{ + if (!page->mainFrame()->view()) + return false; + + if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey()) + return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent)); + return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent)); +} + +void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent) +{ + CurrentEvent currentEvent(keyboardEvent); + + bool handled = handleKeyEvent(keyboardEvent, m_page.get()); + if (!handled) + handled = performDefaultBehaviorForKeyEvent(keyboardEvent); + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled)); +} + +void WebPage::validateMenuItem(const String& commandName) +{ + bool isEnabled = false; + int32_t state = 0; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (frame) { + Editor::Command command = frame->editor()->command(commandName); + state = command.state(); + isEnabled = command.isSupported() && command.isEnabled(); + } + + send(Messages::WebPageProxy::DidValidateMenuItem(commandName, isEnabled, state)); +} + +void WebPage::executeEditCommand(const String& commandName) +{ + executeEditingCommand(commandName, String()); +} + +uint64_t WebPage::restoreSession(const SessionState& sessionState) +{ + const BackForwardListItemVector& list = sessionState.list(); + size_t size = list.size(); + uint64_t currentItemID = 0; + for (size_t i = 0; i < size; ++i) { + WebBackForwardListItem* webItem = list[i].get(); + DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size()); + + RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder); + if (!item) { + LOG_ERROR("Failed to decode a HistoryItem from session state data."); + return 0; + } + + if (i == sessionState.currentIndex()) + currentItemID = webItem->itemID(); + + WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release()); + } + ASSERT(currentItemID); + return currentItemID; +} + +void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState) +{ + if (uint64_t currentItemID = restoreSession(sessionState)) + goToBackForwardItem(currentItemID); +} + +#if ENABLE(TOUCH_EVENTS) +static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page) +{ + Frame* frame = page->mainFrame(); + if (!frame->view()) + return false; + + return frame->eventHandler()->handleTouchEvent(platform(touchEvent)); +} + +void WebPage::touchEvent(const WebTouchEvent& touchEvent) +{ + CurrentEvent currentEvent(touchEvent); + + bool handled = handleTouchEvent(touchEvent, m_page.get()); + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled)); +} +#endif + +void WebPage::setActive(bool isActive) +{ + m_page->focusController()->setActive(isActive); + +#if PLATFORM(MAC) + // Tell all our plug-in views that the window focus changed. + for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) + (*it)->setWindowIsFocused(isActive); +#endif +} + +void WebPage::setDrawsBackground(bool drawsBackground) +{ + if (m_drawsBackground == drawsBackground) + return; + + m_drawsBackground = drawsBackground; + + for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { + if (FrameView* view = coreFrame->view()) + view->setTransparent(!drawsBackground); + } + + m_drawingArea->pageBackgroundTransparencyChanged(); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); +} + +void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground) +{ + if (m_drawsTransparentBackground == drawsTransparentBackground) + return; + + m_drawsTransparentBackground = drawsTransparentBackground; + + Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white; + for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { + if (FrameView* view = coreFrame->view()) + view->setBaseBackgroundColor(backgroundColor); + } + + m_drawingArea->pageBackgroundTransparencyChanged(); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize)); +} + +void WebPage::setFocused(bool isFocused) +{ + m_page->focusController()->setFocused(isFocused); +} + +void WebPage::setInitialFocus(bool forward) +{ + if (!m_page || !m_page->focusController()) + return; + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + frame->document()->setFocusedNode(0); + m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0); +} + +void WebPage::setWindowResizerSize(const IntSize& windowResizerSize) +{ + if (m_windowResizerSize == windowResizerSize) + return; + + m_windowResizerSize = windowResizerSize; + + for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) { + FrameView* view = coreFrame->view(); + if (view) + view->windowResizerRectChanged(); + } +} + +void WebPage::setIsInWindow(bool isInWindow) +{ + if (!isInWindow) { + m_page->setCanStartMedia(false); + m_page->willMoveOffscreen(); + } else { + m_page->setCanStartMedia(true); + m_page->didMoveOnscreen(); + } +} + +void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); +} + +void WebPage::show() +{ + send(Messages::WebPageProxy::ShowPage()); +} + +void WebPage::setUserAgent(const String& userAgent) +{ + m_userAgent = userAgent; +} + +IntRect WebPage::windowResizerRect() const +{ + if (m_windowResizerSize.isEmpty()) + return IntRect(); + + IntSize frameViewSize; + if (Frame* coreFrame = m_mainFrame->coreFrame()) { + if (FrameView* view = coreFrame->view()) + frameViewSize = view->size(); + } + + return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), + m_windowResizerSize.width(), m_windowResizerSize.height()); +} + +void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID) +{ + // NOTE: We need to be careful when running scripts that the objects we depend on don't + // disappear during script execution. + + JSLock lock(SilenceAssertionsOnly); + JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue(); + String resultString; + if (resultValue) + resultString = ustringToString(resultValue.toString(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec())); + + send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); +} + +void WebPage::getContentsAsString(uint64_t callbackID) +{ + String resultString = m_mainFrame->contentsAsString(); + send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); +} + +void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID) +{ + String resultString = renderTreeExternalRepresentation(); + send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); +} + +void WebPage::getSelectionOrContentsAsString(uint64_t callbackID) +{ + String resultString = m_mainFrame->selectionAsString(); + if (resultString.isEmpty()) + resultString = m_mainFrame->contentsAsString(); + send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); +} + +void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID) +{ + String resultString; + if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) + resultString = frame->source(); + + send(Messages::WebPageProxy::StringCallback(resultString, callbackID)); +} + +void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID) +{ + CoreIPC::DataReference dataReference; + + RefPtr<SharedBuffer> buffer; + if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { + if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) { + if ((buffer = loader->mainResourceData())) + dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size()); + } + } + + send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); +} + +void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID) +{ + CoreIPC::DataReference dataReference; + +#if PLATFORM(MAC) || PLATFORM(WIN) + RetainPtr<CFDataRef> data; + if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { + if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame->coreFrame())) { + if ((data = archive->rawDataRepresentation())) + dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); + } + } +#endif + + send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); +} + +void WebPage::preferencesDidChange(const WebPreferencesStore& store) +{ + WebPreferencesStore::removeTestRunnerOverrides(); + updatePreferences(store); +} + +void WebPage::updatePreferences(const WebPreferencesStore& store) +{ + Settings* settings = m_page->settings(); + + m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey()); + + // FIXME: This should be generated from macro expansion for all preferences, + // but we currently don't match the naming of WebCore exactly so we are + // handrolling the boolean and integer preferences until that is fixed. + +#define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key())); + + FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS) + +#undef INITIALIZE_SETTINGS + + settings->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey())); + settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey())); + settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey())); + settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey())); + settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey())); + settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey())); + settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey())); + settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey())); + settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey())); + settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey())); + settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey())); + settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey())); + settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey())); + settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey())); + settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey())); + settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey())); + settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey())); + settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey())); + settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey())); + settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey())); + settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey())); + settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey())); + + settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey())); + settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey())); + settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey())); + settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey())); + +#if PLATFORM(WIN) + // Temporarily turn off accelerated compositing until we have a good solution for rendering it. + settings->setAcceleratedCompositingEnabled(false); +#else + settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey())); +#endif + settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey())); + settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey())); + +#if ENABLE(DATABASE) + AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey())); +#endif + + platformPreferencesDidChange(store); +} + +#if ENABLE(INSPECTOR) +WebInspector* WebPage::inspector() +{ + if (m_isClosed) + return 0; + if (!m_inspector) + m_inspector = adoptPtr(new WebInspector(this)); + return m_inspector.get(); +} +#endif + +#if !PLATFORM(MAC) +bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt) +{ + Node* node = evt->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + + const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); + if (!keyEvent) + return false; + + Editor::Command command = frame->editor()->command(interpretKeyEvent(evt)); + + if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) { + // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated, + // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated + // (e.g. Tab that inserts a Tab character, or Enter). + return !command.isTextInsertion() && command.execute(evt); + } + + if (command.execute(evt)) + return true; + + // Don't insert null or control characters as they can result in unexpected behaviour + if (evt->charCode() < ' ') + return false; + + return frame->editor()->insertText(evt->keyEvent()->text(), evt); +} +#endif + +void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags) +{ + if (!m_page) { + send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone)); + return; + } + + DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags)); + switch (action) { + case DragControllerActionEntered: + send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData))); + break; + + case DragControllerActionUpdated: + send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData))); + break; + + case DragControllerActionExited: + m_page->dragController()->dragExited(&dragData); + break; + + case DragControllerActionPerformDrag: + m_page->dragController()->performDrag(&dragData); + break; + + default: + ASSERT_NOT_REACHED(); + } +} + +WebEditCommand* WebPage::webEditCommand(uint64_t commandID) +{ + return m_editCommandMap.get(commandID).get(); +} + +void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command) +{ + m_editCommandMap.set(commandID, command); +} + +void WebPage::removeWebEditCommand(uint64_t commandID) +{ + m_editCommandMap.remove(commandID); +} + +void WebPage::unapplyEditCommand(uint64_t commandID) +{ + WebEditCommand* command = webEditCommand(commandID); + if (!command) + return; + + command->command()->unapply(); +} + +void WebPage::reapplyEditCommand(uint64_t commandID) +{ + WebEditCommand* command = webEditCommand(commandID); + if (!command) + return; + + m_isInRedo = true; + command->command()->reapply(); + m_isInRedo = false; +} + +void WebPage::didRemoveEditCommand(uint64_t commandID) +{ + removeWebEditCommand(commandID); +} + +void WebPage::setActivePopupMenu(WebPopupMenu* menu) +{ + m_activePopupMenu = menu; +} + +void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener) +{ + m_activeOpenPanelResultListener = openPanelResultListener; +} + +bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options) +{ + return m_page->findString(target, options); +} + +void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount) +{ + m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount); +} + +void WebPage::hideFindUI() +{ + m_findController.hideFindUI(); +} + +void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount) +{ + m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount); +} + +void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex) +{ + if (!m_activePopupMenu) + return; + + m_activePopupMenu->didChangeSelectedIndex(newIndex); + m_activePopupMenu = 0; +} + +void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files) +{ + if (!m_activeOpenPanelResultListener) + return; + + m_activeOpenPanelResultListener->didChooseFiles(files); + m_activeOpenPanelResultListener = 0; +} + +void WebPage::didCancelForOpenPanel() +{ + m_activeOpenPanelResultListener = 0; +} + +void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) +{ + m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed); +} + +void WebPage::advanceToNextMisspelling(bool startBeforeSelection) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + frame->editor()->advanceToNextMisspelling(startBeforeSelection); +} + +void WebPage::changeSpellingToWord(const String& word) +{ + replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word); +} + +void WebPage::unmarkAllMisspellings() +{ + for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { + if (Document* document = frame->document()) + document->markers()->removeMarkers(DocumentMarker::Spelling); + } +} + +void WebPage::unmarkAllBadGrammar() +{ + for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { + if (Document* document = frame->document()) + document->markers()->removeMarkers(DocumentMarker::Grammar); + } +} + +#if PLATFORM(MAC) +void WebPage::uppercaseWord() +{ + m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord(); +} + +void WebPage::lowercaseWord() +{ + m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord(); +} + +void WebPage::capitalizeWord() +{ + m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord(); +} +#endif + +void WebPage::setTextForActivePopupMenu(int32_t index) +{ + if (!m_activePopupMenu) + return; + + m_activePopupMenu->setTextForIndex(index); +} + +void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) +{ + ASSERT(m_contextMenu); + m_contextMenu->itemSelected(item); + m_contextMenu = 0; +} + +void WebPage::replaceSelectionWithText(Frame* frame, const String& text) +{ + if (frame->selection()->isNone()) + return; + + RefPtr<DocumentFragment> textFragment = createFragmentFromText(frame->selection()->toNormalizedRange().get(), text); + applyCommand(ReplaceSelectionCommand::create(frame->document(), textFragment.release(), true, false, true)); + frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded); +} + +bool WebPage::mainFrameHasCustomRepresentation() const +{ + return static_cast<WebFrameLoaderClient*>(mainFrame()->coreFrame()->loader()->client())->frameHasCustomRepresentation(); +} + +#if PLATFORM(MAC) + +void WebPage::addPluginView(PluginView* pluginView) +{ + ASSERT(!m_pluginViews.contains(pluginView)); + + m_pluginViews.add(pluginView); +} + +void WebPage::removePluginView(PluginView* pluginView) +{ + ASSERT(m_pluginViews.contains(pluginView)); + + m_pluginViews.remove(pluginView); +} + +void WebPage::setWindowIsVisible(bool windowIsVisible) +{ + m_windowIsVisible = windowIsVisible; + + // Tell all our plug-in views that the window visibility changed. + for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) + (*it)->setWindowIsVisible(windowIsVisible); +} + +void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates) +{ + m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates; + m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates; + m_accessibilityPosition = accessibilityViewCoordinates; + + // Tell all our plug-in views that the window and view frames have changed. + for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) + (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates); +} + +bool WebPage::windowIsFocused() const +{ + return m_page->focusController()->isActive(); +} + +#endif + +void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (messageID.is<CoreIPC::MessageClassDrawingAreaLegacy>()) { + if (m_drawingArea) + m_drawingArea->didReceiveMessage(connection, messageID, arguments); + return; + } + +#ifdef __APPLE__ + if (messageID.is<CoreIPC::MessageClassDrawingArea>()) { + if (m_drawingArea) + m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments); + return; + } +#endif + +#if ENABLE(INSPECTOR) + if (messageID.is<CoreIPC::MessageClassWebInspector>()) { + if (WebInspector* inspector = this->inspector()) + inspector->didReceiveWebInspectorMessage(connection, messageID, arguments); + return; + } +#endif + + didReceiveWebPageMessage(connection, messageID, arguments); +} + +CoreIPC::SyncReplyMode WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply) +{ + return didReceiveSyncWebPageMessage(connection, messageID, arguments, reply); +} + +InjectedBundleBackForwardList* WebPage::backForwardList() +{ + if (!m_backForwardList) + m_backForwardList = InjectedBundleBackForwardList::create(this); + return m_backForwardList.get(); +} + +#if PLATFORM(QT) +void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point) +{ + const int minimumZoomTargetWidth = 100; + + Frame* mainframe = m_mainFrame->coreFrame(); + HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true); + + Node* node = result.innerNode(); + while (node && node->getRect().width() < minimumZoomTargetWidth) + node = node->parentNode(); + + IntRect zoomableArea; + if (node) + zoomableArea = node->getRect(); + send(Messages::WebPageProxy::DidFindZoomableArea(zoomableArea)); +} +#endif + +WebPage::SandboxExtensionTracker::~SandboxExtensionTracker() +{ + invalidate(); +} + +void WebPage::SandboxExtensionTracker::invalidate() +{ + if (m_pendingProvisionalSandboxExtension) { + m_pendingProvisionalSandboxExtension->invalidate(); + m_pendingProvisionalSandboxExtension = 0; + } + + if (m_provisionalSandboxExtension) { + m_provisionalSandboxExtension->invalidate(); + m_provisionalSandboxExtension = 0; + } + + if (m_committedSandboxExtension) { + m_committedSandboxExtension->invalidate(); + m_committedSandboxExtension = 0; + } +} + +void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) +{ + ASSERT(frame->isMainFrame()); + + ASSERT(!m_pendingProvisionalSandboxExtension); + m_pendingProvisionalSandboxExtension = SandboxExtension::create(handle); +} + +void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame) +{ + if (!frame->isMainFrame()) + return; + + ASSERT(!m_provisionalSandboxExtension); + + m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release(); + if (!m_provisionalSandboxExtension) + return; + + m_provisionalSandboxExtension->consume(); +} + +void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame) +{ + if (!frame->isMainFrame()) + return; + + ASSERT(!m_pendingProvisionalSandboxExtension); + + // The provisional load has been committed. Invalidate the currently committed sandbox + // extension and make the provisional sandbox extension the committed sandbox extension. + if (m_committedSandboxExtension) + m_committedSandboxExtension->invalidate(); + + m_committedSandboxExtension = m_provisionalSandboxExtension.release(); +} + +void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame) +{ + if (!frame->isMainFrame()) + return; + + ASSERT(!m_pendingProvisionalSandboxExtension); + if (!m_provisionalSandboxExtension) + return; + + m_provisionalSandboxExtension->invalidate(); + m_provisionalSandboxExtension = 0; +} + +bool WebPage::hasLocalDataForURL(const KURL& url) +{ + if (url.isLocalFile()) + return true; + + FrameLoader* frameLoader = m_page->mainFrame()->loader(); + DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0; + if (documentLoader && documentLoader->subresource(url)) + return true; + + return platformHasLocalDataForURL(url); +} + +void WebPage::setCustomTextEncodingName(const String& encoding) +{ + m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding); +} + +void WebPage::didRemoveBackForwardItem(uint64_t itemID) +{ + WebBackForwardListProxy::removeItem(itemID); +} + +#if PLATFORM(MAC) + +bool WebPage::isSpeaking() +{ + bool result; + return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result; +} + +void WebPage::speak(const String& string) +{ + send(Messages::WebPageProxy::Speak(string)); +} + +void WebPage::stopSpeaking() +{ + send(Messages::WebPageProxy::StopSpeaking()); +} + +#endif + +void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + + Frame* coreFrame = frame->coreFrame(); + if (!coreFrame) + return; + + if (!m_printContext) + m_printContext = adoptPtr(new PrintContext(coreFrame)); + + m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight); +} + +void WebPage::endPrinting() +{ + m_printContext = nullptr; +} + +void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, Vector<IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting) +{ + beginPrinting(frameID, printInfo); + + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + + float fullPageHeight; + m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true); + + resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(printInfo.availablePaperWidth) * printInfo.pageSetupScaleFactor; + resultPageRects = m_printContext->pageRects(); + + // If we're asked to print, we should actually print at least a blank page. + if (resultPageRects.isEmpty()) + resultPageRects.append(IntRect(0, 0, 1, 1)); +} + +#if PLATFORM(MAC) +// FIXME: Find a better place for Mac specific code. +void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, Vector<uint8_t>& pdfData) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + + Frame* coreFrame = frame->coreFrame(); + if (!coreFrame) + return; + + ASSERT(coreFrame->document()->printing()); + + RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0)); + + // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. + RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); + + CGRect mediaBox = CGRectMake(0, 0, frame->size().width(), frame->size().height()); + RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); + CFDictionaryRef pageInfo = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CGPDFContextBeginPage(context.get(), pageInfo); + + GraphicsContext ctx(context.get()); + m_printContext->spoolRect(ctx, rect); + + CGPDFContextEndPage(context.get()); + CGPDFContextClose(context.get()); + + pdfData.resize(CFDataGetLength(pdfPageData.get())); + CFDataGetBytes(pdfPageData.get(), CFRangeMake(0, pdfData.size()), pdfData.data()); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h new file mode 100644 index 0000000..7649ab6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h @@ -0,0 +1,499 @@ +/* + * Copyright (C) 2010, 2011 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 WebPage_h +#define WebPage_h + +#include "APIObject.h" +#include "DrawingArea.h" +#include "FindController.h" +#include "GeolocationPermissionRequestManager.h" +#include "ImageOptions.h" +#include "InjectedBundlePageContextMenuClient.h" +#include "InjectedBundlePageEditorClient.h" +#include "InjectedBundlePageFormClient.h" +#include "InjectedBundlePageLoaderClient.h" +#include "InjectedBundlePageUIClient.h" +#include "MessageSender.h" +#include "Plugin.h" +#include "SandboxExtension.h" +#include "WebEditCommand.h" +#include <WebCore/Editor.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/IntRect.h> +#include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +#if ENABLE(TOUCH_EVENTS) +#include <WebCore/PlatformTouchEvent.h> +#endif + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#ifdef __OBJC__ +@class AccessibilityWebPageObject; +#else +class AccessibilityWebPageObject; +#endif +#endif + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebCore { + class GraphicsContext; + class KeyboardEvent; + class Page; + class PrintContext; + class ResourceRequest; + class SharedBuffer; +} + +namespace WebKit { + +class DrawingArea; +class InjectedBundleBackForwardList; +class PageOverlay; +class PluginView; +class SessionState; +class WebContextMenu; +class WebContextMenuItemData; +class WebEvent; +class WebFrame; +class WebImage; +class WebInspector; +class WebKeyboardEvent; +class WebMouseEvent; +class WebOpenPanelResultListener; +class WebPageGroupProxy; +class WebPopupMenu; +class WebWheelEvent; +struct PrintInfo; +struct WebPageCreationParameters; +struct WebPreferencesStore; + +#if ENABLE(TOUCH_EVENTS) +class WebTouchEvent; +#endif + +class WebPage : public APIObject, public CoreIPC::MessageSender<WebPage> { +public: + static const Type APIType = TypeBundlePage; + + static PassRefPtr<WebPage> create(uint64_t pageID, const WebPageCreationParameters&); + virtual ~WebPage(); + + // Used by MessageSender. + CoreIPC::Connection* connection() const; + uint64_t destinationID() const { return pageID(); } + + void close(); + + WebCore::Page* corePage() const { return m_page.get(); } + uint64_t pageID() const { return m_pageID; } + + void setSize(const WebCore::IntSize&); + const WebCore::IntSize& size() const { return m_viewSize; } + + InjectedBundleBackForwardList* backForwardList(); + DrawingArea* drawingArea() const { return m_drawingArea.get(); } + + WebPageGroupProxy* pageGroup() const { return m_pageGroup.get(); } + +#if ENABLE(INSPECTOR) + WebInspector* inspector(); +#endif + + // -- Called by the DrawingArea. + // FIXME: We could genericize these into a DrawingArea client interface. Would that be beneficial? + void drawRect(WebCore::GraphicsContext&, const WebCore::IntRect&); + void layoutIfNeeded(); + + // -- Called from WebCore clients. +#if !PLATFORM(MAC) + bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*); +#endif + void show(); + String userAgent() const { return m_userAgent; } + WebCore::IntRect windowResizerRect() const; + bool tabsToLinks() const { return m_tabToLinks; } + + WebEditCommand* webEditCommand(uint64_t); + void addWebEditCommand(uint64_t, WebEditCommand*); + void removeWebEditCommand(uint64_t); + bool isInRedo() const { return m_isInRedo; } + + void setActivePopupMenu(WebPopupMenu*); + + WebOpenPanelResultListener* activeOpenPanelResultListener() const { return m_activeOpenPanelResultListener.get(); } + void setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener>); + + // -- Called from WebProcess. + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + + // -- InjectedBundle methods + void initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient*); + void initializeInjectedBundleEditorClient(WKBundlePageEditorClient*); + void initializeInjectedBundleFormClient(WKBundlePageFormClient*); + void initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient*); + void initializeInjectedBundleUIClient(WKBundlePageUIClient*); + + InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; } + InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; } + InjectedBundlePageFormClient& injectedBundleFormClient() { return m_formClient; } + InjectedBundlePageLoaderClient& injectedBundleLoaderClient() { return m_loaderClient; } + InjectedBundlePageUIClient& injectedBundleUIClient() { return m_uiClient; } + + bool findStringFromInjectedBundle(const String&, FindOptions); + + WebFrame* mainFrame() const { return m_mainFrame.get(); } + PassRefPtr<Plugin> createPlugin(const Plugin::Parameters&); + + String renderTreeExternalRepresentation() const; + void executeEditingCommand(const String& commandName, const String& argument); + bool isEditingCommandEnabled(const String& commandName); + void clearMainFrameName(); + void sendClose(); + + double textZoomFactor() const; + void setTextZoomFactor(double); + double pageZoomFactor() const; + void setPageZoomFactor(double); + void setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor); + + void scaleWebView(double scale, const WebCore::IntPoint& origin); + double viewScaleFactor() const; + + void setUseFixedLayout(bool); + void setFixedLayoutSize(const WebCore::IntSize&); + + bool drawsBackground() const { return m_drawsBackground; } + bool drawsTransparentBackground() const { return m_drawsTransparentBackground; } + + void stopLoading(); + void setDefersLoading(bool deferLoading); + +#if USE(ACCELERATED_COMPOSITING) + void changeAcceleratedCompositingMode(WebCore::GraphicsLayer*); + void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*); + void exitAcceleratedCompositingMode(); +#endif + +#if PLATFORM(MAC) + void addPluginView(PluginView*); + void removePluginView(PluginView*); + + bool windowIsVisible() const { return m_windowIsVisible; } + const WebCore::IntRect& windowFrameInScreenCoordinates() const { return m_windowFrameInScreenCoordinates; } + const WebCore::IntRect& viewFrameInWindowCoordinates() const { return m_viewFrameInWindowCoordinates; } + bool windowIsFocused() const; + bool interceptEditingKeyboardEvent(WebCore::KeyboardEvent*, bool); +#elif PLATFORM(WIN) + HWND nativeWindow() const { return m_nativeWindow; } +#endif + + void installPageOverlay(PassRefPtr<PageOverlay>); + void uninstallPageOverlay(PageOverlay*); + + PassRefPtr<WebImage> snapshotInViewCoordinates(const WebCore::IntRect&, ImageOptions); + PassRefPtr<WebImage> snapshotInDocumentCoordinates(const WebCore::IntRect&, ImageOptions); + + static const WebEvent* currentEvent(); + + FindController& findController() { return m_findController; } + GeolocationPermissionRequestManager& geolocationPermissionRequestManager() { return m_geolocationPermissionRequestManager; } + + void pageDidScroll(); +#if ENABLE(TILED_BACKING_STORE) + void pageDidRequestScroll(const WebCore::IntSize& delta); + void setActualVisibleContentRect(const WebCore::IntRect&); + + bool resizesToContentsEnabled() const { return !m_resizesToContentsLayoutSize.isEmpty(); } + WebCore::IntSize resizesToContentsLayoutSize() const { return m_resizesToContentsLayoutSize; } + void setResizesToContentsUsingLayoutSize(const WebCore::IntSize& targetLayoutSize); + void resizeToContentsIfNeeded(); +#endif + + WebContextMenu* contextMenu(); + + bool hasLocalDataForURL(const WebCore::KURL&); + + static bool canHandleRequest(const WebCore::ResourceRequest&); + + class SandboxExtensionTracker { + public: + ~SandboxExtensionTracker(); + + void invalidate(); + + void beginLoad(WebFrame*, const SandboxExtension::Handle& handle); + void didStartProvisionalLoad(WebFrame*); + void didCommitProvisionalLoad(WebFrame*); + void didFailProvisionalLoad(WebFrame*); + private: + RefPtr<SandboxExtension> m_pendingProvisionalSandboxExtension; + RefPtr<SandboxExtension> m_provisionalSandboxExtension; + RefPtr<SandboxExtension> m_committedSandboxExtension; + }; + + SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; } + + static void getLocationAndLengthFromRange(WebCore::Range*, uint64_t& location, uint64_t& length); + +#if PLATFORM(MAC) + void sendAccessibilityPresenterToken(const CoreIPC::DataReference&); + AccessibilityWebPageObject* accessibilityRemoteObject(); + WebCore::IntPoint accessibilityPosition() const { return m_accessibilityPosition; } + + void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput); + + void getMarkedRange(uint64_t& location, uint64_t& length); + void characterIndexForPoint(const WebCore::IntPoint point, uint64_t& result); + void firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect); +#elif PLATFORM(WIN) + void confirmComposition(const String& compositionString); + void setComposition(const WTF::String& compositionString, const WTF::Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition); + void firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect); + void getSelectedText(WTF::String&); +#endif + + // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require + // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed. + void dummy(bool&); + +#if PLATFORM(MAC) + bool isSpeaking(); + void speak(const String&); + void stopSpeaking(); + + bool isSmartInsertDeleteEnabled() const { return m_isSmartInsertDeleteEnabled; } +#endif + + void replaceSelectionWithText(WebCore::Frame*, const String&); + void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags); + + void beginPrinting(uint64_t frameID, const PrintInfo&); + void endPrinting(); + void computePagesForPrinting(uint64_t frameID, const PrintInfo&, Vector<WebCore::IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting); +#if PLATFORM(MAC) + void drawRectToPDF(uint64_t frameID, const WebCore::IntRect&, Vector<uint8_t>& pdfData); +#endif + + bool mainFrameHasCustomRepresentation() const; + +private: + WebPage(uint64_t pageID, const WebPageCreationParameters&); + + virtual Type type() const { return APIType; } + + void platformInitialize(); + + void didReceiveWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + CoreIPC::SyncReplyMode didReceiveSyncWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + + static const char* interpretKeyEvent(const WebCore::KeyboardEvent*); + bool performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&); + + String sourceForFrame(WebFrame*); + + void loadData(PassRefPtr<WebCore::SharedBuffer>, const String& MIMEType, const String& encodingName, const WebCore::KURL& baseURL, const WebCore::KURL& failingURL); + + bool platformHasLocalDataForURL(const WebCore::KURL&); + + // Actions + void tryClose(); + void loadURL(const String&, const SandboxExtension::Handle& sandboxExtensionHandle); + void loadURLRequest(const WebCore::ResourceRequest&, const SandboxExtension::Handle& sandboxExtensionHandle); + void loadHTMLString(const String& htmlString, const String& baseURL); + void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL); + void loadPlainTextString(const String&); + void reload(bool reloadFromOrigin); + void goForward(uint64_t); + void goBack(uint64_t); + void goToBackForwardItem(uint64_t); + void setActive(bool); + void setFocused(bool); + void setInitialFocus(bool); + void setWindowResizerSize(const WebCore::IntSize&); + void setIsInWindow(bool); + void mouseEvent(const WebMouseEvent&); + void wheelEvent(const WebWheelEvent&); + void keyEvent(const WebKeyboardEvent&); + void validateMenuItem(const String&); + void executeEditCommand(const String&); +#if ENABLE(TOUCH_EVENTS) + void touchEvent(const WebTouchEvent&); +#endif + + uint64_t restoreSession(const SessionState&); + void restoreSessionAndNavigateToCurrentItem(const SessionState&); + + void didRemoveBackForwardItem(uint64_t); + + void setDrawsBackground(bool); + void setDrawsTransparentBackground(bool); + + void getContentsAsString(uint64_t callbackID); + void getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID); + void getRenderTreeExternalRepresentation(uint64_t callbackID); + void getSelectionOrContentsAsString(uint64_t callbackID); + void getSourceForFrame(uint64_t frameID, uint64_t callbackID); + void getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID); + void runJavaScriptInMainFrame(const String&, uint64_t callbackID); + + void preferencesDidChange(const WebPreferencesStore&); + void platformPreferencesDidChange(const WebPreferencesStore&); + void updatePreferences(const WebPreferencesStore&); + + void didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID); + void setUserAgent(const String&); + void setCustomTextEncodingName(const String&); + +#if PLATFORM(MAC) + void setWindowIsVisible(bool windowIsVisible); + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates); +#endif + + void unapplyEditCommand(uint64_t commandID); + void reapplyEditCommand(uint64_t commandID); + void didRemoveEditCommand(uint64_t commandID); + + void findString(const String&, uint32_t findOptions, uint32_t maxMatchCount); + void hideFindUI(); + void countStringMatches(const String&, uint32_t findOptions, uint32_t maxMatchCount); + +#if PLATFORM(QT) + void findZoomableAreaForPoint(const WebCore::IntPoint&); +#endif + + void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex); + void setTextForActivePopupMenu(int32_t index); + + void didChooseFilesForOpenPanel(const Vector<String>&); + void didCancelForOpenPanel(); + + void didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed); + + void advanceToNextMisspelling(bool startBeforeSelection); + void changeSpellingToWord(const String& word); + void unmarkAllMisspellings(); + void unmarkAllBadGrammar(); +#if PLATFORM(MAC) + void uppercaseWord(); + void lowercaseWord(); + void capitalizeWord(); + + void setSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled) { m_isSmartInsertDeleteEnabled = isSmartInsertDeleteEnabled; } +#endif + +#if ENABLE(CONTEXT_MENUS) + void didSelectItemFromActiveContextMenu(const WebContextMenuItemData&); +#endif + + OwnPtr<WebCore::Page> m_page; + RefPtr<WebFrame> m_mainFrame; + RefPtr<InjectedBundleBackForwardList> m_backForwardList; + + RefPtr<WebPageGroupProxy> m_pageGroup; + + String m_userAgent; + + WebCore::IntSize m_viewSize; + RefPtr<DrawingArea> m_drawingArea; + + bool m_drawsBackground; + bool m_drawsTransparentBackground; + + bool m_isInRedo; + bool m_isClosed; + + bool m_tabToLinks; + +#if PLATFORM(MAC) + // Whether the containing window is visible or not. + bool m_windowIsVisible; + + // Whether smart insert/delete is enabled or not. + bool m_isSmartInsertDeleteEnabled; + + // The frame of the containing window in screen coordinates. + WebCore::IntRect m_windowFrameInScreenCoordinates; + + // The frame of the view in window coordinates. + WebCore::IntRect m_viewFrameInWindowCoordinates; + + // The accessibility position of the view. + WebCore::IntPoint m_accessibilityPosition; + + // All plug-in views on this web page. + HashSet<PluginView*> m_pluginViews; + + RetainPtr<AccessibilityWebPageObject> m_mockAccessibilityElement; +#elif PLATFORM(WIN) + // Our view's window (in the UI process). + HWND m_nativeWindow; +#endif + + HashMap<uint64_t, RefPtr<WebEditCommand> > m_editCommandMap; + + WebCore::IntSize m_windowResizerSize; + + InjectedBundlePageContextMenuClient m_contextMenuClient; + InjectedBundlePageEditorClient m_editorClient; + InjectedBundlePageFormClient m_formClient; + InjectedBundlePageLoaderClient m_loaderClient; + InjectedBundlePageUIClient m_uiClient; + +#if ENABLE(TILED_BACKING_STORE) + WebCore::IntSize m_resizesToContentsLayoutSize; +#endif + + FindController m_findController; + RefPtr<PageOverlay> m_pageOverlay; + +#if ENABLE(INSPECTOR) + OwnPtr<WebInspector> m_inspector; +#endif + RefPtr<WebPopupMenu> m_activePopupMenu; + RefPtr<WebContextMenu> m_contextMenu; + RefPtr<WebOpenPanelResultListener> m_activeOpenPanelResultListener; + GeolocationPermissionRequestManager m_geolocationPermissionRequestManager; + + OwnPtr<WebCore::PrintContext> m_printContext; + + SandboxExtensionTracker m_sandboxExtensionTracker; + uint64_t m_pageID; +}; + +} // namespace WebKit + +#endif // WebPage_h diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in new file mode 100644 index 0000000..bd6bf1a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in @@ -0,0 +1,163 @@ +# 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. + +messages -> WebPage { + SetActive(bool active) + SetFocused(bool focused) + SetInitialFocus(bool forward) + SetIsInWindow(bool isInWindow) + + SetDrawsBackground(bool drawsBackground) + SetDrawsTransparentBackground(bool drawsTransparentBackground) + + KeyEvent(WebKit::WebKeyboardEvent event) + MouseEvent(WebKit::WebMouseEvent event) + WheelEvent(WebKit::WebWheelEvent event) +#if ENABLE(TOUCH_EVENTS) + TouchEvent(WebKit::WebTouchEvent event) +#endif + + GoBack(uint64_t backForwardItemID) + GoForward(uint64_t backForwardItemID) + GoToBackForwardItem(uint64_t backForwardItemID) + LoadHTMLString(WTF::String htmlString, WTF::String baseURL) + LoadAlternateHTMLString(WTF::String htmlString, WTF::String baseURL, WTF::String unreachableURL); + LoadPlainTextString(WTF::String string) + LoadURL(WTF::String url, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + LoadURLRequest(WebCore::ResourceRequest request, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + Reload(bool reloadFromOrigin) + StopLoading() + + RestoreSessionAndNavigateToCurrentItem(WebKit::SessionState state) + + DidRemoveBackForwardItem(uint64_t backForwardItemID) + + DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID) + + # Callbacks. + GetContentsAsString(uint64_t callbackID) + GetMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID) + GetRenderTreeExternalRepresentation(uint64_t callbackID) + GetSelectionOrContentsAsString(uint64_t callbackID) + GetSourceForFrame(uint64_t frameID, uint64_t callbackID) + GetWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID) + RunJavaScriptInMainFrame(WTF::String script, uint64_t callbackID) + + PreferencesDidChange(WebKit::WebPreferencesStore store) + + SetUserAgent(WTF::String userAgent) + SetCustomTextEncodingName(WTF::String encodingName) + +#if ENABLE(TILED_BACKING_STORE) + SetActualVisibleContentRect(WebCore::IntRect rect) + SetResizesToContentsUsingLayoutSize(WebCore::IntSize size) +#endif + + Close() + TryClose() + + ValidateMenuItem(WTF::String name) + ExecuteEditCommand(WTF::String name) + + DidRemoveEditCommand(uint64_t commandID) + ReapplyEditCommand(uint64_t commandID) + UnapplyEditCommand(uint64_t commandID) + + SetPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor) + SetPageZoomFactor(double zoomFactor) + SetTextZoomFactor(double zoomFactor) + + ScaleWebView(double scale, WebCore::IntPoint origin) + + SetUseFixedLayout(bool fixed) + SetFixedLayoutSize(WebCore::IntSize size) + + # Find. + FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) + HideFindUI() + CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) + + # Drag and drop. + PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags) + + # Popup menu. + DidChangeSelectedIndexForActivePopupMenu(int32_t newIndex); + SetTextForActivePopupMenu(int32_t index); + + # Context menu. + DidSelectItemFromActiveContextMenu(WebKit::WebContextMenuItemData menuItem); + + # Open panel. + DidChooseFilesForOpenPanel(Vector<WTF::String> fileURLs) + DidCancelForOpenPanel() + + # Spelling and grammar. + AdvanceToNextMisspelling(bool startBeforeSelection) + ChangeSpellingToWord(WTF::String word) + UnmarkAllMisspellings() + UnmarkAllBadGrammar() +#if PLATFORM(MAC) + UppercaseWord(); + LowercaseWord(); + CapitalizeWord(); + + SetSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled); +#endif + + # Geolocation + DidReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) + + SetWindowResizerSize(WebCore::IntSize intersectsView) + + # Printing. + BeginPrinting(uint64_t frameID, WebKit::PrintInfo printInfo); + EndPrinting(); + ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo) -> (Vector<WebCore::IntRect> pageRects, double totalScaleFactorForPrinting) +#if PLATFORM(MAC) + DrawRectToPDF(uint64_t frameID, WebCore::IntRect rect) -> (Vector<uint8_t> pdfData) +#endif + + // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require + // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed. + Dummy() -> (bool dummyReturn) + +#if PLATFORM(MAC) + # Complex text input support for plug-ins. + SendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, String textInput) + + SetWindowIsVisible(bool windowIsVisible) + WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates, WebCore::IntPoint accessibilityViewCoordinates) + GetMarkedRange() -> (uint64_t location, uint64_t length) + CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result) + FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect) + SendAccessibilityPresenterToken(CoreIPC::DataReference token) +#endif +#if PLATFORM(WIN) + ConfirmComposition(WTF::String compositionString) + SetComposition(WTF::String compositionString, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t cursorPosition) + FirstRectForCharacterInSelectedRange(uint64_t characterPosition) -> (WebCore::IntRect resultRect) + GetSelectedText() -> (WTF::String text) +#endif +#if PLATFORM(QT) + FindZoomableAreaForPoint(WebCore::IntPoint point) +#endif +} diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp new file mode 100644 index 0000000..67109ec --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp @@ -0,0 +1,47 @@ +/* + * 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 "WebPageGroupProxy.h" + +#include "WebProcess.h" +#include "InjectedBundle.h" + +namespace WebKit { + +PassRefPtr<WebPageGroupProxy> WebPageGroupProxy::create(const WebPageGroupData& data) +{ + RefPtr<WebPageGroupProxy> pageGroup = adoptRef(new WebPageGroupProxy(data)); + + if (pageGroup->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle()) + WebProcess::shared().injectedBundle()->didInitializePageGroup(pageGroup.get()); + + return pageGroup.release(); +} + +WebPageGroupProxy::~WebPageGroupProxy() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h new file mode 100644 index 0000000..55cf629 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef WebPageGroupProxy_h +#define WebPageGroupProxy_h + +#include "APIObject.h" +#include "WebPageGroupData.h" +#include <wtf/PassRefPtr.h> + +namespace WebKit { + +class WebPageGroupProxy : public APIObject { +public: + static const Type APIType = TypeBundlePageGroup; + + static PassRefPtr<WebPageGroupProxy> create(const WebPageGroupData&); + virtual ~WebPageGroupProxy(); + + const String& identifier() const { return m_data.identifer; } + uint64_t pageGroupID() const { return m_data.pageGroupID; } + bool isVisibleToInjectedBundle() const { return m_data.visibleToInjectedBundle; } + +private: + WebPageGroupProxy(const WebPageGroupData& data) + : m_data(data) + { + } + + virtual Type type() const { return APIType; } + + WebPageGroupData m_data; +}; + +} // namespace WebKit + +#endif // WebPageGroupProxy_h diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp new file mode 100644 index 0000000..4697f62 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <wtf/text/WTFString.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + notImplemented(); + return String(); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h new file mode 100644 index 0000000..3b331b9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 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 AccessibilityWebPageObject_h +#define AccessibilityWebPageObject_h + +namespace WebKit { +class WebPage; +} + +@interface AccessibilityWebPageObject : NSObject { + WebKit::WebPage* m_page; + + id m_parent; + NSArray* m_attributeNames; + NSMutableArray* m_accessibilityChildren; +} + +- (void)setWebPage:(WebKit::WebPage*)page; + +- (void)setRemoteParent:(id)parent; + +@end + +#endif // AccessibilityWebPageObject_h diff --git a/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm new file mode 100644 index 0000000..fa4aa1a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/AccessibilityWebPageObject.mm @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2011 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. + */ + +#import "AccessibilityWebPageObject.h" + +#import "WebFrame.h" +#import "WebPage.h" +#import <WebCore/AXObjectCache.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/ScrollView.h> +#import <WebCore/Scrollbar.h> + +using namespace WebCore; +using namespace WebKit; + +@implementation AccessibilityWebPageObject + +- (id)accessibilityRootObjectWrapper +{ + WebCore::Page* page = m_page->corePage(); + if (!page) + return nil; + + WebCore::Frame* core = page->mainFrame(); + if (!core || !core->document()) + return nil; + + AccessibilityObject* root = core->document()->axObjectCache()->rootObject(); + if (!root) + return nil; + + return root->wrapper(); +} + +- (void)setWebPage:(WebPage*)page +{ + m_page = page; +} + +- (void)setRemoteParent:(id)parent +{ + if (parent != m_parent) { + [m_parent release]; + m_parent = [parent retain]; + } +} + +- (void)dealloc +{ + [m_accessibilityChildren release]; + [m_attributeNames release]; + [m_parent release]; + [super dealloc]; +} + +- (BOOL)accessibilityIsIgnored +{ + return NO; +} + +- (NSArray *)accessibilityAttributeNames +{ + if (!m_attributeNames) + m_attributeNames = [[NSArray alloc] initWithObjects: + NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityFocusedAttribute, + NSAccessibilityParentAttribute, NSAccessibilityWindowAttribute, NSAccessibilityTopLevelUIElementAttribute, + NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, NSAccessibilityChildrenAttribute, nil]; + + return m_attributeNames; +} + +- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute +{ + return NO; +} + +- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute +{ + return; +} + +- (NSArray *)accessibilityActionNames +{ + return [NSArray array]; +} + +- (NSArray *)accessibilityChildren +{ + id wrapper = [self accessibilityRootObjectWrapper]; + if (!wrapper) + return [NSArray array]; + + return [NSArray arrayWithObject:wrapper]; +} + +- (id)accessibilityAttributeValue:(NSString *)attribute +{ + if (!WebCore::AXObjectCache::accessibilityEnabled()) + WebCore::AXObjectCache::enableAccessibility(); + + if ([attribute isEqualToString:NSAccessibilityParentAttribute]) + return m_parent; + if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) + return [m_parent accessibilityAttributeValue:NSAccessibilityWindowAttribute]; + if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) + return [m_parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; + if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) + return NSAccessibilityGroupRole; + if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) + return NSAccessibilityRoleDescription(NSAccessibilityGroupRole, nil); + if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) + return [NSNumber numberWithBool:NO]; + + if (!m_page) + return nil; + + if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { + WebCore::IntPoint point = m_page->accessibilityPosition(); + return [NSValue valueWithPoint:NSMakePoint(point.x(), point.y())]; + } + if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) { + const IntSize& s = m_page->size(); + return [NSValue valueWithSize:NSMakeSize(s.width(), s.height())]; + } + if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) + return [self accessibilityChildren]; + + return [super accessibilityAttributeValue:attribute]; +} + +- (BOOL)accessibilityShouldUseUniqueId +{ + return YES; +} + +- (id)accessibilityHitTest:(NSPoint)point +{ + // Hit-test point comes in as bottom-screen coordinates. Needs to be normalized to the frame of the web page. + NSPoint remotePosition = [[self accessibilityAttributeValue:NSAccessibilityPositionAttribute] pointValue]; + NSSize remoteSize = [[self accessibilityAttributeValue:NSAccessibilitySizeAttribute] sizeValue]; + + // Get the y position of the WKView (we have to screen-flip and go from bottom left to top left). + CGFloat screenHeight = [[[NSScreen screens] objectAtIndex:0] frame].size.height; + remotePosition.y = (screenHeight - remotePosition.y) - remoteSize.height; + + point.y = screenHeight - point.y; + + // Re-center point into the web page's frame. + point.y -= remotePosition.y; + point.x -= remotePosition.x; + + WebCore::FrameView* fv = m_page->mainFrame()->coreFrame()->view(); + if (fv) { + point.y += fv->scrollPosition().y(); + point.x += fv->scrollPosition().x(); + } + + return [[self accessibilityRootObjectWrapper] accessibilityHitTest:point]; +} + +- (id)accessibilityFocusedUIElement +{ + return NSAccessibilityUnignoredDescendant(self); +} + + +@end diff --git a/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp b/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp new file mode 100644 index 0000000..6bcecfd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/ChunkedUpdateDrawingAreaMac.cpp @@ -0,0 +1,60 @@ +/* + * 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 "ChunkedUpdateDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebFrameLoaderClient.h" +#include <WebCore/Frame.h> +#include <WebCore/GraphicsContext.h> +#include <wtf/RetainPtr.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + // FIXME: It would be better if we could avoid painting altogether when there is a custom representation. + if (m_webPage->mainFrameHasCustomRepresentation()) + return; + + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); + RetainPtr<CGContextRef> bitmapContext(AdoptCF, CGBitmapContextCreate(updateChunk->data(), updateChunk->rect().width(), updateChunk->rect().height(), 8, updateChunk->rect().width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + + // WebCore expects a flipped coordinate system. + CGContextTranslateCTM(bitmapContext.get(), 0.0, updateChunk->rect().height()); + CGContextScaleCTM(bitmapContext.get(), 1.0, -1.0); + + // Now paint into the backing store. + GraphicsContext graphicsContext(bitmapContext.get()); + graphicsContext.translate(-updateChunk->rect().x(), -updateChunk->rect().y()); + + m_webPage->drawRect(graphicsContext, updateChunk->rect()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm new file mode 100644 index 0000000..f8b7e71 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/LayerBackedDrawingAreaMac.mm @@ -0,0 +1,185 @@ +/* + * 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. + */ + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerBackedDrawingArea.h" + +#include "DrawingAreaProxyMessageKinds.h" +#include "WebKitSystemInterface.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayer.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +void LayerBackedDrawingArea::platformInit() +{ + setUpUpdateLayoutRunLoopObserver(); + + [m_backingLayer->platformLayer() setGeometryFlipped:YES]; +#if HAVE(HOSTED_CORE_ANIMATION) + attachCompositingContext(); +#endif + + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::platformClear() +{ + if (!m_attached) + return; + + if (m_updateLayoutRunLoopObserver) { + CFRunLoopObserverInvalidate(m_updateLayoutRunLoopObserver.get()); + m_updateLayoutRunLoopObserver = 0; + } + +#if HAVE(HOSTED_CORE_ANIMATION) + WKCARemoteLayerClientInvalidate(m_remoteLayerRef.get()); + m_remoteLayerRef = nullptr; +#endif + + m_attached = false; +} + +void LayerBackedDrawingArea::attachCompositingContext() +{ + if (m_attached) + return; + + m_attached = true; + +#if HAVE(HOSTED_CORE_ANIMATION) + mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); + m_remoteLayerRef = WKCARemoteLayerClientMakeWithServerPort(serverPort); + WKCARemoteLayerClientSetLayer(m_remoteLayerRef.get(), m_backingLayer->platformLayer()); + + uint32_t contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerRef.get()); + WebProcess::shared().connection()->sendSync(DrawingAreaProxyLegacyMessage::AttachCompositingContext, m_webPage->pageID(), CoreIPC::In(contextID), CoreIPC::Out()); +#endif +} + +void LayerBackedDrawingArea::detachCompositingContext() +{ + m_backingLayer->removeAllChildren(); + + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer* layer) +{ + m_backingLayer->removeAllChildren(); + if (layer) + m_backingLayer->addChild(layer); + + scheduleCompositingLayerSync(); +} + +void LayerBackedDrawingArea::scheduleCompositingLayerSync() +{ +// if (m_syncTimer.isActive()) +// return; +// +// m_syncTimer.startOneShot(0); + + scheduleUpdateLayoutRunLoopObserver(); +} + +void LayerBackedDrawingArea::syncCompositingLayers() +{ + m_backingLayer->syncCompositingStateForThisLayerOnly(); + + bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateRecursive(); + if (!didSync) { + + } +} + +void LayerBackedDrawingArea::setUpUpdateLayoutRunLoopObserver() +{ + if (m_updateLayoutRunLoopObserver) + return; + + // Run before Core Animations commit observer, which has order 2000000. + const CFIndex runLoopOrder = 2000000 - 1; + CFRunLoopObserverContext context = { 0, this, 0, 0, 0 }; + m_updateLayoutRunLoopObserver.adoptCF(CFRunLoopObserverCreate(0, + kCFRunLoopBeforeWaiting | kCFRunLoopExit, true /* repeats */, + runLoopOrder, updateLayoutRunLoopObserverCallback, &context)); +} + +void LayerBackedDrawingArea::scheduleUpdateLayoutRunLoopObserver() +{ + CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); + CFRunLoopWakeUp(currentRunLoop); + + if (CFRunLoopContainsObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes)) + return; + + CFRunLoopAddObserver(currentRunLoop, m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes); +} + +void LayerBackedDrawingArea::removeUpdateLayoutRunLoopObserver() +{ + // FIXME: cache the run loop ref? + CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), m_updateLayoutRunLoopObserver.get(), kCFRunLoopCommonModes); +} + +void LayerBackedDrawingArea::updateLayoutRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* info) +{ + // Keep the drawing area alive while running the callback, since that does layout, + // which might replace this drawing area with one of another type. + RefPtr<LayerBackedDrawingArea> drawingArea = reinterpret_cast<LayerBackedDrawingArea*>(info); + drawingArea->updateLayoutRunLoopObserverFired(); +} + +void LayerBackedDrawingArea::updateLayoutRunLoopObserverFired() +{ + // Laying out the page can cause the drawing area to change so we keep an extra reference. + RefPtr<LayerBackedDrawingArea> protect(this); + + m_webPage->layoutIfNeeded(); + + if (m_webPage->drawingArea() != this) + return; + + if (m_attached) + syncCompositingLayers(); +} + +void LayerBackedDrawingArea::onPageClose() +{ + platformClear(); +} + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm new file mode 100644 index 0000000..83909be --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#import "WebInspector.h" + +#import <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + NSString *path = [[NSBundle bundleWithIdentifier:@"com.apple.WebCore"] pathForResource:@"localizedStrings" ofType:@"js"]; + if (path) + return [[NSURL fileURLWithPath:path] absoluteString]; + return String(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm new file mode 100644 index 0000000..f3211f2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm @@ -0,0 +1,369 @@ +/* + * 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 "WebPage.h" + +#include "AccessibilityWebPageObject.h" +#include "DataReference.h" +#include "PluginView.h" +#include "WebCoreArgumentCoders.h" +#include "WebEvent.h" +#include "WebFrame.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/AXObjectCache.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/HitTestResult.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/ScrollView.h> +#include <WebCore/TextIterator.h> +#include <WebCore/WindowsKeyboardCodes.h> +#include <WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ + m_page->addSchedulePair(SchedulePair::create([NSRunLoop currentRunLoop], kCFRunLoopCommonModes)); + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + AccessibilityWebPageObject* mockAccessibilityElement = [[[AccessibilityWebPageObject alloc] init] autorelease]; + + // Get the pid for the starting process. + pid_t pid = WebProcess::shared().presenterApplicationPid(); + WKAXInitializeElementWithPresenterPid(mockAccessibilityElement, pid); + [mockAccessibilityElement setWebPage:this]; + + // send data back over + NSData* remoteToken = (NSData *)WKAXRemoteTokenForElement(mockAccessibilityElement); + CoreIPC::DataReference dataToken = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([remoteToken bytes]), [remoteToken length]); + send(Messages::WebPageProxy::DidReceiveAccessibilityPageToken(dataToken)); + m_mockAccessibilityElement = mockAccessibilityElement; +#endif +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ +} + +// FIXME: need to add support for input methods + +bool WebPage::interceptEditingKeyboardEvent(KeyboardEvent* evt, bool shouldSaveCommand) +{ + Node* node = evt->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + + const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); + if (!keyEvent) + return false; + const Vector<KeypressCommand>& commands = evt->keypressCommands(); + bool hasKeypressCommand = !commands.isEmpty(); + + bool eventWasHandled = false; + + if (shouldSaveCommand || !hasKeypressCommand) { + Vector<KeypressCommand> commandsList; + Vector<CompositionUnderline> underlines; + unsigned start; + unsigned end; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretKeyEvent(keyEvent->type()), + Messages::WebPageProxy::InterpretKeyEvent::Reply(commandsList, start, end, underlines), + m_pageID, CoreIPC::Connection::NoTimeout)) + return false; + if (commandsList.isEmpty()) + return eventWasHandled; + + if (commandsList[0].commandName == "setMarkedText") { + frame->editor()->setComposition(commandsList[0].text, underlines, start, end); + eventWasHandled = true; + } else if (commandsList[0].commandName == "insertText" && frame->editor()->hasComposition()) { + frame->editor()->confirmComposition(commandsList[0].text); + eventWasHandled = true; + } else if (commandsList[0].commandName == "unmarkText") { + frame->editor()->confirmComposition(); + eventWasHandled = true; + } else { + for (size_t i = 0; i < commandsList.size(); i++) + evt->keypressCommands().append(commandsList[i]); + } + } else { + size_t size = commands.size(); + // Are there commands that would just cause text insertion if executed via Editor? + // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore + // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated + // (e.g. Tab that inserts a Tab character, or Enter). + bool haveTextInsertionCommands = false; + for (size_t i = 0; i < size; ++i) { + if (frame->editor()->command(commands[i].commandName).isTextInsertion()) + haveTextInsertionCommands = true; + } + if (!haveTextInsertionCommands || keyEvent->type() == PlatformKeyboardEvent::Char) { + for (size_t i = 0; i < size; ++i) { + if (commands[i].commandName == "insertText") { + // Don't insert null or control characters as they can result in unexpected behaviour + if (evt->charCode() < ' ') + return false; + eventWasHandled = frame->editor()->insertText(commands[i].text, evt); + } else + if (frame->editor()->command(commands[i].commandName).isSupported()) + eventWasHandled = frame->editor()->command(commands[i].commandName).execute(evt); + } + } + } + return eventWasHandled; +} + +void WebPage::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput) +{ + for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) { + if ((*it)->sendComplexTextInput(pluginComplexTextInputIdentifier, textInput)) + break; + } +} + +void WebPage::getMarkedRange(uint64_t& location, uint64_t& length) +{ + location = NSNotFound; + length = 0; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + getLocationAndLengthFromRange(frame->editor()->compositionRange().get(), location, length); +} + +static Range *characterRangeAtPoint(Frame* frame, const IntPoint point) +{ + VisiblePosition position = frame->visiblePositionForPoint(point); + if (position.isNull()) + return NULL; + + VisiblePosition previous = position.previous(); + if (previous.isNotNull()) { + Range *previousCharacterRange = makeRange(previous, position).get(); + NSRect rect = frame->editor()->firstRectForRange(previousCharacterRange); + if (NSPointInRect(point, rect)) + return previousCharacterRange; + } + + VisiblePosition next = position.next(); + if (next.isNotNull()) { + Range *nextCharacterRange = makeRange(position, next).get(); + NSRect rect = frame->editor()->firstRectForRange(nextCharacterRange); + if (NSPointInRect(point, rect)) + return nextCharacterRange; + } + + return NULL; +} + +void WebPage::characterIndexForPoint(IntPoint point, uint64_t& index) +{ + index = NSNotFound; + Frame* frame = m_page->mainFrame(); + if (!frame) + return; + + HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(point, false); + frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame(); + + Range *range = characterRangeAtPoint(frame, result.point()); + if (!range) + return; + + uint64_t length; + getLocationAndLengthFromRange(range, index, length); +} + +static PassRefPtr<Range> convertToRange(Frame* frame, NSRange nsrange) +{ + if (nsrange.location > INT_MAX) + return 0; + if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX) + nsrange.length = INT_MAX - nsrange.location; + + // our critical assumption is that we are only called by input methods that + // concentrate on a given area containing the selection + // We have to do this because of text fields and textareas. The DOM for those is not + // directly in the document DOM, so serialization is problematic. Our solution is + // to use the root editable element of the selection start as the positional base. + // That fits with AppKit's idea of an input context. + Element* selectionRoot = frame->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement(); + return TextIterator::rangeFromLocationAndLength(scope, nsrange.location, nsrange.length); +} + +void WebPage::firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + resultRect.setLocation(IntPoint(0, 0)); + resultRect.setSize(IntSize(0, 0)); + + RefPtr<Range> range = convertToRange(frame, NSMakeRange(location, length)); + if (range) { + ASSERT(range->startContainer()); + ASSERT(range->endContainer()); + } + + IntRect rect = frame->editor()->firstRectForRange(range.get()); + resultRect = frame->view()->contentsToWindow(rect); +} + +static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); +} + +static inline void logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); +} + +bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent) +{ + if (keyboardEvent.type() != WebEvent::KeyDown) + return false; + + // FIXME: This should be in WebCore. + + switch (keyboardEvent.windowsVirtualKeyCode()) { + case VK_BACK: + if (keyboardEvent.shiftKey()) + m_page->goForward(); + else + m_page->goBack(); + break; + case VK_SPACE: + if (keyboardEvent.shiftKey()) + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + else + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + case VK_PRIOR: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + break; + case VK_NEXT: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + case VK_HOME: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument); + break; + case VK_END: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument); + break; + case VK_UP: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) { + scroll(m_page.get(), ScrollUp, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (keyboardEvent.altKey() || keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollUp, ScrollByPage); + else + scroll(m_page.get(), ScrollUp, ScrollByLine); + break; + case VK_DOWN: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) { + scroll(m_page.get(), ScrollDown, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (keyboardEvent.altKey() || keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollDown, ScrollByPage); + else + scroll(m_page.get(), ScrollDown, ScrollByLine); + break; + case VK_LEFT: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) + m_page->goBack(); + else { + if (keyboardEvent.altKey() | keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollLeft, ScrollByPage); + else + scroll(m_page.get(), ScrollLeft, ScrollByLine); + } + break; + case VK_RIGHT: + if (keyboardEvent.shiftKey()) + return false; + if (keyboardEvent.metaKey()) + m_page->goForward(); + else { + if (keyboardEvent.altKey() || keyboardEvent.controlKey()) + scroll(m_page.get(), ScrollRight, ScrollByPage); + else + scroll(m_page.get(), ScrollRight, ScrollByLine); + } + break; + default: + return false; + } + + return true; +} + +void WebPage::sendAccessibilityPresenterToken(const CoreIPC::DataReference& data) +{ +#if !defined(BUILDING_ON_SNOW_LEOPARD) + NSData* tokenData = [NSData dataWithBytes:data.data() length:data.size()]; + [m_mockAccessibilityElement.get() setRemoteParent:WKAXRemoteElementForToken((CFDataRef)tokenData)]; +#endif +} + +AccessibilityWebPageObject* WebPage::accessibilityRemoteObject() +{ + return m_mockAccessibilityElement.get(); +} + +bool WebPage::platformHasLocalDataForURL(const WebCore::KURL& url) +{ + NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url]; + [request setValue:(NSString*)userAgent() forHTTPHeaderField:@"User-Agent"]; + NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request]; + [request release]; + + return cachedResponse; +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) +{ + if ([NSURLConnection canHandleRequest:request.nsURLRequest()]) + return YES; + + // FIXME: Return true if this scheme is any one WebKit2 knows how to handle. + return request.url().protocolIs("applewebdata"); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp new file mode 100644 index 0000000..25ed3e7 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/ChunkedUpdateDrawingAreaQt.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 "ChunkedUpdateDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebPage.h" +#include <QImage> +#include <QPainter> +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + QImage image(updateChunk->createImage()); + QPainter painter(&image); + // Now paint into the backing store. + GraphicsContext graphicsContext(&painter); + graphicsContext.translate(-updateChunk->rect().x(), -updateChunk->rect().y()); + + m_webPage->drawRect(graphicsContext, updateChunk->rect()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp new file mode 100644 index 0000000..b7ad782 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/TiledDrawingAreaQt.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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. + */ + +#if ENABLE(TILED_BACKING_STORE) + +#include "TiledDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebPage.h" +#include <WebCore/GraphicsContext.h> + +#include <QImage> +#include <QPainter> + +using namespace WebCore; + +namespace WebKit { + +void TiledDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk, float scale) +{ + IntRect tileRect = updateChunk->rect(); + QImage image(updateChunk->createImage()); + QPainter painter(&image); + // Now paint into the backing store. + GraphicsContext graphicsContext(&painter); + graphicsContext.translate(-tileRect.x(), -tileRect.y()); + graphicsContext.scale(FloatSize(scale, scale)); + IntRect contentRect = enclosingIntRect(FloatRect(tileRect.x() / scale, + tileRect.y() / scale, + tileRect.width() / scale, + tileRect.height() / scale)); + m_webPage->drawRect(graphicsContext, contentRect); +} + +} // namespace WebKit + +#endif // TILED_BACKING_STORE diff --git a/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp new file mode 100644 index 0000000..99aa1eb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp @@ -0,0 +1,45 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <wtf/text/WTFString.h> + +#define DISABLE_NOT_IMPLEMENTED_WARNINGS 1 +#include "NotImplemented.h" + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + notImplemented(); + return String(); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp new file mode 100644 index 0000000..fe1a89c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 "WebPage.h" + +#include "WebEvent.h" +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/Settings.h> + +#ifndef VK_UNKNOWN +#define VK_UNKNOWN 0 +#define VK_BACK 0x08 +#define VK_TAB 0x09 +#define VK_CLEAR 0x0C +#define VK_RETURN 0x0D +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 // CTRL key +#define VK_MENU 0x12 // ALT key +#define VK_PAUSE 0x13 // PAUSE key +#define VK_CAPITAL 0x14 // CAPS LOCK key +#define VK_KANA 0x15 // Input Method Editor (IME) Kana mode +#define VK_HANGUL 0x15 // IME Hangul mode +#define VK_JUNJA 0x17 // IME Junja mode +#define VK_FINAL 0x18 // IME final mode +#define VK_HANJA 0x19 // IME Hanja mode +#define VK_KANJI 0x19 // IME Kanji mode +#define VK_ESCAPE 0x1B // ESC key +#define VK_CONVERT 0x1C // IME convert +#define VK_NONCONVERT 0x1D // IME nonconvert +#define VK_ACCEPT 0x1E // IME accept +#define VK_MODECHANGE 0x1F // IME mode change request +#define VK_SPACE 0x20 // SPACE key +#define VK_PRIOR 0x21 // PAGE UP key +#define VK_NEXT 0x22 // PAGE DOWN key +#define VK_END 0x23 // END key +#define VK_HOME 0x24 // HOME key +#define VK_LEFT 0x25 // LEFT ARROW key +#define VK_UP 0x26 // UP ARROW key +#define VK_RIGHT 0x27 // RIGHT ARROW key +#define VK_DOWN 0x28 // DOWN ARROW key +#define VK_SELECT 0x29 // SELECT key +#define VK_PRINT 0x2A // PRINT key +#define VK_EXECUTE 0x2B // EXECUTE key +#define VK_SNAPSHOT 0x2C // PRINT SCREEN key +#define VK_INSERT 0x2D // INS key +#define VK_DELETE 0x2E // DEL key +#define VK_HELP 0x2F // HELP key +// Windows 2000/XP: For any country/region, the '.' key +#define VK_OEM_PERIOD 0xBE +#endif + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ +} + +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, CtrlKey, "InsertNewline" }, + { VK_RETURN, AltKey, "InsertNewline" }, + { VK_RETURN, ShiftKey, "InsertNewline" }, + { VK_RETURN, AltKey | ShiftKey, "InsertNewline" }, + + // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled + // in the application or in WebKit. We chose WebKit. + { 'C', CtrlKey, "Copy" }, + { 'V', CtrlKey, "Paste" }, + { 'X', CtrlKey, "Cut" }, + { 'A', CtrlKey, "SelectAll" }, + { VK_INSERT, CtrlKey, "Copy" }, + { VK_DELETE, ShiftKey, "Cut" }, + { VK_INSERT, ShiftKey, "Paste" }, + { 'Z', CtrlKey, "Undo" }, + { 'Z', CtrlKey | ShiftKey, "Redo" }, +}; + +static const KeyPressEntry keyPressEntries[] = { + { '\t', 0, "InsertTab" }, + { '\t', ShiftKey, "InsertBacktab" }, + { '\r', 0, "InsertNewline" }, + { '\r', CtrlKey, "InsertNewline" }, + { '\r', AltKey, "InsertNewline" }, + { '\r', ShiftKey, "InsertNewline" }, + { '\r', AltKey | ShiftKey, "InsertNewline" }, +}; + +const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt) +{ + ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent); + + static HashMap<int, const char*>* keyDownCommandsMap = 0; + static HashMap<int, const char*>* keyPressCommandsMap = 0; + + if (!keyDownCommandsMap) { + keyDownCommandsMap = new HashMap<int, const char*>; + keyPressCommandsMap = new HashMap<int, const char*>; + + for (unsigned i = 0; i < (sizeof(keyDownEntries) / sizeof(keyDownEntries[0])); i++) + keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); + + for (unsigned i = 0; i < (sizeof(keyPressEntries) / sizeof(keyPressEntries[0])); 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->ctrlKey()) + modifiers |= CtrlKey; + + if (evt->type() == eventNames().keydownEvent) { + int mapKey = modifiers << 16 | evt->keyEvent()->windowsVirtualKeyCode(); + return mapKey ? keyDownCommandsMap->get(mapKey) : 0; + } + + int mapKey = modifiers << 16 | evt->charCode(); + return mapKey ? keyPressCommandsMap->get(mapKey) : 0; +} + +static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); +} + +static inline void logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); +} + +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->goForward(); + else + m_page->goBack(); + break; + case VK_SPACE: + logicalScroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward, 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: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument); + break; + case VK_END: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument); + break; + case VK_PRIOR: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + break; + case VK_NEXT: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + default: + return false; + } + + return true; +} + +bool WebPage::platformHasLocalDataForURL(const WebCore::KURL&) +{ + // FIXME: Implement + return false; +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest&) +{ + // FIXME: Implement + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/ChunkedUpdateDrawingAreaWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/ChunkedUpdateDrawingAreaWin.cpp new file mode 100644 index 0000000..aa1f975 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/ChunkedUpdateDrawingAreaWin.cpp @@ -0,0 +1,63 @@ +/* + * 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 "ChunkedUpdateDrawingArea.h" + +#include "UpdateChunk.h" +#include "WebPage.h" +#include <WebCore/BitmapInfo.h> +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + OwnPtr<HDC> hdc(::CreateCompatibleDC(0)); + + void* bits; + BitmapInfo bmp = BitmapInfo::createBottomUp(updateChunk->rect().size()); + OwnPtr<HBITMAP> hbmp(::CreateDIBSection(0, &bmp, DIB_RGB_COLORS, &bits, updateChunk->memory(), 0)); + + HBITMAP hbmpOld = static_cast<HBITMAP>(::SelectObject(hdc.get(), hbmp.get())); + + GraphicsContext gc(hdc.get()); + gc.save(); + + // FIXME: Is this white fill needed? + RECT rect = updateChunk->rect(); + ::FillRect(hdc.get(), &rect, (HBRUSH)::GetStockObject(WHITE_BRUSH)); + gc.translate(-updateChunk->rect().x(), -updateChunk->rect().y()); + + m_webPage->drawRect(gc, updateChunk->rect()); + + gc.restore(); + + // Re-select the old HBITMAP + ::SelectObject(hdc.get(), hbmpOld); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/LayerBackedDrawingAreaWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/LayerBackedDrawingAreaWin.cpp new file mode 100644 index 0000000..c07e1f5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/LayerBackedDrawingAreaWin.cpp @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerBackedDrawingArea.h" + +#include "DrawingAreaProxyMessageKinds.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayer.h> +#include <WebCore/Page.h> +#include <WebCore/WKCACFLayerRenderer.h> +#include <WebCore/WebCoreInstanceHandle.h> + +using namespace WebCore; + +namespace WebKit { + +void LayerBackedDrawingArea::platformInit() +{ +} + +void LayerBackedDrawingArea::platformClear() +{ +} + +void LayerBackedDrawingArea::attachCompositingContext() +{ +} + +void LayerBackedDrawingArea::detachCompositingContext() +{ +} + +void LayerBackedDrawingArea::setRootCompositingLayer(WebCore::GraphicsLayer* layer) +{ +} + +void LayerBackedDrawingArea::scheduleCompositingLayerSync() +{ +} + +void LayerBackedDrawingArea::syncCompositingLayers() +{ +} + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp new file mode 100644 index 0000000..4c30b8b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp @@ -0,0 +1,46 @@ +/* + * 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 "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <wtf/RetainPtr.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + RetainPtr<CFURLRef> localizedStringsURLRef(AdoptCF, CFBundleCopyResourceURL(CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit")), CFSTR("localizedStrings"), CFSTR("js"), 0)); + if (!localizedStringsURLRef) + return String(); + + return String(CFURLGetString(localizedStringsURLRef.get())); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp new file mode 100644 index 0000000..d41972c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp @@ -0,0 +1,310 @@ +/* + * 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 "WebPage.h" + +#include "FontSmoothingLevel.h" +#include "WebEvent.h" +#include "WebPreferencesStore.h" +#include <WebCore/FocusController.h> +#include <WebCore/FontRenderingMode.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/Settings.h> +#if PLATFORM(CG) +#include <WebKitSystemInterface/WebKitSystemInterface.h> +#endif +#include <WinUser.h> + +#if USE(CFNETWORK) +#include <CFNetwork/CFURLCachePriv.h> +#include <CFNetwork/CFURLProtocolPriv.h> +#include <CFNetwork/CFURLRequestPriv.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ + m_page->settings()->setFontRenderingMode(AlternateRenderingMode); +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store) +{ + FontSmoothingLevel fontSmoothingLevel = static_cast<FontSmoothingLevel>(store.getUInt32ValueForKey(WebPreferencesKey::fontSmoothingLevelKey())); + +#if PLATFORM(CG) + FontSmoothingLevel adjustedLevel = fontSmoothingLevel; + if (adjustedLevel == FontSmoothingLevelWindows) + adjustedLevel = FontSmoothingLevelMedium; + wkSetFontSmoothingLevel(adjustedLevel); +#endif + + m_page->settings()->setFontRenderingMode(fontSmoothingLevel == FontSmoothingLevelWindows ? AlternateRenderingMode : NormalRenderingMode); +} + +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, CtrlKey, "InsertNewline" }, + { VK_RETURN, AltKey, "InsertNewline" }, + { VK_RETURN, ShiftKey, "InsertNewline" }, + { VK_RETURN, AltKey | ShiftKey, "InsertNewline" }, + + // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled + // in the application or in WebKit. We chose WebKit. + { 'C', CtrlKey, "Copy" }, + { 'V', CtrlKey, "Paste" }, + { 'X', CtrlKey, "Cut" }, + { 'A', CtrlKey, "SelectAll" }, + { VK_INSERT, CtrlKey, "Copy" }, + { VK_DELETE, ShiftKey, "Cut" }, + { VK_INSERT, ShiftKey, "Paste" }, + { 'Z', CtrlKey, "Undo" }, + { 'Z', CtrlKey | ShiftKey, "Redo" }, +}; + +static const KeyPressEntry keyPressEntries[] = { + { '\t', 0, "InsertTab" }, + { '\t', ShiftKey, "InsertBacktab" }, + { '\r', 0, "InsertNewline" }, + { '\r', CtrlKey, "InsertNewline" }, + { '\r', AltKey, "InsertNewline" }, + { '\r', ShiftKey, "InsertNewline" }, + { '\r', AltKey | ShiftKey, "InsertNewline" }, +}; + +const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt) +{ + ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent); + + static HashMap<int, const char*>* keyDownCommandsMap = 0; + static HashMap<int, const char*>* keyPressCommandsMap = 0; + + if (!keyDownCommandsMap) { + keyDownCommandsMap = new HashMap<int, const char*>; + keyPressCommandsMap = new HashMap<int, const char*>; + + for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i) + keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); + + for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++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->ctrlKey()) + 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; +} + +static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); +} + +static inline void logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); +} + +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->goForward(); + else + m_page->goBack(); + 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: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument); + break; + case VK_END: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument); + break; + case VK_PRIOR: + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + break; + case VK_NEXT: + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + default: + return false; + } + + return true; +} + +bool WebPage::platformHasLocalDataForURL(const WebCore::KURL& url) +{ +#if USE(CFNETWORK) + RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL()); + RetainPtr<CFMutableURLRequestRef> request(AdoptCF, CFURLRequestCreateMutable(0, cfURL.get(), kCFURLRequestCachePolicyReloadIgnoringCache, 60, 0)); + + RetainPtr<CFStringRef> userAgent(AdoptCF, userAgent().createCFString()); + CFURLRequestSetHTTPHeaderFieldValue(request.get(), CFSTR("User-Agent"), userAgent.get()); + + RetainPtr<CFURLCacheRef> cache(AdoptCF, CFURLCacheCopySharedURLCache()); + + RetainPtr<CFCachedURLResponseRef> response(AdoptCF, CFURLCacheCopyResponseForRequest(cache.get(), request.get())); + return response; +#else + return false; +#endif +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) +{ +#if USE(CFNETWORK) + // FIXME: Are there other requests we need to be able to handle? WebKit1's WebView.cpp has a FIXME here as well. + return CFURLProtocolCanHandleRequest(request.cfURLRequest()); +#else + return true; +#endif +} + +void WebPage::confirmComposition(const String& compositionString) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || !frame->editor()->canEdit()) + return; + frame->editor()->confirmComposition(compositionString); +} + +void WebPage::setComposition(const String& compositionString, const Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || !frame->editor()->canEdit()) + return; + frame->editor()->setComposition(compositionString, underlines, cursorPosition, 0); +} + +void WebPage::firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + IntRect rect; + if (RefPtr<Range> range = frame->editor()->hasComposition() ? frame->editor()->compositionRange() : frame->selection()->selection().toNormalizedRange()) { + ExceptionCode ec = 0; + RefPtr<Range> tempRange = range->cloneRange(ec); + tempRange->setStart(tempRange->startContainer(ec), tempRange->startOffset(ec) + characterPosition, ec); + rect = frame->editor()->firstRectForRange(tempRange.get()); + } + resultRect = frame->view()->contentsToWindow(rect); +} + +void WebPage::getSelectedText(String& text) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange(); + text = selectedRange->text(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebProcess.cpp b/Source/WebKit2/WebProcess/WebProcess.cpp new file mode 100644 index 0000000..47f4125 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcess.cpp @@ -0,0 +1,659 @@ +/* + * Copyright (C) 2009, 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 "WebProcess.h" + +#include "AuthenticationManager.h" +#include "DownloadManager.h" +#include "InjectedBundle.h" +#include "InjectedBundleMessageKinds.h" +#include "InjectedBundleUserMessageCoders.h" +#include "RunLoop.h" +#include "SandboxExtension.h" +#include "WebContextMessages.h" +#include "WebCoreArgumentCoders.h" +#include "WebDatabaseManager.h" +#include "WebFrame.h" +#include "WebGeolocationManagerMessages.h" +#include "WebMemorySampler.h" +#include "WebPage.h" +#include "WebPageCreationParameters.h" +#include "WebPlatformStrategies.h" +#include "WebPreferencesStore.h" +#include "WebProcessCreationParameters.h" +#include "WebProcessMessages.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/ApplicationCacheStorage.h> +#include <WebCore/CrossOriginPreflightResultCache.h> +#include <WebCore/Font.h> +#include <WebCore/Language.h> +#include <WebCore/Page.h> +#include <WebCore/PageGroup.h> +#include <WebCore/SchemeRegistry.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/Settings.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RandomNumber.h> + +#ifndef NDEBUG +#include <WebCore/MemoryCache.h> +#include <WebCore/GCController.h> +#endif + +#if !OS(WINDOWS) +#include <unistd.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +#if OS(WINDOWS) +static void sleep(unsigned seconds) +{ + ::Sleep(seconds * 1000); +} +#endif + +static void* randomCrashThread(void*) +{ + // This delay was chosen semi-arbitrarily. We want the crash to happen somewhat quickly to + // enable useful stress testing, but not so quickly that the web process will always crash soon + // after launch. + static const unsigned maximumRandomCrashDelay = 180; + + sleep(randomNumber() * maximumRandomCrashDelay); + CRASH(); + return 0; +} + +static void startRandomCrashThreadIfRequested() +{ + if (!getenv("WEBKIT2_CRASH_WEB_PROCESS_RANDOMLY")) + return; + createThread(randomCrashThread, 0, "WebKit2: Random Crash Thread"); +} + +WebProcess& WebProcess::shared() +{ + static WebProcess& process = *new WebProcess; + return process; +} + +WebProcess::WebProcess() + : m_inDidClose(false) + , m_hasSetCacheModel(false) + , m_cacheModel(CacheModelDocumentViewer) +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + , m_compositingRenderServerPort(MACH_PORT_NULL) +#endif +#if PLATFORM(QT) + , m_networkAccessManager(0) +#endif + , m_textCheckerState() + , m_geolocationManager(this) +{ +#if USE(PLATFORM_STRATEGIES) + // Initialize our platform strategies. + WebPlatformStrategies::initialize(); +#endif // USE(PLATFORM_STRATEGIES) + +#if ENABLE(DATABASE) + // Make sure the WebDatabaseManager is initialized so that the Database directory is set. + WebDatabaseManager::shared(); +#endif +} + +void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop) +{ + ASSERT(!m_connection); + + m_connection = CoreIPC::Connection::createClientConnection(serverIdentifier, this, runLoop); + m_connection->open(); + + m_runLoop = runLoop; + + startRandomCrashThreadIfRequested(); +} + +void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments) +{ + ASSERT(m_pageMap.isEmpty()); + + platformInitializeWebProcess(parameters, arguments); + + RefPtr<APIObject> injectedBundleInitializationUserData; + InjectedBundleUserMessageDecoder messageDecoder(injectedBundleInitializationUserData); + if (!arguments->decode(messageDecoder)) + return; + + if (!parameters.injectedBundlePath.isEmpty()) { + m_injectedBundle = InjectedBundle::create(parameters.injectedBundlePath); + m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle)); + + if (!m_injectedBundle->load(injectedBundleInitializationUserData.get())) { + // Don't keep around the InjectedBundle reference if the load fails. + m_injectedBundle.clear(); + } + } + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + if (!parameters.applicationCacheDirectory.isEmpty()) + cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory); +#endif + + setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks); + setCacheModel(static_cast<uint32_t>(parameters.cacheModel)); + + if (!parameters.languageCode.isEmpty()) + overrideDefaultLanguage(parameters.languageCode); + + m_textCheckerState = parameters.textCheckerState; + + for (size_t i = 0; i < parameters.urlSchemesRegistererdAsEmptyDocument.size(); ++i) + registerURLSchemeAsEmptyDocument(parameters.urlSchemesRegistererdAsEmptyDocument[i]); + + for (size_t i = 0; i < parameters.urlSchemesRegisteredAsSecure.size(); ++i) + registerURLSchemeAsSecure(parameters.urlSchemesRegisteredAsSecure[i]); + + for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i) + setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]); + + for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i) + m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]); + + if (parameters.clearResourceCaches) + clearResourceCaches(); + if (parameters.clearApplicationCache) + clearApplicationCache(); + +#if PLATFORM(MAC) + m_presenterApplicationPid = parameters.presenterApplicationPid; +#endif + + if (parameters.shouldAlwaysUseComplexTextCodePath) + setAlwaysUsesComplexTextCodePath(true); +} + +void WebProcess::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks) +{ + PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks); +} + +void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme) +{ + SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme); +} + +void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const +{ + SchemeRegistry::registerURLSchemeAsSecure(urlScheme); +} + +void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const +{ + SecurityOrigin::setDomainRelaxationForbiddenForURLScheme(true, urlScheme); +} + +void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) +{ + Font::setCodePath(alwaysUseComplexText ? Font::Complex : Font::Auto); +} + +void WebProcess::languageChanged(const String& language) const +{ + overrideDefaultLanguage(language); +} + +void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle) +{ + RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); + if (!sharedMemory) + return; + + m_visitedLinkTable.setSharedMemory(sharedMemory.release()); +} + +PageGroup* WebProcess::sharedPageGroup() +{ + return PageGroup::pageGroup("WebKit2Group"); +} + +void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes) +{ + for (size_t i = 0; i < linkHashes.size(); ++i) + Page::visitedStateChanged(sharedPageGroup(), linkHashes[i]); +} + +void WebProcess::allVisitedLinkStateChanged() +{ + Page::allVisitedStateChanged(sharedPageGroup()); +} + +bool WebProcess::isLinkVisited(LinkHash linkHash) const +{ + return m_visitedLinkTable.isLinkVisited(linkHash); +} + +void WebProcess::addVisitedLink(WebCore::LinkHash linkHash) +{ + if (isLinkVisited(linkHash)) + return; + m_connection->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0); +} + +void WebProcess::setCacheModel(uint32_t cm) +{ + CacheModel cacheModel = static_cast<CacheModel>(cm); + + if (!m_hasSetCacheModel || cacheModel != m_cacheModel) { + m_hasSetCacheModel = true; + m_cacheModel = cacheModel; + platformSetCacheModel(cacheModel); + } +} + +void WebProcess::calculateCacheSizes(CacheModel cacheModel, uint64_t memorySize, uint64_t diskFreeSize, + unsigned& cacheTotalCapacity, unsigned& cacheMinDeadCapacity, unsigned& cacheMaxDeadCapacity, double& deadDecodedDataDeletionInterval, + unsigned& pageCacheCapacity, unsigned long& urlCacheMemoryCapacity, unsigned long& urlCacheDiskCapacity) +{ + switch (cacheModel) { + case CacheModelDocumentViewer: { + // Page cache capacity (in pages) + pageCacheCapacity = 0; + + // Object cache capacities (in bytes) + if (memorySize >= 2048) + cacheTotalCapacity = 96 * 1024 * 1024; + else if (memorySize >= 1536) + cacheTotalCapacity = 64 * 1024 * 1024; + else if (memorySize >= 1024) + cacheTotalCapacity = 32 * 1024 * 1024; + else if (memorySize >= 512) + cacheTotalCapacity = 16 * 1024 * 1024; + + cacheMinDeadCapacity = 0; + cacheMaxDeadCapacity = 0; + + // Foundation memory cache capacity (in bytes) + urlCacheMemoryCapacity = 0; + + // Foundation disk cache capacity (in bytes) + urlCacheDiskCapacity = 0; + + break; + } + case CacheModelDocumentBrowser: { + // Page cache capacity (in pages) + if (memorySize >= 1024) + pageCacheCapacity = 3; + else if (memorySize >= 512) + pageCacheCapacity = 2; + else if (memorySize >= 256) + pageCacheCapacity = 1; + else + pageCacheCapacity = 0; + + // Object cache capacities (in bytes) + if (memorySize >= 2048) + cacheTotalCapacity = 96 * 1024 * 1024; + else if (memorySize >= 1536) + cacheTotalCapacity = 64 * 1024 * 1024; + else if (memorySize >= 1024) + cacheTotalCapacity = 32 * 1024 * 1024; + else if (memorySize >= 512) + cacheTotalCapacity = 16 * 1024 * 1024; + + cacheMinDeadCapacity = cacheTotalCapacity / 8; + cacheMaxDeadCapacity = cacheTotalCapacity / 4; + + // Foundation memory cache capacity (in bytes) + if (memorySize >= 2048) + urlCacheMemoryCapacity = 4 * 1024 * 1024; + else if (memorySize >= 1024) + urlCacheMemoryCapacity = 2 * 1024 * 1024; + else if (memorySize >= 512) + urlCacheMemoryCapacity = 1 * 1024 * 1024; + else + urlCacheMemoryCapacity = 512 * 1024; + + // Foundation disk cache capacity (in bytes) + if (diskFreeSize >= 16384) + urlCacheDiskCapacity = 50 * 1024 * 1024; + else if (diskFreeSize >= 8192) + urlCacheDiskCapacity = 40 * 1024 * 1024; + else if (diskFreeSize >= 4096) + urlCacheDiskCapacity = 30 * 1024 * 1024; + else + urlCacheDiskCapacity = 20 * 1024 * 1024; + + break; + } + case CacheModelPrimaryWebBrowser: { + // Page cache capacity (in pages) + // (Research indicates that value / page drops substantially after 3 pages.) + if (memorySize >= 2048) + pageCacheCapacity = 5; + else if (memorySize >= 1024) + pageCacheCapacity = 4; + else if (memorySize >= 512) + pageCacheCapacity = 3; + else if (memorySize >= 256) + pageCacheCapacity = 2; + else + pageCacheCapacity = 1; + + // Object cache capacities (in bytes) + // (Testing indicates that value / MB depends heavily on content and + // browsing pattern. Even growth above 128MB can have substantial + // value / MB for some content / browsing patterns.) + if (memorySize >= 2048) + cacheTotalCapacity = 128 * 1024 * 1024; + else if (memorySize >= 1536) + cacheTotalCapacity = 96 * 1024 * 1024; + else if (memorySize >= 1024) + cacheTotalCapacity = 64 * 1024 * 1024; + else if (memorySize >= 512) + cacheTotalCapacity = 32 * 1024 * 1024; + + cacheMinDeadCapacity = cacheTotalCapacity / 4; + cacheMaxDeadCapacity = cacheTotalCapacity / 2; + + // This code is here to avoid a PLT regression. We can remove it if we + // can prove that the overall system gain would justify the regression. + cacheMaxDeadCapacity = std::max(24u, cacheMaxDeadCapacity); + + deadDecodedDataDeletionInterval = 60; + + // Foundation memory cache capacity (in bytes) + // (These values are small because WebCore does most caching itself.) + if (memorySize >= 1024) + urlCacheMemoryCapacity = 4 * 1024 * 1024; + else if (memorySize >= 512) + urlCacheMemoryCapacity = 2 * 1024 * 1024; + else if (memorySize >= 256) + urlCacheMemoryCapacity = 1 * 1024 * 1024; + else + urlCacheMemoryCapacity = 512 * 1024; + + // Foundation disk cache capacity (in bytes) + if (diskFreeSize >= 16384) + urlCacheDiskCapacity = 175 * 1024 * 1024; + else if (diskFreeSize >= 8192) + urlCacheDiskCapacity = 150 * 1024 * 1024; + else if (diskFreeSize >= 4096) + urlCacheDiskCapacity = 125 * 1024 * 1024; + else if (diskFreeSize >= 2048) + urlCacheDiskCapacity = 100 * 1024 * 1024; + else if (diskFreeSize >= 1024) + urlCacheDiskCapacity = 75 * 1024 * 1024; + else + urlCacheDiskCapacity = 50 * 1024 * 1024; + + break; + } + default: + ASSERT_NOT_REACHED(); + }; +} + +WebPage* WebProcess::webPage(uint64_t pageID) const +{ + return m_pageMap.get(pageID).get(); +} + +void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters) +{ + // It is necessary to check for page existence here since during a window.open() (or targeted + // link) the WebPage gets created both in the synchronous handler and through the normal way. + std::pair<HashMap<uint64_t, RefPtr<WebPage> >::iterator, bool> result = m_pageMap.add(pageID, 0); + if (result.second) { + ASSERT(!result.first->second); + result.first->second = WebPage::create(pageID, parameters); + } + + ASSERT(result.first->second); +} + +void WebProcess::removeWebPage(uint64_t pageID) +{ + m_pageMap.remove(pageID); + + shutdownIfPossible(); +} + +bool WebProcess::isSeparateProcess() const +{ + // If we're running on the main run loop, we assume that we're in a separate process. + return m_runLoop == RunLoop::main(); +} + +void WebProcess::shutdownIfPossible() +{ + if (!m_pageMap.isEmpty()) + return; + + if (m_inDidClose) + return; + + if (DownloadManager::shared().isDownloading()) + return; + + // Keep running forever if we're running in the same process. + if (!isSeparateProcess()) + return; + + // Actually shut down the process. + +#ifndef NDEBUG + gcController().garbageCollectNow(); + memoryCache()->setDisabled(true); +#endif + + // Invalidate our connection. + m_connection->invalidate(); + m_connection = nullptr; + + platformShutdown(); + + m_runLoop->stop(); +} + +CoreIPC::SyncReplyMode WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply) +{ + uint64_t pageID = arguments->destinationID(); + if (!pageID) + return CoreIPC::AutomaticReply; + + WebPage* page = webPage(pageID); + if (!page) + return CoreIPC::AutomaticReply; + + page->didReceiveSyncMessage(connection, messageID, arguments, reply); + return CoreIPC::AutomaticReply; +} + +void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (messageID.is<CoreIPC::MessageClassWebProcess>()) { + didReceiveWebProcessMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassAuthenticationManager>()) { + AuthenticationManager::shared().didReceiveMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassWebDatabaseManager>()) { + WebDatabaseManager::shared().didReceiveMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassWebGeolocationManager>()) { + m_geolocationManager.didReceiveMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassInjectedBundle>()) { + if (!m_injectedBundle) + return; + m_injectedBundle->didReceiveMessage(connection, messageID, arguments); + return; + } + + uint64_t pageID = arguments->destinationID(); + if (!pageID) + return; + + WebPage* page = webPage(pageID); + if (!page) + return; + + page->didReceiveMessage(connection, messageID, arguments); +} + +void WebProcess::didClose(CoreIPC::Connection*) +{ + // When running in the same process the connection will never be closed. + ASSERT(isSeparateProcess()); + +#ifndef NDEBUG + m_inDidClose = true; + + // Close all the live pages. + Vector<RefPtr<WebPage> > pages; + copyValuesToVector(m_pageMap, pages); + for (size_t i = 0; i < pages.size(); ++i) + pages[i]->close(); + pages.clear(); + + gcController().garbageCollectNow(); + memoryCache()->setDisabled(true); +#endif + + // The UI process closed this connection, shut down. + m_runLoop->stop(); +} + +void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID) +{ + // We received an invalid message, but since this is from the UI process (which we trust), + // we'll let it slide. +} + +WebFrame* WebProcess::webFrame(uint64_t frameID) const +{ + return m_frameMap.get(frameID); +} + +void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame) +{ + m_frameMap.set(frameID, frame); +} + +void WebProcess::removeWebFrame(uint64_t frameID) +{ + m_frameMap.remove(frameID); + + // We can end up here after our connection has closed when WebCore's frame life-support timer + // fires when the application is shutting down. There's no need (and no way) to update the UI + // process in this case. + if (!m_connection) + return; + + m_connection->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0); +} + +WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID) +{ + return m_pageGroupMap.get(pageGroupID).get(); +} + +WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData) +{ + std::pair<HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::iterator, bool> result = m_pageGroupMap.add(pageGroupData.pageGroupID, 0); + if (result.second) { + ASSERT(!result.first->second); + result.first->second = WebPageGroupProxy::create(pageGroupData); + } + + return result.first->second.get(); +} + +void WebProcess::clearResourceCaches() +{ + platformClearResourceCaches(); + + // Toggling the cache model like this forces the cache to evict all its in-memory resources. + // FIXME: We need a better way to do this. + CacheModel cacheModel = m_cacheModel; + setCacheModel(CacheModelDocumentViewer); + setCacheModel(cacheModel); + + // Empty the cross-origin preflight cache. + CrossOriginPreflightResultCache::shared().empty(); +} + +void WebProcess::clearApplicationCache() +{ +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + // Empty the application cache. + cacheStorage().empty(); +#endif +} + +void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request) +{ + WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0; + + DownloadManager::shared().startDownload(downloadID, initiatingPage, request); +} + +void WebProcess::cancelDownload(uint64_t downloadID) +{ + DownloadManager::shared().cancelDownload(downloadID); +} + +void WebProcess::startMemorySampler(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval) +{ +#if ENABLE(MEMORY_SAMPLER) + WebMemorySampler::shared()->start(sampleLogFileHandle, sampleLogFilePath, interval); +#endif +} + +void WebProcess::stopMemorySampler() +{ +#if ENABLE(MEMORY_SAMPLER) + WebMemorySampler::shared()->stop(); +#endif +} + +void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState) +{ + m_textCheckerState = textCheckerState; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebProcess.h b/Source/WebKit2/WebProcess/WebProcess.h new file mode 100644 index 0000000..e82cf15 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcess.h @@ -0,0 +1,199 @@ +/* + * 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. + */ + +#ifndef WebProcess_h +#define WebProcess_h + +#include "CacheModel.h" +#include "ChildProcess.h" +#include "DrawingArea.h" +#include "SandboxExtension.h" +#include "SharedMemory.h" +#include "TextCheckerState.h" +#include "VisitedLinkTable.h" +#include "WebGeolocationManager.h" +#include "WebPageGroupProxy.h" +#include <WebCore/LinkHash.h> +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> + +#if PLATFORM(MAC) +#include "MachPort.h" +#endif + +#if PLATFORM(QT) +class QNetworkAccessManager; +#endif + +namespace WebCore { + class IntSize; + class PageGroup; + class ResourceRequest; +} + +namespace WebKit { + +class InjectedBundle; +class WebFrame; +class WebPage; +struct WebPageCreationParameters; +struct WebPageGroupData; +struct WebPreferencesStore; +struct WebProcessCreationParameters; + +class WebProcess : ChildProcess { +public: + static WebProcess& shared(); + + void initialize(CoreIPC::Connection::Identifier, RunLoop* runLoop); + + CoreIPC::Connection* connection() const { return m_connection.get(); } + RunLoop* runLoop() const { return m_runLoop; } + + WebPage* webPage(uint64_t pageID) const; + void createWebPage(uint64_t pageID, const WebPageCreationParameters&); + void removeWebPage(uint64_t pageID); + + InjectedBundle* injectedBundle() const { return m_injectedBundle.get(); } + + bool isSeparateProcess() const; + +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + mach_port_t compositingRenderServerPort() const { return m_compositingRenderServerPort; } +#endif + + void addVisitedLink(WebCore::LinkHash); + bool isLinkVisited(WebCore::LinkHash) const; + + WebFrame* webFrame(uint64_t) const; + void addWebFrame(uint64_t, WebFrame*); + void removeWebFrame(uint64_t); + + WebPageGroupProxy* webPageGroup(uint64_t pageGroupID); + WebPageGroupProxy* webPageGroup(const WebPageGroupData&); + static WebCore::PageGroup* sharedPageGroup(); +#if PLATFORM(MAC) + pid_t presenterApplicationPid() const { return m_presenterApplicationPid; } +#endif + +#if PLATFORM(QT) + QNetworkAccessManager* networkAccessManager() { return m_networkAccessManager; } +#endif + + // Will shut down the web process if there are no live pages or downloads. + void shutdownIfPossible(); + + bool shouldUseCustomRepresentationForMIMEType(const String& mimeType) const { return m_mimeTypesWithCustomRepresentations.contains(mimeType); } + + // Text Checking + const TextCheckerState& textCheckerState() const { return m_textCheckerState; } + + // Geolocation + WebGeolocationManager& geolocationManager() { return m_geolocationManager; } + +private: + WebProcess(); + + void initializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*); + void platformInitializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*); + void platformShutdown(); + void setShouldTrackVisitedLinks(bool); + void registerURLSchemeAsEmptyDocument(const String&); + void registerURLSchemeAsSecure(const String&) const; + void setDomainRelaxationForbiddenForURLScheme(const String&) const; + void setAlwaysUsesComplexTextCodePath(bool); + void languageChanged(const String&) const; +#if PLATFORM(WIN) + void setShouldPaintNativeControls(bool); +#endif + + void setVisitedLinkTable(const SharedMemory::Handle&); + void visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes); + void allVisitedLinkStateChanged(); + + void setCacheModel(uint32_t); + void platformSetCacheModel(CacheModel); + static void calculateCacheSizes(CacheModel cacheModel, uint64_t memorySize, uint64_t diskFreeSize, + unsigned& cacheTotalCapacity, unsigned& cacheMinDeadCapacity, unsigned& cacheMaxDeadCapacity, double& deadDecodedDataDeletionInterval, + unsigned& pageCacheCapacity, unsigned long& urlCacheMemoryCapacity, unsigned long& urlCacheDiskCapacity); + void clearResourceCaches(); + void platformClearResourceCaches(); + void clearApplicationCache(); + + void startMemorySampler(const SandboxExtension::Handle&, const String&, const double); + void stopMemorySampler(); + + void downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const WebCore::ResourceRequest&); + void cancelDownload(uint64_t downloadID); + + void setTextCheckerState(const TextCheckerState&); + + // CoreIPC::Connection::Client + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + void didClose(CoreIPC::Connection*); + void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + + // Implemented in generated WebProcessMessageReceiver.cpp + void didReceiveWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + RefPtr<CoreIPC::Connection> m_connection; + HashMap<uint64_t, RefPtr<WebPage> > m_pageMap; + HashMap<uint64_t, RefPtr<WebPageGroupProxy> > m_pageGroupMap; + RefPtr<InjectedBundle> m_injectedBundle; + + bool m_inDidClose; + + RunLoop* m_runLoop; + + // FIXME: The visited link table should not be per process. + VisitedLinkTable m_visitedLinkTable; + + bool m_hasSetCacheModel; + CacheModel m_cacheModel; + +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + mach_port_t m_compositingRenderServerPort; +#endif +#if PLATFORM(MAC) + pid_t m_presenterApplicationPid; +#endif + +#if PLATFORM(QT) + QNetworkAccessManager* m_networkAccessManager; +#endif + + HashMap<uint64_t, WebFrame*> m_frameMap; + + HashSet<String, CaseFoldingHash> m_mimeTypesWithCustomRepresentations; + + TextCheckerState m_textCheckerState; + WebGeolocationManager m_geolocationManager; +}; + +} // namespace WebKit + +#endif // WebProcess_h diff --git a/Source/WebKit2/WebProcess/WebProcess.messages.in b/Source/WebKit2/WebProcess/WebProcess.messages.in new file mode 100644 index 0000000..2ea9237 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcess.messages.in @@ -0,0 +1,59 @@ +# 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. + +messages -> WebProcess { + # Initialize the WebProcess. + InitializeWebProcess(WebKit::WebProcessCreationParameters processCreationParameters, WebKit::WebContextUserMessageEncoder initializationUserData) + + # Create a new page. + CreateWebPage(uint64_t newPageID, WebKit::WebPageCreationParameters pageCreationParameters) + + # Visited link tracking. + SetVisitedLinkTable(WebKit::SharedMemory::Handle handle) + VisitedLinkStateChanged(Vector<WebCore::LinkHash> linkHashes) + AllVisitedLinkStateChanged() + + # Global preferences. + SetShouldTrackVisitedLinks(bool shouldTrackVisitedLinks) + SetCacheModel(uint32_t cacheModel) + RegisterURLSchemeAsEmptyDocument(WTF::String scheme) + RegisterURLSchemeAsSecure(WTF::String scheme) + SetDomainRelaxationForbiddenForURLScheme(WTF::String scheme) + SetAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) + LanguageChanged(WTF::String language) +#if PLATFORM(WIN) + SetShouldPaintNativeControls(bool shouldPaintNativeControls) +#endif + + ClearResourceCaches(); + ClearApplicationCache(); + + void StartMemorySampler(WebKit::SandboxExtension::Handle sampleLogFileHandle, WTF::String sampleLogFilePath, double interval); + void StopMemorySampler(); + + # Downloads. This should really be in a Download.messages.in, but it seemed unnecessary to create a new file just for + # two messages. + void DownloadRequest(uint64_t downloadID, uint64_t initiatingPageID, WebCore::ResourceRequest request) + CancelDownload(uint64_t downloadID) + + SetTextCheckerState(WebKit::TextCheckerState textCheckerState) +} diff --git a/Source/WebKit2/WebProcess/WebProcessMain.h b/Source/WebKit2/WebProcess/WebProcessMain.h new file mode 100644 index 0000000..a287d63 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcessMain.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef WebProcessMain_h +#define WebProcessMain_h + +#include "WKBase.h" + +namespace WebKit { + +class CommandLine; + +int WebProcessMain(const CommandLine&); + +} // namespace WebKit + +#endif // WebProcessMain_h diff --git a/Source/WebKit2/WebProcess/com.apple.WebProcess.sb b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb new file mode 100644 index 0000000..2123c95 --- /dev/null +++ b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb @@ -0,0 +1,129 @@ +(version 1) +(deny default (with partial-symbolication)) +(allow ipc-posix-shm system-audit system-socket file-read-metadata) + +(import "system.sb") + +;; Read-only preferences and data +(allow file-read* + ;; Basic system paths + (subpath "/Library/Fonts") + (subpath "/Library/Frameworks") + (subpath "/Library/Keychains") + (subpath "/private/var/db/mds") + (regex #"^/private/etc/(hosts|group|passwd)$") + + ;; Plugins + (subpath "/Library/Internet Plug-Ins") + (subpath (string-append (param "_HOME") "/Library/Internet Plug-Ins")) + + ;; System and user preferences + (literal "/Library/Preferences/.GlobalPreferences.plist") + (literal "/Library/Preferences/com.apple.security.plist") + (literal (string-append (param "_HOME") "/Library/Preferences/.GlobalPreferences.plist")) + (regex (string-append "^" (param "_HOME") "/Library/Preferences/ByHost/\.GlobalPreferences\.")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.ATS.plist")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.HIToolbox.plist")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.LaunchServices.plist")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.WebFoundation.plist")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.security.plist")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.security.revocation.plist")) + (subpath (string-append (param "_HOME") "/Library/Keychains")) + + ;; On-disk WebKit2 framework location, to account for debug installations + ;; outside of /System/Library/Frameworks + (subpath (param "WEBKIT2_FRAMEWORK_DIR")) + + ;; Extensions from UIProcess + (extension) +) + +(allow file-write* + ;; Extensions from UIProcess + (extension) +) + +;; Writable preferences and temporary files +(allow file* + (subpath (string-append (param "_HOME") "/Library/Caches/com.apple.WebProcess")) + (regex (string-append "^" (param "_HOME") "/Library/Preferences/ByHost/com\.apple\.HIToolbox\.")) + (regex (string-append "^" (param "_HOME") "/Library/Preferences/com\.apple\.WebProcess\.")) +) + +;; Darwin temporary files and caches, if present +(if (positive? (string-length (param "DARWIN_USER_CACHE_DIR"))) + (allow file* (subpath (param "DARWIN_USER_CACHE_DIR")))) +(if (positive? (string-length (param "DARWIN_USER_TEMP_DIR"))) + (allow file* (subpath (param "DARWIN_USER_TEMP_DIR")))) + +;; The NSURLCache directory. +(if (positive? (string-length (param "NSURL_CACHE_DIR"))) + (allow file* (subpath (param "NSURL_CACHE_DIR")))) + +;; The bundle resource path of the UI process. +(if (positive? (string-length (param "UI_PROCESS_BUNDLE_RESOURCE_DIR"))) + (allow file-read* (subpath (param "UI_PROCESS_BUNDLE_RESOURCE_DIR")))) + +;; FIXME: overly permissive since we can't pre-enumerate the client +;; classes for graphics cards +(allow iokit-open + ;;(iokit-user-client-class "IOHIDParamUserClient") + ;;(iokit-user-client-class "RootDomainUserClient") +) + +;; Various services required by AppKit and other frameworks +(allow mach-lookup + (global-name "com.apple.CoreServices.coreservicesd") + (global-name "com.apple.DiskArbitration.diskarbitrationd") + (global-name "com.apple.FileCoordination") + (global-name "com.apple.FontObjectsServer") + (global-name "com.apple.FontServer") + (global-name "com.apple.SecurityServer") + (global-name "com.apple.SystemConfiguration.configd") + (global-name "com.apple.audio.VDCAssistant") + (global-name "com.apple.audio.audiohald") + (global-name "com.apple.audio.coreaudiod") + (global-name "com.apple.cookied") + (global-name "com.apple.cvmsServ") + (global-name "com.apple.distributed_notifications.2") + (global-name "com.apple.dock.server") + (global-name "com.apple.ocspd") + (global-name "com.apple.pasteboard.1") + (global-name "com.apple.window_proxies") + (global-name "com.apple.windowserver.active") + (global-name-regex #"^com\.apple\.WebKit\.WebProcess-") + (global-name-regex #"^com\.apple\.qtkitserver\.") +) + +;; FIXME: These rules are required until <rdar://problem/8448410> is addressed. See <rdar://problem/8349882> for discussion. +(allow network-outbound) +(deny network-outbound (regex "")) +(deny network-outbound (local ip)) +(allow network-outbound + ;; Local mDNSResponder for DNS, arbitrary outbound TCP + (literal "/private/var/run/mDNSResponder") + (remote tcp) +) + +;; FIXME: These rules are required until plug-ins are moved out of the web process. +(allow file-read* + (regex (string-append "^" (param "_HOME") "/Library/Preferences/ByHost/com\.apple\.ist\.")) + (literal (string-append (param "_HOME") "/Library/Preferences/edu.mit.Kerberos")) + (literal "/Library/Preferences/edu.mit.Kerberos") +) + +(allow mach-lookup + (global-name "org.h5l.kcm") + (global-name "com.apple.tsm.uiserver") + (global-name-regex #"^com\.apple\.ist") +) + +(allow network-outbound (remote ip)) + +;; These rules are required while QTKitServer is being launched directly via posix_spawn (<rdar://problem/6912494>). +(allow process-fork) +(allow process-exec (literal "/System/Library/Frameworks/QTKit.framework/Versions/A/Resources/QTKitServer") (with no-sandbox)) + +;; FIXME: Investigate these. +(allow appleevent-send (appleevent-destination "com.apple.WebProcess")) +(allow mach-lookup (global-name-regex #"^EPPC-")) diff --git a/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp b/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp new file mode 100644 index 0000000..4c26c08 --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2011 Motorola Mobility, 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 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 "WebProcess.h" + +#include "NotImplemented.h" +#include "WebProcessCreationParameters.h" + +namespace WebKit { + +void WebProcess::platformSetCacheModel(CacheModel) +{ + notImplemented(); +} + +void WebProcess::platformClearResourceCaches() +{ + notImplemented(); +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*) +{ + notImplemented(); +} + +void WebProcess::platformShutdown() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp b/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp new file mode 100644 index 0000000..dcac73f --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 "WebProcessMainGtk.h" + +#include "WKBase.h" +#include <WebCore/ResourceHandle.h> +#include <WebKit2/RunLoop.h> +#include <WebKit2/WebProcess.h> +#include <gtk/gtk.h> +#include <runtime/InitializeThreading.h> +#include <unistd.h> +#include <wtf/Threading.h> + +namespace WebKit { + +WK_EXPORT int WebProcessMainGtk(int argc, char* argv[]) +{ + ASSERT(argc == 2); + +#ifndef NDEBUG + if (g_getenv("WEBKIT2_PAUSE_WEB_PROCESS_ON_LAUNCH")) + sleep(30); +#endif + + gtk_init(&argc, &argv); + g_type_init(); + + JSC::initializeThreading(); + WTF::initializeMainThread(); + + RunLoop::initializeMainRunLoop(); + WebCore::ResourceHandle::defaultSession(); + + int socket = atoi(argv[1]); + WebProcess::shared().initialize(socket, RunLoop::main()); + RunLoop::run(); + + return 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.h b/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.h new file mode 100644 index 0000000..828af83 --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, 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 WebProcessMainGtk_h +#define WebProcessMainGtk_h + +#include <WebKit2/WKBase.h> + +namespace WebKit { + +#ifdef __cplusplus +extern "C" { +WK_EXPORT int WebProcessMainGtk(int argc, char* argv[]); +} // extern "C" +#endif // __cplusplus + +} // namespace WebKit + +#endif // WebProcessMain_h diff --git a/Source/WebKit2/WebProcess/mac/WebProcessMac.mm b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm new file mode 100644 index 0000000..c899fcb --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm @@ -0,0 +1,170 @@ +/* + * 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 "WebProcess.h" + +#include "SandboxExtension.h" +#include "WebProcessCreationParameters.h" +#include <WebCore/MemoryCache.h> +#include <WebCore/PageCache.h> +#include <WebKitSystemInterface.h> +#include <algorithm> +#include <dispatch/dispatch.h> +#include <mach/host_info.h> +#include <mach/mach.h> +#include <mach/mach_error.h> + +#if ENABLE(WEB_PROCESS_SANDBOX) +#include <sandbox.h> +#include <stdlib.h> +#include <sysexits.h> +#endif + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +static uint64_t memorySize() +{ + static host_basic_info_data_t hostInfo; + + static dispatch_once_t once; + dispatch_once(&once, ^() { + mach_port_t host = mach_host_self(); + mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; + kern_return_t r = host_info(host, HOST_BASIC_INFO, (host_info_t)&hostInfo, &count); + mach_port_deallocate(mach_task_self(), host); + + if (r != KERN_SUCCESS) + LOG_ERROR("%s : host_info(%d) : %s.\n", __FUNCTION__, r, mach_error_string(r)); + }); + + return hostInfo.max_mem; +} + +static uint64_t volumeFreeSize(NSString *path) +{ + NSDictionary *fileSystemAttributesDictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:path error:NULL]; + return [[fileSystemAttributesDictionary objectForKey:NSFileSystemFreeSize] unsignedLongLongValue]; +} + +void WebProcess::platformSetCacheModel(CacheModel cacheModel) +{ + RetainPtr<NSString> nsurlCacheDirectory(AdoptNS, (NSString *)WKCopyFoundationCacheDirectory()); + if (!nsurlCacheDirectory) + nsurlCacheDirectory.adoptNS(NSHomeDirectory()); + + // As a fudge factor, use 1000 instead of 1024, in case the reported byte + // count doesn't align exactly to a megabyte boundary. + uint64_t memSize = memorySize() / 1024 / 1000; + uint64_t diskFreeSize = volumeFreeSize(nsurlCacheDirectory.get()) / 1024 / 1000; + + unsigned cacheTotalCapacity = 0; + unsigned cacheMinDeadCapacity = 0; + unsigned cacheMaxDeadCapacity = 0; + double deadDecodedDataDeletionInterval = 0; + unsigned pageCacheCapacity = 0; + unsigned long urlCacheMemoryCapacity = 0; + unsigned long urlCacheDiskCapacity = 0; + + calculateCacheSizes(cacheModel, memSize, diskFreeSize, + cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, + pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity); + + + memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); + memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); + pageCache()->setCapacity(pageCacheCapacity); + + NSURLCache *nsurlCache = [NSURLCache sharedURLCache]; + [nsurlCache setMemoryCapacity:urlCacheMemoryCapacity]; + [nsurlCache setDiskCapacity:max<unsigned long>(urlCacheDiskCapacity, [nsurlCache diskCapacity])]; // Don't shrink a big disk cache, since that would cause churn. +} + +void WebProcess::platformClearResourceCaches() +{ + [[NSURLCache sharedURLCache] removeAllCachedResponses]; +} + +static void initializeSandbox(const WebProcessCreationParameters& parameters) +{ +#if ENABLE(WEB_PROCESS_SANDBOX) + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DisableSandbox"]) { + fprintf(stderr, "Bypassing sandbox due to DisableSandbox user default.\n"); + return; + } + + char* errorBuf; + char tmpPath[PATH_MAX]; + char tmpRealPath[PATH_MAX]; + char cachePath[PATH_MAX]; + char cacheRealPath[PATH_MAX]; + const char* frameworkPath = [[[[NSBundle bundleForClass:NSClassFromString(@"WKView")] bundlePath] stringByDeletingLastPathComponent] UTF8String]; + const char* profilePath = [[[NSBundle mainBundle] pathForResource:@"com.apple.WebProcess" ofType:@"sb"] UTF8String]; + + if (confstr(_CS_DARWIN_USER_TEMP_DIR, tmpPath, PATH_MAX) <= 0 || !realpath(tmpPath, tmpRealPath)) + tmpRealPath[0] = '\0'; + + if (confstr(_CS_DARWIN_USER_CACHE_DIR, cachePath, PATH_MAX) <= 0 || !realpath(cachePath, cacheRealPath)) + cacheRealPath[0] = '\0'; + + const char* const sandboxParam[] = { + "WEBKIT2_FRAMEWORK_DIR", frameworkPath, + "DARWIN_USER_TEMP_DIR", (const char*)tmpRealPath, + "DARWIN_USER_CACHE_DIR", (const char*)cacheRealPath, + "NSURL_CACHE_DIR", (const char*)parameters.nsURLCachePath.data(), + "UI_PROCESS_BUNDLE_RESOURCE_DIR", (const char*)parameters.uiProcessBundleResourcePath.data(), + NULL + }; + + if (sandbox_init_with_parameters(profilePath, SANDBOX_NAMED_EXTERNAL, sandboxParam, &errorBuf)) { + fprintf(stderr, "WebProcess: couldn't initialize sandbox profile [%s] with framework path [%s], tmp path [%s], cache path [%s]: %s\n", profilePath, frameworkPath, tmpRealPath, cacheRealPath, errorBuf); + exit(EX_NOPERM); + } +#endif +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*) +{ + initializeSandbox(parameters); + + if (!parameters.nsURLCachePath.isNull()) { + NSUInteger cacheMemoryCapacity = parameters.nsURLCacheMemoryCapacity; + NSUInteger cacheDiskCapacity = parameters.nsURLCacheDiskCapacity; + + NSString *nsCachePath = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:parameters.nsURLCachePath.data() length:parameters.nsURLCachePath.length()]; + RetainPtr<NSURLCache> parentProcessURLCache(AdoptNS, [[NSURLCache alloc] initWithMemoryCapacity:cacheMemoryCapacity diskCapacity:cacheDiskCapacity diskPath:nsCachePath]); + [NSURLCache setSharedURLCache:parentProcessURLCache.get()]; + } + + m_compositingRenderServerPort = parameters.acceleratedCompositingPort.port(); +} + +void WebProcess::platformShutdown() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/mac/WebProcessMainMac.mm b/Source/WebKit2/WebProcess/mac/WebProcessMainMac.mm new file mode 100644 index 0000000..5cefb59 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebProcessMainMac.mm @@ -0,0 +1,111 @@ +/* + * 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. + */ + +#import "WebProcessMain.h" + +#import "CommandLine.h" +#import "RunLoop.h" +#import "WebProcess.h" +#import "WebSystemInterface.h" +#import <WebKit2/WKView.h> +#import <WebKitSystemInterface.h> +#import <objc/objc-auto.h> +#import <runtime/InitializeThreading.h> +#import <servers/bootstrap.h> +#import <signal.h> +#import <stdio.h> +#import <sysexits.h> +#import <unistd.h> +#import <wtf/RetainPtr.h> +#import <wtf/Threading.h> +#import <wtf/text/CString.h> + +// FIXME: We should be doing this another way. +extern "C" kern_return_t bootstrap_look_up2(mach_port_t, const name_t, mach_port_t*, pid_t, uint64_t); + +#define SHOW_CRASH_REPORTER 1 + +using namespace WebCore; + +namespace WebKit { + +int WebProcessMain(const CommandLine& commandLine) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + String serviceName = commandLine["servicename"]; + if (serviceName.isEmpty()) + return EXIT_FAILURE; + + // Get the server port. + mach_port_t serverPort; + kern_return_t kr = bootstrap_look_up2(bootstrap_port, serviceName.utf8().data(), &serverPort, 0, 0); + if (kr) { + printf("bootstrap_look_up2 result: %x", kr); + return 2; + } + +#if !SHOW_CRASH_REPORTER + // Installs signal handlers that exit on a crash so that CrashReporter does not show up. + signal(SIGILL, _exit); + signal(SIGFPE, _exit); + signal(SIGBUS, _exit); + signal(SIGSEGV, _exit); +#endif + + InitWebCoreSystemInterface(); + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + // Set the visible application name. + String parentProcessName = commandLine["parentprocessname"]; + if (!parentProcessName.isNull()) { + // FIXME: Localization! + NSString *applicationName = [NSString stringWithFormat:@"%@ Web Content", (NSString *)parentProcessName]; + WKSetVisibleApplicationName((CFStringRef)applicationName); + } + + // Create the connection. + WebProcess::shared().initialize(serverPort, RunLoop::main()); + + [pool drain]; + + // Initialize AppKit. + [NSApplication sharedApplication]; + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + WKAXRegisterRemoteApp(); +#endif + + RunLoop::run(); + + // FIXME: Do more cleanup here. + + return 0; +} + +} // namespace WebKit + diff --git a/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp b/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp new file mode 100644 index 0000000..bd4e370 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * + * 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 "RunLoop.h" +#include <runtime/InitializeThreading.h> +#include "WebProcess.h" +#include <wtf/Threading.h> + +#include <QApplication> +#include <QList> +#include <QNetworkProxyFactory> +#include <QString> +#include <QStringList> +#include <QUrl> +#include <QtGlobal> + +#if USE(MEEGOTOUCH) +#include <MComponentData> +#endif + +#ifndef NDEBUG +#if !OS(WINDOWS) +#include <unistd.h> +#endif +#endif + +#if !defined(QWEBKIT_EXPORT) +#if defined(QT_SHARED) +#define QWEBKIT_EXPORT Q_DECL_EXPORT +#else +#define QWEBKIT_EXPORT +#endif +#endif +#ifndef NDEBUG +#include <QDebug> +#endif + +using namespace WebCore; + +namespace WebKit { +#ifndef NDEBUG +#if OS(WINDOWS) +static void sleep(unsigned seconds) +{ + ::Sleep(seconds * 1000); +} +#endif +#endif + +class EnvHttpProxyFactory : public QNetworkProxyFactory +{ +public: + EnvHttpProxyFactory() { } + + bool initializeFromEnvironment(); + + QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery& query = QNetworkProxyQuery()); + +private: + QList<QNetworkProxy> m_httpProxy; + QList<QNetworkProxy> m_httpsProxy; +}; + +bool EnvHttpProxyFactory::initializeFromEnvironment() +{ + bool wasSetByEnvironment = false; + + QUrl proxyUrl = QUrl::fromUserInput(qgetenv("http_proxy")); + if (proxyUrl.isValid() && !proxyUrl.host().isEmpty()) { + int proxyPort = (proxyUrl.port() > 0) ? proxyUrl.port() : 8080; + m_httpProxy << QNetworkProxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyPort); + wasSetByEnvironment = true; + } else + m_httpProxy << QNetworkProxy::NoProxy; + + proxyUrl = QUrl::fromUserInput(qgetenv("https_proxy")); + if (proxyUrl.isValid() && !proxyUrl.host().isEmpty()) { + int proxyPort = (proxyUrl.port() > 0) ? proxyUrl.port() : 8080; + m_httpsProxy << QNetworkProxy(QNetworkProxy::HttpProxy, proxyUrl.host(), proxyPort); + wasSetByEnvironment = true; + } else + m_httpsProxy << QNetworkProxy::NoProxy; + + return wasSetByEnvironment; +} + +QList<QNetworkProxy> EnvHttpProxyFactory::queryProxy(const QNetworkProxyQuery& query) +{ + QString protocol = query.protocolTag().toLower(); + if (protocol == QLatin1String("http")) + return m_httpProxy; + else if (protocol == QLatin1String("https")) + return m_httpsProxy; + + QList<QNetworkProxy> proxies; + proxies << QNetworkProxy::NoProxy; + return proxies; +} + +static void initializeProxy() +{ + QList<QNetworkProxy> proxylist = QNetworkProxyFactory::systemProxyForQuery(); + if (proxylist.count() == 1) { + QNetworkProxy proxy = proxylist.first(); + if (proxy == QNetworkProxy::NoProxy || proxy == QNetworkProxy::DefaultProxy) { + EnvHttpProxyFactory* proxyFactory = new EnvHttpProxyFactory(); + if (proxyFactory->initializeFromEnvironment()) { + QNetworkProxyFactory::setApplicationProxyFactory(proxyFactory); + return; + } + } + } + QNetworkProxyFactory::setUseSystemConfiguration(true); +} + +QWEBKIT_EXPORT int WebProcessMainQt(int argc, char** argv) +{ + QApplication::setGraphicsSystem("raster"); + QApplication* app = new QApplication(argc, argv); +#ifndef NDEBUG + if (!qgetenv("WEBKIT2_PAUSE_WEB_PROCESS_ON_LAUNCH").isEmpty()) { + qDebug() << "Waiting 3 seconds for debugger"; + sleep(3); + } +#endif + +#if USE(MEEGOTOUCH) + new MComponentData(argc, argv); +#endif + + initializeProxy(); + + srandom(time(0)); + + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + // Create the connection. + QString identifier(app->arguments().size() > 1 ? app->arguments().at(1) : ""); + WebKit::WebProcess::shared().initialize(identifier, RunLoop::main()); + + RunLoop::run(); + + // FIXME: Do more cleanup here. + + return 0; +} + +} diff --git a/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp b/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp new file mode 100644 index 0000000..53a51d3 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp @@ -0,0 +1,63 @@ +/* + * 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 "WebProcess.h" + +#include "WebProcessCreationParameters.h" +#include <WebCore/RuntimeEnabledFeatures.h> +#include <QNetworkAccessManager> + +namespace WebKit { + +void WebProcess::platformSetCacheModel(CacheModel) +{ + // FIXME: Implement. +} + +void WebProcess::platformClearResourceCaches() +{ +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments) +{ + m_networkAccessManager = new QNetworkAccessManager; + + // Disable runtime enabled features that have no WebKit2 implementation yet. +#if ENABLE(DEVICE_ORIENTATION) + WebCore::RuntimeEnabledFeatures::setDeviceMotionEnabled(false); + WebCore::RuntimeEnabledFeatures::setDeviceOrientationEnabled(false); +#endif +#if ENABLE(SPEECH_INPUT) + WebCore::RuntimeEnabledFeatures::setSpeechInputEnabled(false); +#endif +} + +void WebProcess::platformShutdown() +{ + delete m_networkAccessManager; + m_networkAccessManager = 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/win/WebProcessMainWin.cpp b/Source/WebKit2/WebProcess/win/WebProcessMainWin.cpp new file mode 100644 index 0000000..944d8ff --- /dev/null +++ b/Source/WebKit2/WebProcess/win/WebProcessMainWin.cpp @@ -0,0 +1,84 @@ +/* + * 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 "WebProcessMain.h" + +#include "CommandLine.h" +#include "RunLoop.h" +#include "WebProcess.h" +#include <WebCore/SoftLinking.h> +#include <runtime/InitializeThreading.h> +#include <wtf/Threading.h> +#include <wtf/text/StringHash.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +#if USE(SAFARI_THEME) +#ifdef DEBUG_ALL +SOFT_LINK_DEBUG_LIBRARY(SafariTheme) +#else +SOFT_LINK_LIBRARY(SafariTheme) +#endif + +SOFT_LINK(SafariTheme, STInitialize, void, APIENTRY, (), ()) + +static void initializeSafariTheme() +{ + static bool didInitializeSafariTheme; + if (!didInitializeSafariTheme) { + if (SafariThemeLibrary()) + STInitialize(); + didInitializeSafariTheme = true; + } +} +#endif // USE(SAFARI_THEME) + +int WebProcessMain(const CommandLine& commandLine) +{ + ::OleInitialize(0); + +#if USE(SAFARI_THEME) + initializeSafariTheme(); +#endif + + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + const String& identifierString = commandLine["clientIdentifier"]; + + // FIXME: Should we return an error code here? + HANDLE clientIdentifier = reinterpret_cast<HANDLE>(identifierString.toUInt64Strict()); + if (!clientIdentifier) + return 0; + + WebProcess::shared().initialize(clientIdentifier, RunLoop::main()); + RunLoop::run(); + + return 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/win/WebProcessWin.cpp b/Source/WebKit2/WebProcess/win/WebProcessWin.cpp new file mode 100644 index 0000000..7f53cd3 --- /dev/null +++ b/Source/WebKit2/WebProcess/win/WebProcessWin.cpp @@ -0,0 +1,123 @@ +/* + * 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 "WebProcess.h" + +#include "WebProcessCreationParameters.h" +#include <WebCore/FileSystem.h> +#include <WebCore/MemoryCache.h> +#include <WebCore/PageCache.h> +#include <WebCore/Settings.h> +#include <wtf/text/WTFString.h> + +#if USE(CFNETWORK) +#include <CFNetwork/CFURLCachePriv.h> +#include <CFNetwork/CFURLProtocolPriv.h> +#include <WebCore/CookieStorageCFNet.h> +#include <WebKitSystemInterface/WebKitSystemInterface.h> +#include <wtf/RetainPtr.h> +#endif + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +static uint64_t memorySize() +{ + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + GlobalMemoryStatusEx(&statex); + return statex.ullTotalPhys; +} + +static uint64_t volumeFreeSize(CFStringRef cfstringPath) +{ + WTF::String path(cfstringPath); + ULARGE_INTEGER freeBytesToCaller; + BOOL result = GetDiskFreeSpaceExW((LPCWSTR)path.charactersWithNullTermination(), &freeBytesToCaller, 0, 0); + if (!result) + return 0; + return freeBytesToCaller.QuadPart; +} + +void WebProcess::platformSetCacheModel(CacheModel cacheModel) +{ +#if USE(CFNETWORK) + RetainPtr<CFStringRef> cfurlCacheDirectory(AdoptCF, wkCopyFoundationCacheDirectory()); + if (!cfurlCacheDirectory) + cfurlCacheDirectory.adoptCF(WebCore::localUserSpecificStorageDirectory().createCFString()); + + // As a fudge factor, use 1000 instead of 1024, in case the reported byte + // count doesn't align exactly to a megabyte boundary. + uint64_t memSize = memorySize() / 1024 / 1000; + uint64_t diskFreeSize = volumeFreeSize(cfurlCacheDirectory.get()) / 1024 / 1000; + + unsigned cacheTotalCapacity = 0; + unsigned cacheMinDeadCapacity = 0; + unsigned cacheMaxDeadCapacity = 0; + double deadDecodedDataDeletionInterval = 0; + unsigned pageCacheCapacity = 0; + unsigned long urlCacheMemoryCapacity = 0; + unsigned long urlCacheDiskCapacity = 0; + + calculateCacheSizes(cacheModel, memSize, diskFreeSize, + cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, + pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity); + + memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); + memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); + pageCache()->setCapacity(pageCacheCapacity); + + RetainPtr<CFURLCacheRef> cfurlCache(AdoptCF, CFURLCacheCopySharedURLCache()); + CFURLCacheSetMemoryCapacity(cfurlCache.get(), urlCacheMemoryCapacity); + CFURLCacheSetDiskCapacity(cfurlCache.get(), max<unsigned long>(urlCacheDiskCapacity, CFURLCacheDiskCapacity(cfurlCache.get()))); // Don't shrink a big disk cache, since that would cause churn. +#endif +} + +void WebProcess::platformClearResourceCaches() +{ +#if USE(CFNETWORK) + CFURLCacheRemoveAllCachedResponses(RetainPtr<CFURLCacheRef>(AdoptCF, CFURLCacheCopySharedURLCache()).get()); +#endif +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*) +{ + setShouldPaintNativeControls(parameters.shouldPaintNativeControls); +} + +void WebProcess::platformShutdown() +{ +} + +void WebProcess::setShouldPaintNativeControls(bool shouldPaintNativeControls) +{ +#if USE(SAFARI_THEME) + Settings::setShouldPaintNativeControls(shouldPaintNativeControls); +#endif +} + +} // namespace WebKit |