diff options
Diffstat (limited to 'Source/WebKit2/WebProcess')
348 files changed, 51662 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp new file mode 100644 index 000000000..9c1ad8798 --- /dev/null +++ b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp @@ -0,0 +1,109 @@ +/* + * 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 "config.h" +#include "WebApplicationCacheManager.h" + +#include "MessageID.h" +#include "SecurityOriginData.h" +#include "WebApplicationCacheManagerProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/ApplicationCache.h> +#include <WebCore/ApplicationCacheStorage.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityOriginHash.h> + +using namespace WebCore; + +namespace WebKit { + +WebApplicationCacheManager& WebApplicationCacheManager::shared() +{ + static WebApplicationCacheManager& shared = *new WebApplicationCacheManager; + return shared; +} + +WebApplicationCacheManager::WebApplicationCacheManager() +{ +} + +void WebApplicationCacheManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebApplicationCacheManagerMessage(connection, messageID, arguments); +} + +void WebApplicationCacheManager::getApplicationCacheOrigins(uint64_t callbackID) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash> origins; + + cacheStorage().getOriginsWithCache(origins); + + Vector<SecurityOriginData> identifiers; + identifiers.reserveCapacity(origins.size()); + + HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>::iterator end = origins.end(); + HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash>::iterator i = origins.begin(); + for (; i != end; ++i) { + RefPtr<SecurityOrigin> origin = *i; + + SecurityOriginData originData; + originData.protocol = origin->protocol(); + originData.host = origin->host(); + originData.port = origin->port(); + + identifiers.uncheckedAppend(originData); + } + + WebProcess::shared().connection()->send(Messages::WebApplicationCacheManagerProxy::DidGetApplicationCacheOrigins(identifiers, callbackID), 0); +} + +void WebApplicationCacheManager::deleteEntriesForOrigin(const SecurityOriginData& originData) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + RefPtr<SecurityOrigin> origin = SecurityOrigin::create(originData.protocol, originData.host, originData.port); + if (!origin) + return; + + ApplicationCache::deleteCacheForOrigin(origin.get()); +} + +void WebApplicationCacheManager::deleteAllEntries() +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + cacheStorage().deleteAllEntries(); +} + +void WebApplicationCacheManager::setAppCacheMaximumSize(uint64_t size) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + cacheStorage().setMaximumSize(size); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.h b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.h new file mode 100644 index 000000000..38d48e119 --- /dev/null +++ b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.h @@ -0,0 +1,63 @@ +/* + * 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 WebApplicationCacheManager_h +#define WebApplicationCacheManager_h + +#include <wtf/Noncopyable.h> +#include <wtf/text/WTFString.h> + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebKit { + +struct SecurityOriginData; + +class WebApplicationCacheManager { + WTF_MAKE_NONCOPYABLE(WebApplicationCacheManager); + +public: + static WebApplicationCacheManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void deleteAllEntries(); + void setAppCacheMaximumSize(uint64_t); +private: + WebApplicationCacheManager(); + + void getApplicationCacheOrigins(uint64_t callbackID); + void deleteEntriesForOrigin(const SecurityOriginData&); + + void didReceiveWebApplicationCacheManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +}; + +} // namespace WebKit + +#endif // WebApplicationCacheManager_h diff --git a/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.messages.in b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.messages.in new file mode 100644 index 000000000..bf21d9d9f --- /dev/null +++ b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.messages.in @@ -0,0 +1,27 @@ +# 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 -> WebApplicationCacheManager { + void GetApplicationCacheOrigins(uint64_t callbackID) + void DeleteEntriesForOrigin(WebKit::SecurityOriginData originIdentifier) + void DeleteAllEntries() +} diff --git a/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.cpp b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.cpp new file mode 100644 index 000000000..aa76a29ca --- /dev/null +++ b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AuthenticationManager.h" + +#include "Download.h" +#include "DownloadProxyMessages.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> + +using namespace WebCore; + +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 AuthenticationChallenge& authenticationChallenge) +{ + ASSERT(frame); + ASSERT(frame->page()); + + uint64_t challengeID = generateAuthenticationChallengeID(); + m_challenges.set(challengeID, authenticationChallenge); + + WebProcess::shared().connection()->send(Messages::WebPageProxy::DidReceiveAuthenticationChallenge(frame->frameID(), authenticationChallenge, challengeID), frame->page()->pageID()); +} + +void AuthenticationManager::didReceiveAuthenticationChallenge(Download* download, const AuthenticationChallenge& authenticationChallenge) +{ + uint64_t challengeID = generateAuthenticationChallengeID(); + m_challenges.set(challengeID, authenticationChallenge); + + download->send(Messages::DownloadProxy::DidReceiveAuthenticationChallenge(authenticationChallenge, challengeID)); +} + +// Currently, only Mac knows how to respond to authentication challenges with certificate info. +#if !PLATFORM(MAC) +bool AuthenticationManager::tryUsePlatformCertificateInfoForChallenge(const WebCore::AuthenticationChallenge&, const PlatformCertificateInfo&) +{ + return false; +} +#endif + +void AuthenticationManager::useCredentialForChallenge(uint64_t challengeID, const Credential& credential, const PlatformCertificateInfo& certificateInfo) +{ + AuthenticationChallenge challenge = m_challenges.take(challengeID); + ASSERT(!challenge.isNull()); + + if (tryUsePlatformCertificateInfoForChallenge(challenge, certificateInfo)) + return; + + AuthenticationClient* coreClient = challenge.authenticationClient(); + if (!coreClient) { + // This authentication challenge comes from a download. + Download::receivedCredential(challenge, credential); + return; + + } + + coreClient->receivedCredential(challenge, credential); +} + +void AuthenticationManager::continueWithoutCredentialForChallenge(uint64_t challengeID) +{ + AuthenticationChallenge challenge = m_challenges.take(challengeID); + ASSERT(!challenge.isNull()); + AuthenticationClient* coreClient = challenge.authenticationClient(); + if (!coreClient) { + // This authentication challenge comes from a download. + Download::receivedRequestToContinueWithoutCredential(challenge); + return; + } + + coreClient->receivedRequestToContinueWithoutCredential(challenge); +} + +void AuthenticationManager::cancelChallenge(uint64_t challengeID) +{ + AuthenticationChallenge challenge = m_challenges.take(challengeID); + ASSERT(!challenge.isNull()); + AuthenticationClient* coreClient = challenge.authenticationClient(); + if (!coreClient) { + // This authentication challenge comes from a download. + Download::receivedCancellation(challenge); + 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 000000000..192c91aef --- /dev/null +++ b/Source/WebKit2/WebProcess/Authentication/AuthenticationManager.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 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 Download; +class PlatformCertificateInfo; +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 didReceiveAuthenticationChallenge(Download*, const WebCore::AuthenticationChallenge&); + + void useCredentialForChallenge(uint64_t challengeID, const WebCore::Credential&, const PlatformCertificateInfo&); + void continueWithoutCredentialForChallenge(uint64_t challengeID); + void cancelChallenge(uint64_t challengeID); + +private: + AuthenticationManager(); + + void didReceiveAuthenticationManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + bool tryUsePlatformCertificateInfoForChallenge(const WebCore::AuthenticationChallenge&, const PlatformCertificateInfo&); + + 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 000000000..bb1cc30ca --- /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, WebKit::PlatformCertificateInfo certificate); + void ContinueWithoutCredentialForChallenge(uint64_t challengeID); + void CancelChallenge(uint64_t challengeID); +} diff --git a/Source/WebKit2/WebProcess/Authentication/mac/AuthenticationManager.mac.mm b/Source/WebKit2/WebProcess/Authentication/mac/AuthenticationManager.mac.mm new file mode 100644 index 000000000..091ad40c0 --- /dev/null +++ b/Source/WebKit2/WebProcess/Authentication/mac/AuthenticationManager.mac.mm @@ -0,0 +1,65 @@ +/* + * 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 "config.h" +#include "AuthenticationManager.h" + +#include "PlatformCertificateInfo.h" +#include <Security/SecIdentity.h> +#include <WebCore/AuthenticationChallenge.h> + +using namespace WebCore; + +namespace WebKit { + +bool AuthenticationManager::tryUsePlatformCertificateInfoForChallenge(const AuthenticationChallenge& challenge, const PlatformCertificateInfo& certificateInfo) +{ + CFArrayRef chain = certificateInfo.certificateChain(); + if (!chain) + return false; + + ASSERT(CFArrayGetCount(chain)); + + // The passed-in certificate chain includes the identity certificate at index 0, and additional certificates starting at index 1. + SecIdentityRef identity; + OSStatus result = SecIdentityCreateWithCertificate(NULL, (SecCertificateRef)CFArrayGetValueAtIndex(chain, 0), &identity); + if (result != errSecSuccess) { + LOG_ERROR("Unable to create SecIdentityRef with certificate - %i", result); + [challenge.sender() cancelAuthenticationChallenge:challenge.nsURLAuthenticationChallenge()]; + return true; + } + + CFIndex chainCount = CFArrayGetCount(chain); + NSArray *nsChain = chainCount > 1 ? [(NSArray *)chain subarrayWithRange:NSMakeRange(1, chainCount - 1)] : nil; + + NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity + certificates:nsChain + persistence:NSURLCredentialPersistenceNone]; + + [challenge.sender() useCredential:credential forAuthenticationChallenge:challenge.nsURLAuthenticationChallenge()]; + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp new file mode 100644 index 000000000..6f3af1d10 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.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 "config.h" +#include "WebCookieManager.h" + +#include "MessageID.h" +#include "WebCookieManagerProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/CookieJar.h> +#include <WebCore/CookieStorage.h> + +using namespace WebCore; + +namespace WebKit { + +WebCookieManager& WebCookieManager::shared() +{ + DEFINE_STATIC_LOCAL(WebCookieManager, shared, ()); + return shared; +} + +WebCookieManager::WebCookieManager() +{ +} + +void WebCookieManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebCookieManagerMessage(connection, messageID, arguments); +} + +void WebCookieManager::getHostnamesWithCookies(uint64_t callbackID) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + HashSet<String> hostnames; + + WebCore::getHostnamesWithCookies(hostnames); + + Vector<String> hostnameList; + copyToVector(hostnames, hostnameList); + + WebProcess::shared().connection()->send(Messages::WebCookieManagerProxy::DidGetHostnamesWithCookies(hostnameList, callbackID), 0); +} + +void WebCookieManager::deleteCookiesForHostname(const String& hostname) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + WebCore::deleteCookiesForHostname(hostname); +} + +void WebCookieManager::deleteAllCookies() +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + WebCore::deleteAllCookies(); +} + +void WebCookieManager::startObservingCookieChanges() +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + WebCore::startObservingCookieChanges(); +} + +void WebCookieManager::stopObservingCookieChanges() +{ + WebCore::stopObservingCookieChanges(); +} + +void WebCookieManager::dispatchCookiesDidChange() +{ + WebProcess::shared().connection()->send(Messages::WebCookieManagerProxy::CookiesDidChange(), 0); +} + +void WebCookieManager::setHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + platformSetHTTPCookieAcceptPolicy(policy); +} + +void WebCookieManager::getHTTPCookieAcceptPolicy(uint64_t callbackID) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + WebProcess::shared().connection()->send(Messages::WebCookieManagerProxy::DidGetHTTPCookieAcceptPolicy(platformGetHTTPCookieAcceptPolicy(), callbackID), 0); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/WebCookieManager.h b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.h new file mode 100644 index 000000000..c0bd1f3d1 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.h @@ -0,0 +1,71 @@ +/* + * 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 WebCookieManager_h +#define WebCookieManager_h + +#include "HTTPCookieAcceptPolicy.h" +#include <wtf/Noncopyable.h> +#include <wtf/text/WTFString.h> + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebKit { + +class WebCookieManager { + WTF_MAKE_NONCOPYABLE(WebCookieManager); +public: + static WebCookieManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void dispatchCookiesDidChange(); + + void setHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy); + +private: + WebCookieManager(); + + void getHostnamesWithCookies(uint64_t callbackID); + void deleteCookiesForHostname(const String&); + void deleteAllCookies(); + + void platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy); + void getHTTPCookieAcceptPolicy(uint64_t callbackID); + HTTPCookieAcceptPolicy platformGetHTTPCookieAcceptPolicy(); + + void startObservingCookieChanges(); + void stopObservingCookieChanges(); + + void didReceiveWebCookieManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +}; + +} // namespace WebKit + +#endif // WebCookieManager_h diff --git a/Source/WebKit2/WebProcess/Cookies/WebCookieManager.messages.in b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.messages.in new file mode 100644 index 000000000..15de9b6c3 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.messages.in @@ -0,0 +1,36 @@ +/* + * 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 -> WebCookieManager { + void GetHostnamesWithCookies(uint64_t callbackID) + void DeleteCookiesForHostname(WTF::String hostname) + void DeleteAllCookies() + + void SetHTTPCookieAcceptPolicy(uint32_t policy) + void GetHTTPCookieAcceptPolicy(uint64_t callbackID) + + void StartObservingCookieChanges() + void StopObservingCookieChanges() +} diff --git a/Source/WebKit2/WebProcess/Cookies/cf/WebCookieManagerCFNet.cpp b/Source/WebKit2/WebProcess/Cookies/cf/WebCookieManagerCFNet.cpp new file mode 100644 index 000000000..6606897d9 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/cf/WebCookieManagerCFNet.cpp @@ -0,0 +1,63 @@ +/* + * 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 "config.h" +#include "WebCookieManager.h" + +#include <CFNetwork/CFHTTPCookiesPriv.h> +#include <WebCore/CookieStorage.h> +#include <WebCore/CookieStorageCFNet.h> + +#if PLATFORM(MAC) +#include <WebKitSystemInterface.h> +#elif PLATFORM(WIN) +#include <WebKitSystemInterface/WebKitSystemInterface.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) +{ +#if PLATFORM(MAC) + CFHTTPCookieStorageRef defaultCookieStorage = WKGetDefaultHTTPCookieStorage(); +#elif PLATFORM(WIN) + CFHTTPCookieStorageRef defaultCookieStorage = wkGetDefaultHTTPCookieStorage(); +#endif + + CFHTTPCookieStorageSetCookieAcceptPolicy(defaultCookieStorage, policy); + + if (RetainPtr<CFHTTPCookieStorageRef> cookieStorage = currentCFHTTPCookieStorage()) + CFHTTPCookieStorageSetCookieAcceptPolicy(cookieStorage.get(), policy); +} + +HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy() +{ + RetainPtr<CFHTTPCookieStorageRef> cookieStorage = currentCFHTTPCookieStorage(); + return CFHTTPCookieStorageGetCookieAcceptPolicy(cookieStorage.get()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/curl/WebCookieManagerCurl.cpp b/Source/WebKit2/WebProcess/Cookies/curl/WebCookieManagerCurl.cpp new file mode 100644 index 000000000..505082dd7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/curl/WebCookieManagerCurl.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011 Brent Fulgham <bfulgham@webkit.org>. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebCookieManager.h" + +#include <WebCore/CookieStorage.h> +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) +{ + // Fixme: To be implemented + notImplemented(); +} + +HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy() +{ + notImplemented(); + return HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/mac/WebCookieManagerMac.mm b/Source/WebKit2/WebProcess/Cookies/mac/WebCookieManagerMac.mm new file mode 100644 index 000000000..daf39cdc7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/mac/WebCookieManagerMac.mm @@ -0,0 +1,50 @@ +/* + * 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 "config.h" +#import "WebCookieManager.h" +#import <WebCore/CookieStorageCFNet.h> +#import <WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) +{ + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:policy]; + +#if USE(CFURLSTORAGESESSIONS) + if (RetainPtr<CFHTTPCookieStorageRef> cookieStorage = currentCFHTTPCookieStorage()) + WKSetHTTPCookieAcceptPolicy(cookieStorage.get(), policy); +#endif +} + +HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy() +{ + return [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/qt/WebCookieManagerQt.cpp b/Source/WebKit2/WebProcess/Cookies/qt/WebCookieManagerQt.cpp new file mode 100644 index 000000000..acdd608ff --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/qt/WebCookieManagerQt.cpp @@ -0,0 +1,42 @@ +/* + * 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 "config.h" +#include "WebCookieManager.h" + +namespace WebKit { + +void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy) +{ + // FIXME: Not implemented. +} + +HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy() +{ + // FIXME: Not implemented. + return HTTPCookieAcceptPolicyAlways; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/soup/WebCookieManagerSoup.cpp b/Source/WebKit2/WebProcess/Cookies/soup/WebCookieManagerSoup.cpp new file mode 100644 index 000000000..be5421b43 --- /dev/null +++ b/Source/WebKit2/WebProcess/Cookies/soup/WebCookieManagerSoup.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 Samsung Electronics. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebCookieManager.h" + +#include <WebCore/CookieJarSoup.h> +#include <libsoup/soup.h> + +using namespace WebCore; + +namespace WebKit { + +void WebCookieManager::platformSetHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) +{ + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + SoupCookieJarAcceptPolicy soupPolicy; + + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + switch (policy) { + case HTTPCookieAcceptPolicyAlways: + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + break; + case HTTPCookieAcceptPolicyNever: + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_NEVER; + break; + case HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain: + soupPolicy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; + break; + } + soup_cookie_jar_set_accept_policy(cookieJar, soupPolicy); +} + +HTTPCookieAcceptPolicy WebCookieManager::platformGetHTTPCookieAcceptPolicy() +{ + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + SoupCookieJarAcceptPolicy soupPolicy; + + HTTPCookieAcceptPolicy policy; + + soupPolicy = soup_cookie_jar_get_accept_policy(cookieJar); + switch (soupPolicy) { + case SOUP_COOKIE_JAR_ACCEPT_ALWAYS: + policy = HTTPCookieAcceptPolicyAlways; + break; + case SOUP_COOKIE_JAR_ACCEPT_NEVER: + policy = HTTPCookieAcceptPolicyNever; + break; + case SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY: + policy = HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; + break; + default: + policy = HTTPCookieAcceptPolicyAlways; + } + return policy; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/Download.cpp b/Source/WebKit2/WebProcess/Downloads/Download.cpp new file mode 100644 index 000000000..1d059415a --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/Download.cpp @@ -0,0 +1,161 @@ +/* + * 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 "config.h" +#include "Download.h" + +#include "AuthenticationManager.h" +#include "Connection.h" +#include "DataReference.h" +#include "DownloadAuthenticationClient.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) +#if USE(CFNETWORK) + , m_allowOverwrite(false) +#endif +#if PLATFORM(QT) + , m_qtDownloader(0) +#endif +{ + ASSERT(m_downloadID); + + WebProcess::shared().disableTermination(); +} + +Download::~Download() +{ + platformInvalidate(); + + WebProcess::shared().enableTermination(); +} + +CoreIPC::Connection* Download::connection() const +{ + return WebProcess::shared().connection(); +} + +void Download::didStart() +{ + send(Messages::DownloadProxy::DidStart(m_request)); +} + +void Download::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge) +{ + AuthenticationManager::shared().didReceiveAuthenticationChallenge(this, authenticationChallenge); +} + +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::retrieveDestinationWithSuggestedFilename(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; +} + +String Download::decideDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite) +{ + String destination = retrieveDestinationWithSuggestedFilename(filename, allowOverwrite); + + didDecideDestination(destination, allowOverwrite); + + return destination; +} + +void Download::didCreateDestination(const String& path) +{ + send(Messages::DownloadProxy::DidCreateDestination(path)); +} + +void Download::didFinish() +{ + platformDidFinish(); + + 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 000000000..0387efa66 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/Download.h @@ -0,0 +1,153 @@ +/* + * 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 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> + +OBJC_CLASS NSURLDownload; +OBJC_CLASS WKDownloadAsDelegate; +#endif + +#if PLATFORM(GTK) +#include <WebCore/ResourceHandle.h> +#include <WebCore/ResourceHandleClient.h> +#endif + +#if USE(CFNETWORK) +#include <CFNetwork/CFURLDownloadPriv.h> +#endif + +namespace CoreIPC { + class DataReference; +} + +namespace WebCore { + class AuthenticationChallenge; + class Credential; + class ResourceError; + class ResourceHandle; + class ResourceResponse; +} + +namespace WebKit { + +class DownloadAuthenticationClient; +class SandboxExtension; +class WebPage; + +#if PLATFORM(QT) +class QtFileDownloader; +#endif + +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::ResourceResponse&); + void cancel(); + + uint64_t downloadID() const { return m_downloadID; } + + void didStart(); + void didReceiveAuthenticationChallenge(const WebCore::AuthenticationChallenge&); + 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 platformDidFinish(); + void didFail(const WebCore::ResourceError&, const CoreIPC::DataReference& resumeData); + void didCancel(const CoreIPC::DataReference& resumeData); + void didDecideDestination(const String&, bool allowOverwrite); + +#if PLATFORM(QT) + void startTransfer(const String& destination); +#endif + +#if USE(CFNETWORK) + const String& destination() const { return m_destination; } + DownloadAuthenticationClient* authenticationClient(); +#endif + + // Authentication + static void receivedCredential(const WebCore::AuthenticationChallenge&, const WebCore::Credential&); + static void receivedRequestToContinueWithoutCredential(const WebCore::AuthenticationChallenge&); + static void receivedCancellation(const WebCore::AuthenticationChallenge&); + + void useCredential(const WebCore::AuthenticationChallenge&, const WebCore::Credential&); + void continueWithoutCredential(const WebCore::AuthenticationChallenge&); + void cancelAuthenticationChallenge(const WebCore::AuthenticationChallenge&); + +private: + Download(uint64_t downloadID, const WebCore::ResourceRequest&); + + void platformInvalidate(); + + String retrieveDestinationWithSuggestedFilename(const String& filename, bool& allowOverwrite); + + uint64_t m_downloadID; + WebCore::ResourceRequest m_request; + + RefPtr<SandboxExtension> m_sandboxExtension; + +#if PLATFORM(MAC) + RetainPtr<NSURLDownload> m_nsURLDownload; + RetainPtr<WKDownloadAsDelegate> m_delegate; +#endif + bool m_allowOverwrite; + String m_destination; + String m_bundlePath; +#if USE(CFNETWORK) + RetainPtr<CFURLDownloadRef> m_download; + RefPtr<DownloadAuthenticationClient> m_authenticationClient; +#endif +#if PLATFORM(QT) + QtFileDownloader* m_qtDownloader; +#endif +#if PLATFORM(GTK) + OwnPtr<WebCore::ResourceHandleClient> m_downloadClient; + RefPtr<WebCore::ResourceHandle> m_resourceHandle; +#endif +}; + +} // namespace WebKit + +#endif // Download_h diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.cpp b/Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.cpp new file mode 100644 index 000000000..2f1580ff7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.cpp @@ -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. + */ + +#include "config.h" +#include "DownloadAuthenticationClient.h" + +#include "Download.h" + +using namespace WebCore; + +namespace WebKit { + +DownloadAuthenticationClient::DownloadAuthenticationClient(Download* download) + : m_download(download) +{ + ASSERT_ARG(download, download); +} + +void DownloadAuthenticationClient::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential) +{ + if (!m_download) + return; + m_download->useCredential(challenge, credential); +} + +void DownloadAuthenticationClient::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& challenge) +{ + if (!m_download) + return; + m_download->continueWithoutCredential(challenge); +} + +void DownloadAuthenticationClient::receivedCancellation(const AuthenticationChallenge& challenge) +{ + if (!m_download) + return; + m_download->cancelAuthenticationChallenge(challenge); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.h b/Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.h new file mode 100644 index 000000000..76321ae6d --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/DownloadAuthenticationClient.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 DownloadAuthenticationClient_h +#define DownloadAuthenticationClient_h + +#include <WebCore/AuthenticationClient.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + class AuthenticationChallenge; + class Credential; +} + +namespace WebKit { + +class Download; + +class DownloadAuthenticationClient : public RefCounted<DownloadAuthenticationClient>, public WebCore::AuthenticationClient { +public: + static PassRefPtr<DownloadAuthenticationClient> create(Download* download) { return adoptRef(new DownloadAuthenticationClient(download)); } + + void detach() { m_download = 0; } + + using RefCounted<DownloadAuthenticationClient>::ref; + using RefCounted<DownloadAuthenticationClient>::deref; + +private: + DownloadAuthenticationClient(Download*); + + virtual void receivedCredential(const WebCore::AuthenticationChallenge&, const WebCore::Credential&); + virtual void receivedRequestToContinueWithoutCredential(const WebCore::AuthenticationChallenge&); + virtual void receivedCancellation(const WebCore::AuthenticationChallenge&); + + virtual void refAuthenticationClient() { ref(); } + virtual void derefAuthenticationClient() { deref(); } + + Download* m_download; +}; + +} // namespace WebKit + +#endif // DownloadAuthenticationClient_h diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp new file mode 100644 index 000000000..2ed11944c --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.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 "config.h" +#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 ResourceResponse& response) +{ + OwnPtr<Download> download = Download::create(downloadID, request); + + download->startWithHandle(initiatingPage, handle, 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; +} + +#if PLATFORM(QT) +void DownloadManager::startTransfer(uint64_t downloadID, const String& destination) +{ + ASSERT(m_downloads.contains(downloadID)); + Download* download = m_downloads.get(downloadID); + download->startTransfer(destination); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.h b/Source/WebKit2/WebProcess/Downloads/DownloadManager.h new file mode 100644 index 000000000..9124c035e --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.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 DownloadManager_h +#define DownloadManager_h + +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> + +namespace WTF { +class String; +} + +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::ResourceResponse&); + + void cancelDownload(uint64_t downloadID); + + void downloadFinished(Download*); + bool isDownloading() const { return !m_downloads.isEmpty(); } + +#if PLATFORM(QT) + void startTransfer(uint64_t downloadID, const WTF::String& destination); +#endif + +private: + DownloadManager(); + + HashMap<uint64_t, Download*> m_downloads; +}; + +} // namespace WebKit + +#endif // DownloadManager_h diff --git a/Source/WebKit2/WebProcess/Downloads/cf/win/DownloadCFWin.cpp b/Source/WebKit2/WebProcess/Downloads/cf/win/DownloadCFWin.cpp new file mode 100644 index 000000000..0dd650893 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/cf/win/DownloadCFWin.cpp @@ -0,0 +1,56 @@ +/* + * 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 "config.h" +#include "Download.h" + +using namespace WebCore; + +namespace WebKit { + +void Download::platformDidFinish() +{ + ASSERT(!m_bundlePath.isEmpty()); + ASSERT(!m_destination.isEmpty()); + + // Try to move the bundle to the final filename. + DWORD flags = MOVEFILE_COPY_ALLOWED | (m_allowOverwrite ? MOVEFILE_REPLACE_EXISTING : 0); + if (::MoveFileExW(m_bundlePath.charactersWithNullTermination(), m_destination.charactersWithNullTermination(), flags)) + return; + + // The move failed. Give the client one more chance to choose the final filename. + m_destination = retrieveDestinationWithSuggestedFilename(m_destination, m_allowOverwrite); + if (m_destination.isEmpty()) + return; + + // We either need to report our final filename as the bundle filename or the updated destination filename. + flags = MOVEFILE_COPY_ALLOWED | (m_allowOverwrite ? MOVEFILE_REPLACE_EXISTING : 0); + if (::MoveFileExW(m_bundlePath.charactersWithNullTermination(), m_destination.charactersWithNullTermination(), flags)) + didCreateDestination(m_destination); + else + didCreateDestination(m_bundlePath); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp b/Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp new file mode 100644 index 000000000..22906dc31 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/cfnet/DownloadCFNet.cpp @@ -0,0 +1,263 @@ +/* + * 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 "config.h" +#include "Download.h" + +#include "DataReference.h" +#include "DownloadAuthenticationClient.h" + +#pragma warning(push, 0) +#include <WebCore/AuthenticationCF.h> +#include <WebCore/DownloadBundle.h> +#include <WebCore/LoaderRunLoopCF.h> +#include <WebCore/NotImplemented.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::useCredential(const WebCore::AuthenticationChallenge& challenge, const WebCore::Credential& credential) +{ + if (!m_download) + return; + RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential)); + CFURLDownloadUseCredential(m_download.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef()); +} + +void Download::continueWithoutCredential(const WebCore::AuthenticationChallenge& challenge) +{ + if (!m_download) + return; + CFURLDownloadUseCredential(m_download.get(), 0, challenge.cfURLAuthChallengeRef()); +} + +void Download::cancelAuthenticationChallenge(const WebCore::AuthenticationChallenge&) +{ + if (!m_download) + return; + CFURLDownloadCancel(m_download.get()); + m_download = 0; +} + +DownloadAuthenticationClient* Download::authenticationClient() +{ + if (!m_authenticationClient) + m_authenticationClient = DownloadAuthenticationClient::create(this); + return m_authenticationClient.get(); +} + +void Download::start(WebPage*) +{ + 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); + + CFURLDownloadStart(m_download.get()); +} + +void Download::startWithHandle(WebPage*, ResourceHandle* handle, 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, handle->firstRequest().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() +{ + ASSERT(m_download); + if (!m_download) + return; + + CFURLDownloadSetDeletesUponFailure(m_download.get(), false); + CFURLDownloadCancel(m_download.get()); + + RetainPtr<CFDataRef> resumeData(AdoptCF, CFURLDownloadCopyResumeData(m_download.get())); + if (resumeData) + DownloadBundle::appendResumeData(resumeData.get(), m_bundlePath); + + didCancel(CoreIPC::DataReference()); +} + +void Download::platformInvalidate() +{ + m_download = nullptr; + if (m_authenticationClient) + m_authenticationClient->detach(); +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ + ASSERT(!destination.isEmpty()); + if (destination.isEmpty()) + return; + + m_allowOverwrite = allowOverwrite; + m_destination = destination; + m_bundlePath = destination + DownloadBundle::fileExtension(); + + RetainPtr<CFStringRef> bundlePath(AdoptCF, CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar*>(m_bundlePath.characters()), m_bundlePath.length(), kCFAllocatorNull)); + RetainPtr<CFURLRef> bundlePathURL(AdoptCF, CFURLCreateWithFileSystemPath(0, bundlePath.get(), kCFURLWindowsPathStyle, false)); + CFURLDownloadSetDestination(m_download.get(), bundlePathURL.get(), allowOverwrite); +} + +// 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) +{ + Download* download = downloadFromClientInfo(clientInfo); + download->didReceiveAuthenticationChallenge(AuthenticationChallenge(challenge, download->authenticationClient())); +} + +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, CFStringRef objectName, const void* clientInfo) +{ + Download* download = downloadFromClientInfo(clientInfo); + bool allowOverwrite; + download->decideDestinationWithSuggestedFilename(objectName, allowOverwrite); +} + +void didCreateDestinationCallback(CFURLDownloadRef, CFURLRef, const void* clientInfo) +{ + // The concept of the ".download bundle" is internal to the Download, so we try to hide its + // existence by reporting the final destination was created, when in reality the bundle was created. + + Download* download = downloadFromClientInfo(clientInfo); + download->didCreateDestination(download->destination()); +} + +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); +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + ASSERT(authenticationChallenge.authenticationClient()); + authenticationChallenge.authenticationClient()->receivedCredential(authenticationChallenge, credential); +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + ASSERT(authenticationChallenge.authenticationClient()); + authenticationChallenge.authenticationClient()->receivedRequestToContinueWithoutCredential(authenticationChallenge); +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + ASSERT(authenticationChallenge.authenticationClient()); + authenticationChallenge.authenticationClient()->receivedCancellation(authenticationChallenge); +} + +} // 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 000000000..38cfa6fd5 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/curl/DownloadCurl.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010, 2011 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 "config.h" +#include "Download.h" + +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void Download::start(WebPage* initiatingWebPage) +{ + notImplemented(); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle*, const ResourceResponse&) +{ + notImplemented(); +} + +void Download::cancel() +{ + notImplemented(); +} + +void Download::platformInvalidate() +{ + notImplemented(); +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ + notImplemented(); +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + notImplemented(); +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::useCredential(const AuthenticationChallenge&, const Credential&) +{ + notImplemented(); +} + +void Download::continueWithoutCredential(const AuthenticationChallenge&) +{ + notImplemented(); +} + +void Download::cancelAuthenticationChallenge(const AuthenticationChallenge&) +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/efl/DownloadEfl.cpp b/Source/WebKit2/WebProcess/Downloads/efl/DownloadEfl.cpp new file mode 100755 index 000000000..7d098f133 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/efl/DownloadEfl.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Download.h" + +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void Download::start(WebPage* initiatingWebPage) +{ + notImplemented(); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceResponse& response) +{ + notImplemented(); +} + +void Download::cancel() +{ + notImplemented(); +} + +void Download::platformInvalidate() +{ + notImplemented(); +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ + notImplemented(); +} + +void Download::platformDidFinish() +{ + notImplemented(); +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + notImplemented(); +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::useCredential(const WebCore::AuthenticationChallenge& authenticationChallenge, const WebCore::Credential& credential) +{ + notImplemented(); +} + +void Download::continueWithoutCredential(const WebCore::AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::cancelAuthenticationChallenge(const WebCore::AuthenticationChallenge& authenticationChallenge) +{ + 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 000000000..601d013c7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm @@ -0,0 +1,241 @@ +/* + * 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. + */ + +#import "config.h" +#import "Download.h" + +#import <WebCore/AuthenticationMac.h> +#import <WebCore/NotImplemented.h> +#import <WebCore/ResourceHandle.h> +#import <WebCore/ResourceResponse.h> +#import "DataReference.h" +#import "WebPage.h" + +@interface NSURLDownload (WebNSURLDownloadDetails) ++(id)_downloadWithLoadingConnection:(NSURLConnection *)connection + request:(NSURLRequest *)request + response:(NSURLResponse *)r + delegate:(id)delegate + proxy:(id)proxy; +@end + +@interface WKDownloadAsDelegate : NSObject <NSURLDownloadDelegate> { + WebKit::Download* _download; +} +- (id)initWithDownload:(WebKit::Download*)download; +- (void)invalidate; +@end + +using namespace WebCore; + +namespace WebKit { + +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]; +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, 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]; +} + +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; +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ +} + +void Download::platformDidFinish() +{ +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + [authenticationChallenge.sender() useCredential:mac(credential) forAuthenticationChallenge:authenticationChallenge.nsURLAuthenticationChallenge()]; +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + [authenticationChallenge.sender() continueWithoutCredentialForAuthenticationChallenge:authenticationChallenge.nsURLAuthenticationChallenge()]; +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + [authenticationChallenge.sender() cancelAuthenticationChallenge:authenticationChallenge.nsURLAuthenticationChallenge()]; +} + +} // 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 +{ + if (_download) + _download->didReceiveAuthenticationChallenge(core(challenge)); +} + +- (void)download:(NSURLDownload *)download didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge +{ + // FIXME: Implement. + notImplemented(); +} + +- (BOOL)downloadShouldUseCredentialStorage:(NSURLDownload *)download +{ + return NO; +} + +- (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 000000000..c36478b47 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/qt/DownloadQt.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 "config.h" +#include "Download.h" + +#include "QtFileDownloader.h" +#include "WebProcess.h" +#include <WebCore/NotImplemented.h> +#include <WebCore/QNetworkReplyHandler.h> +#include <WebCore/ResourceHandle.h> +#include <WebCore/ResourceHandleInternal.h> +#include <WebCore/ResourceResponse.h> + +using namespace WebCore; + +namespace WebKit { + +void Download::start(WebPage* initiatingWebPage) +{ + QNetworkAccessManager* manager = WebProcess::shared().networkAccessManager(); + ASSERT(manager); + ASSERT(!m_qtDownloader); + + m_qtDownloader = new QtFileDownloader(this, adoptPtr(manager->get(m_request.toNetworkRequest()))); + m_qtDownloader->init(); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* handle, const ResourceResponse& resp) +{ + ASSERT(!m_qtDownloader); + m_qtDownloader = new QtFileDownloader(this, adoptPtr(handle->getInternal()->m_job->release())); + m_qtDownloader->init(); +} + +void Download::cancel() +{ + ASSERT(m_qtDownloader); + m_qtDownloader->cancel(); +} + +void Download::platformInvalidate() +{ + ASSERT(m_qtDownloader); + m_qtDownloader->deleteLater(); + m_qtDownloader = 0; +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ + notImplemented(); +} + +void Download::startTransfer(const String& destination) +{ + m_qtDownloader->startTransfer(destination); +} + +void Download::platformDidFinish() +{ + notImplemented(); +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + notImplemented(); +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.cpp b/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.cpp new file mode 100644 index 000000000..c3b2e8d0e --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#include "config.h" +#include "QtFileDownloader.h" + +#include "DataReference.h" +#include "Download.h" +#include "HTTPParsers.h" +#include "MIMETypeRegistry.h" +#include <QCoreApplication> +#include <QFile> +#include <QFileInfo> +#include <QNetworkAccessManager> +#include <WebCore/QNetworkReplyHandler.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceResponse.h> + +using namespace WebCore; +using namespace WTF; + +namespace WebKit { + +QtFileDownloader::QtFileDownloader(Download* download, PassOwnPtr<QNetworkReply> reply) + : m_download(download) + , m_reply(reply) + , m_error(QNetworkReply::NoError) + , m_headersRead(false) +{ +} + +QtFileDownloader::~QtFileDownloader() +{ + if (!m_destinationFile) + return; + + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorAborted); +} + +void QtFileDownloader::init() +{ + connect(m_reply.get(), SIGNAL(readyRead()), SLOT(onReadyRead())); + connect(m_reply.get(), SIGNAL(finished()), SLOT(onFinished())); + connect(m_reply.get(), SIGNAL(error(QNetworkReply::NetworkError)), SLOT(onError(QNetworkReply::NetworkError))); +} + +QString QtFileDownloader::determineFilename() +{ + ASSERT(!m_destinationFile); + + QString filenameCandidate = filenameFromHTTPContentDisposition(QString::fromLatin1(m_reply->rawHeader("Content-Disposition"))); + if (filenameCandidate.isEmpty()) { + KURL kurl = m_reply->url(); + filenameCandidate = decodeURLEscapeSequences(kurl.lastPathComponent()); + } + + if (filenameCandidate.isEmpty()) { + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotDetermineFilename); + return QString(); + } + + // Make sure that we remove possible "../.." parts in the given file name. + QFileInfo filenameFilter(filenameCandidate); + QString filename = filenameFilter.fileName(); + + if (filename.isEmpty()) { + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotDetermineFilename); + return QString(); + } + + return filename; +} + +void QtFileDownloader::startTransfer(const QString& decidedFilePath) +{ + ASSERT(!m_destinationFile); + + // Error might have occured during destination query. + if (m_error != QNetworkReply::NoError) { + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorNetworkFailure); + return; + } + + if (decidedFilePath.isEmpty()) { + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCancelled); + return; + } + + OwnPtr<QFile> downloadFile = adoptPtr(new QFile(decidedFilePath)); + + if (!downloadFile->open(QIODevice::WriteOnly | QIODevice::Truncate)) { + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotOpenFile); + return; + } + + // Assigning to m_destinationFile flags that either error or + // finished shall be called in the end. + m_destinationFile = downloadFile.release(); + + m_download->didCreateDestination(m_destinationFile->fileName()); + + // We might have gotten readyRead already even before this function + // was called. + if (m_reply->bytesAvailable()) + onReadyRead(); + + // We might have gotten finished already even before this + // function was called. + if (m_reply->isFinished()) + onFinished(); +} + +void QtFileDownloader::abortDownloadWritingAndEmitError(QtFileDownloader::DownloadError errorCode) +{ + m_reply->abort(); + + // On network failures it's QNetworkReplyHandler::errorForReply who will handle errors. + if (errorCode == QtFileDownloader::DownloadErrorNetworkFailure) { + m_download->didFail(QNetworkReplyHandler::errorForReply(m_reply.get()), CoreIPC::DataReference(0, 0)); + return; + } + + QString translatedErrorMessage; + switch (errorCode) { + case QtFileDownloader::DownloadErrorAborted: + translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Download aborted"); + break; + case QtFileDownloader::DownloadErrorCannotWriteToFile: + translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Cannot write to file"); + break; + case QtFileDownloader::DownloadErrorCannotOpenFile: + translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Cannot open file for writing"); + break; + case QtFileDownloader::DownloadErrorDestinationAlreadyExists: + translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Destination already exists"); + break; + case QtFileDownloader::DownloadErrorCancelled: + translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Download cancelled by caller"); + break; + case QtFileDownloader::DownloadErrorCannotDetermineFilename: + translatedErrorMessage = QCoreApplication::translate("QtFileDownloader", "Cannot determine filename"); + break; + default: + ASSERT_NOT_REACHED(); + } + + ResourceError downloadError("Download", errorCode, m_reply->url().toString(), translatedErrorMessage); + + m_download->didFail(downloadError, CoreIPC::DataReference(0, 0)); +} + +void QtFileDownloader::handleDownloadResponse() +{ + // By API contract, QNetworkReply::metaDataChanged cannot really be trusted. + // Thus we need to call this upon receiving first data. + String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); + String encoding = extractCharsetFromMediaType(contentType); + String mimeType = extractMIMETypeFromMediaType(contentType); + String filename = determineFilename(); + + // If filename is empty it means determineFilename aborted and emitted an error. + if (filename.isEmpty()) + return; + + // Let's try to guess from the extension. + if (mimeType.isEmpty()) + mimeType = MIMETypeRegistry::getMIMETypeForPath(m_reply->url().path()); + + ResourceResponse response(m_reply->url(), mimeType, m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), encoding, filename); + m_download->didReceiveResponse(response); +} + +void QtFileDownloader::onReadyRead() +{ + if (m_destinationFile) { + QByteArray content = m_reply->readAll(); + if (content.size() <= 0) + return; + + qint64 bytesWritten = m_destinationFile->write(content); + + if (bytesWritten == -1) { + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCannotWriteToFile); + return; + } + + // There might a corner case to be fixed here if bytesWritten != content.size() + // does not actually represent an error. + ASSERT(bytesWritten == content.size()); + + m_download->didReceiveData(bytesWritten); + } else if (!m_headersRead) { + handleDownloadResponse(); + m_headersRead = true; + } +} + +void QtFileDownloader::onFinished() +{ + // If it's finished and we haven't even read the headers, it means we never got to onReadyRead and that we are + // probably dealing with the download of a local file or of a small file that was started with a handle. + if (!m_headersRead) { + handleDownloadResponse(); + m_headersRead = true; + return; + } + + if (!m_destinationFile) + return; + + m_destinationFile.clear(); + + if (m_error == QNetworkReply::NoError) + m_download->didFinish(); + else if (m_error == QNetworkReply::OperationCanceledError) + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorCancelled); + else + abortDownloadWritingAndEmitError(QtFileDownloader::DownloadErrorNetworkFailure); +} + +void QtFileDownloader::onError(QNetworkReply::NetworkError code) +{ + m_error = code; +} + +void QtFileDownloader::cancel() +{ + m_reply->abort(); + // QtFileDownloader::onFinished() will be called and will raise a DownloadErrorCancelled. +} + +} // namespace WebKit +#include "moc_QtFileDownloader.cpp" diff --git a/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.h b/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.h new file mode 100644 index 000000000..0ae0fd84a --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/qt/QtFileDownloader.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef QtFileDownloader_h +#define QtFileDownloader_h + +#include <QNetworkReply> +#include <QNetworkRequest> +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> + +QT_BEGIN_NAMESPACE +class QFile; +class QNetworkAccessManager; +class QNetworkRequest; +QT_END_NAMESPACE + +namespace WebCore { +class ResourceError; +} + +namespace WebKit { +class Download; + +class QtFileDownloader : public QObject { + Q_OBJECT +public: + QtFileDownloader(Download*, PassOwnPtr<QNetworkReply>); + virtual ~QtFileDownloader(); + void cancel(); + void init(); + void startTransfer(const QString& destination); + + enum DownloadError { + DownloadErrorAborted = 0, + DownloadErrorCannotWriteToFile, + DownloadErrorCannotOpenFile, + DownloadErrorDestinationAlreadyExists, + DownloadErrorCancelled, + DownloadErrorCannotDetermineFilename, + DownloadErrorNetworkFailure + }; + +private slots: + void onReadyRead(); + void onFinished(); + void onError(QNetworkReply::NetworkError); + +private: + void abortDownloadWritingAndEmitError(QtFileDownloader::DownloadError); + QString determineFilename(); + void handleDownloadResponse(); + + Download* m_download; + OwnPtr<QNetworkReply> m_reply; + OwnPtr<QFile> m_destinationFile; + QNetworkReply::NetworkError m_error; + bool m_headersRead; +}; + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/WebProcess/Downloads/soup/DownloadSoup.cpp b/Source/WebKit2/WebProcess/Downloads/soup/DownloadSoup.cpp new file mode 100644 index 000000000..e43f7a4f7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Downloads/soup/DownloadSoup.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2010, 2011 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 "config.h" +#include "Download.h" + +#include "DataReference.h" +#include <WebCore/ErrorsGtk.h> +#include <WebCore/NotImplemented.h> +#include <gio/gio.h> +#include <glib/gi18n-lib.h> +#include <wtf/gobject/GOwnPtr.h> +#include <wtf/gobject/GRefPtr.h> +#include <wtf/text/CString.h> + +using namespace WebCore; + +namespace WebKit { + +class DownloadClient : public ResourceHandleClient { + WTF_MAKE_NONCOPYABLE(DownloadClient); +public: + DownloadClient(Download* download) + : m_download(download) + { + } + + void downloadFailed(const ResourceError& error) + { + m_download->didFail(error, CoreIPC::DataReference()); + } + + void didReceiveResponse(ResourceHandle*, const ResourceResponse& response) + { + m_response = adoptGRef(response.toSoupMessage()); + m_download->didReceiveResponse(response); + + if (response.httpStatusCode() >= 400) { + downloadFailed(downloadNetworkError(ResourceError(errorDomainDownload, response.httpStatusCode(), + response.url().string(), response.httpStatusText()))); + return; + } + + String suggestedFilename = response.suggestedFilename(); + if (suggestedFilename.isEmpty()) { + KURL url = response.url(); + url.setQuery(String()); + url.removeFragmentIdentifier(); + suggestedFilename = decodeURLEscapeSequences(url.lastPathComponent()); + } + + bool overwrite; + String destinationURI = m_download->decideDestinationWithSuggestedFilename(suggestedFilename.utf8().data(), overwrite); + if (destinationURI.isEmpty()) { + GOwnPtr<char> errorMessage(g_strdup_printf(_("Cannot determine destination URI for download with suggested filename %s"), + suggestedFilename.utf8().data())); + downloadFailed(downloadDestinationError(response, errorMessage.get())); + return; + } + + GRefPtr<GFile> file = adoptGRef(g_file_new_for_uri(destinationURI.utf8().data())); + GOwnPtr<GError> error; + m_outputStream = adoptGRef(g_file_replace(file.get(), 0, TRUE, G_FILE_CREATE_NONE, 0, &error.outPtr())); + if (!m_outputStream) { + downloadFailed(downloadDestinationError(response, error->message)); + return; + } + + m_download->didCreateDestination(destinationURI); + } + + void didReceiveData(ResourceHandle*, const char* data, int length, int /*encodedDataLength*/) + { + gsize bytesWritten; + GOwnPtr<GError> error; + g_output_stream_write_all(G_OUTPUT_STREAM(m_outputStream.get()), data, length, &bytesWritten, 0, &error.outPtr()); + if (error) { + downloadFailed(downloadDestinationError(ResourceResponse(m_response.get()), error->message)); + return; + } + m_download->didReceiveData(bytesWritten); + } + + void didFinishLoading(ResourceHandle*, double) + { + m_outputStream = 0; + m_download->didFinish(); + } + + void didFail(ResourceHandle*, const ResourceError& error) + { + downloadFailed(downloadNetworkError(error)); + } + + void wasBlocked(ResourceHandle*) + { + notImplemented(); + } + + void cannotShowURL(ResourceHandle*) + { + notImplemented(); + } + + Download* m_download; + GRefPtr<GFileOutputStream> m_outputStream; + GRefPtr<SoupMessage> m_response; +}; + +void Download::start(WebPage* initiatingWebPage) +{ + ASSERT(m_downloadClient); + ASSERT(m_resourceHandle); + m_downloadClient = adoptPtr(new DownloadClient(this)); + m_resourceHandle = ResourceHandle::create(0, m_request, m_downloadClient.get(), false, false); + didStart(); +} + +void Download::startWithHandle(WebPage* initiatingPage, ResourceHandle* resourceHandle, const ResourceResponse&) +{ + ASSERT(m_downloadClient); + ASSERT(m_resourceHandle); + m_downloadClient = adoptPtr(new DownloadClient(this)); + resourceHandle->setClient(m_downloadClient.get()); + m_resourceHandle = resourceHandle; + didStart(); +} + +void Download::cancel() +{ + if (!m_resourceHandle) + return; + m_resourceHandle->cancel(); + didCancel(CoreIPC::DataReference()); + m_resourceHandle = 0; +} + +void Download::platformInvalidate() +{ + if (m_resourceHandle) { + m_resourceHandle->setClient(0); + m_resourceHandle->cancel(); + m_resourceHandle = 0; + } + m_downloadClient.release(); +} + +void Download::didDecideDestination(const String& destination, bool allowOverwrite) +{ + notImplemented(); +} + +void Download::platformDidFinish() +{ + m_resourceHandle = 0; +} + +void Download::receivedCredential(const AuthenticationChallenge& authenticationChallenge, const Credential& credential) +{ + notImplemented(); +} + +void Download::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +void Download::receivedCancellation(const AuthenticationChallenge& authenticationChallenge) +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp new file mode 100644 index 000000000..237fd4cf6 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp @@ -0,0 +1,147 @@ +/* + * 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 "config.h" +#include "WebFullScreenManager.h" + +#if ENABLE(FULLSCREEN_API) + +#include "Connection.h" +#include "MessageID.h" +#include "WebCoreArgumentCoders.h" +#include "WebFullScreenManagerProxyMessages.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Color.h> +#include <WebCore/Element.h> +#include <WebCore/Page.h> +#include <WebCore/Settings.h> + +using namespace WebCore; + +namespace WebKit { + +WebFullScreenManager::WebFullScreenManager(WebPage* page) + : m_page(page) +{ +} + +WebFullScreenManager::~WebFullScreenManager() +{ + +} + +WebCore::Element* WebFullScreenManager::element() +{ + return m_element.get(); +} + +void WebFullScreenManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebFullScreenManagerMessage(connection, messageID, arguments); +} + +bool WebFullScreenManager::supportsFullScreen(bool withKeyboard) +{ + if (!m_page->corePage()->settings()->fullScreenEnabled()) + return false; + + return m_page->injectedBundleFullScreenClient().supportsFullScreen(m_page.get(), withKeyboard); + +} + +void WebFullScreenManager::enterFullScreenForElement(WebCore::Element* element) +{ + ASSERT(element); + m_element = element; + m_initialFrame = m_element->screenRect(); + m_page->injectedBundleFullScreenClient().enterFullScreenForElement(m_page.get(), element); +} + +void WebFullScreenManager::exitFullScreenForElement(WebCore::Element* element) +{ + ASSERT(element); + ASSERT(m_element == element); + m_page->injectedBundleFullScreenClient().exitFullScreenForElement(m_page.get(), element); +} + +void WebFullScreenManager::beganEnterFullScreenAnimation() +{ + m_page->send(Messages::WebFullScreenManagerProxy::BeganEnterFullScreenAnimation()); +} + +void WebFullScreenManager::finishedEnterFullScreenAnimation(bool completed) +{ + m_page->send(Messages::WebFullScreenManagerProxy::FinishedEnterFullScreenAnimation(completed)); +} + +void WebFullScreenManager::beganExitFullScreenAnimation() +{ + m_page->send(Messages::WebFullScreenManagerProxy::BeganExitFullScreenAnimation()); +} + +void WebFullScreenManager::finishedExitFullScreenAnimation(bool completed) +{ + m_page->send(Messages::WebFullScreenManagerProxy::FinishedExitFullScreenAnimation(completed)); +} + +IntRect WebFullScreenManager::getFullScreenRect() +{ + IntRect rect; + m_page->sendSync(Messages::WebFullScreenManagerProxy::GetFullScreenRect(), Messages::WebFullScreenManagerProxy::GetFullScreenRect::Reply(rect)); + return rect; +} + +void WebFullScreenManager::willEnterFullScreen() +{ + ASSERT(m_element); + m_element->document()->webkitWillEnterFullScreenForElement(m_element.get()); + m_element->document()->setFullScreenRendererBackgroundColor(Color::transparent); +} + +void WebFullScreenManager::didEnterFullScreen() +{ + ASSERT(m_element); + m_element->document()->setFullScreenRendererBackgroundColor(Color::black); + m_element->document()->webkitDidEnterFullScreenForElement(m_element.get()); +} + +void WebFullScreenManager::willExitFullScreen() +{ + ASSERT(m_element); + m_element->document()->webkitWillExitFullScreenForElement(m_element.get()); + m_element->document()->setFullScreenRendererBackgroundColor(Color::transparent); +} + +void WebFullScreenManager::didExitFullScreen() +{ + ASSERT(m_element); + m_element->document()->webkitDidExitFullScreenForElement(m_element.get()); + m_element->document()->setFullScreenRendererBackgroundColor(Color::black); +} + + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h new file mode 100644 index 000000000..a2b992f8f --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h @@ -0,0 +1,92 @@ +/* + * 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 WebFullScreenManager_h +#define WebFullScreenManager_h + +#if ENABLE(FULLSCREEN_API) + +#include <WebCore/IntRect.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +class MessageID; +} + +namespace WebCore { +class IntRect; +class Element; +class GraphicsLayer; +} + +namespace WebKit { + +class WebPage; + +class WebFullScreenManager : public RefCounted<WebFullScreenManager> { +public: + static PassRefPtr<WebFullScreenManager> create(WebPage*); + virtual ~WebFullScreenManager(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + bool supportsFullScreen(bool withKeyboard); + void enterFullScreenForElement(WebCore::Element*); + void exitFullScreenForElement(WebCore::Element*); + void beganEnterFullScreenAnimation(); + void finishedEnterFullScreenAnimation(bool completed); + void beganExitFullScreenAnimation(); + void finishedExitFullScreenAnimation(bool completed); + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*) = 0; + + void willEnterFullScreen(); + void didEnterFullScreen(); + void willExitFullScreen(); + void didExitFullScreen(); + + WebCore::Element* element(); + +protected: + WebFullScreenManager(WebPage*); + + virtual void beginEnterFullScreenAnimation(float duration) = 0; + virtual void beginExitFullScreenAnimation(float duration) = 0; + virtual void disposeOfLayerClient() { } + WebCore::IntRect getFullScreenRect(); + + void didReceiveWebFullScreenManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + WebCore::IntRect m_initialFrame; + RefPtr<WebPage> m_page; + RefPtr<WebCore::Element> m_element; +}; + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) + +#endif // WebFullScreenManager_h diff --git a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.messages.in b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.messages.in new file mode 100644 index 000000000..82eee3da6 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.messages.in @@ -0,0 +1,33 @@ +# 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. + +#if ENABLE(FULLSCREEN_API) +messages -> WebFullScreenManager { + WillEnterFullScreen() + DidEnterFullScreen() + WillExitFullScreen() + DidExitFullScreen() + BeginEnterFullScreenAnimation(float duration) + BeginExitFullScreenAnimation(float duration) + DisposeOfLayerClient() +} +#endif diff --git a/Source/WebKit2/WebProcess/FullScreen/gtk/WebFullScreenManagerGtk.cpp b/Source/WebKit2/WebProcess/FullScreen/gtk/WebFullScreenManagerGtk.cpp new file mode 100644 index 000000000..5c4e69756 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/gtk/WebFullScreenManagerGtk.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * 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 "WebFullScreenManagerGtk.h" + +#if ENABLE(FULLSCREEN_API) + +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +WebFullScreenManagerGtk::WebFullScreenManagerGtk(WebPage* page) + : WebFullScreenManager(page) +{ +} + +PassRefPtr<WebFullScreenManager> WebFullScreenManager::create(WebPage* page) +{ + return adoptRef(new WebFullScreenManagerGtk(page)); +} + +void WebFullScreenManagerGtk::setRootFullScreenLayer(WebCore::GraphicsLayer* layer) +{ + notImplemented(); +} + +void WebFullScreenManagerGtk::beginEnterFullScreenAnimation(float duration) +{ + notImplemented(); +} + +void WebFullScreenManagerGtk::beginExitFullScreenAnimation(float duration) +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/FullScreen/gtk/WebFullScreenManagerGtk.h b/Source/WebKit2/WebProcess/FullScreen/gtk/WebFullScreenManagerGtk.h new file mode 100644 index 000000000..51f5527fc --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/gtk/WebFullScreenManagerGtk.h @@ -0,0 +1,50 @@ +/* + * 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 WebFullScreenManagerGtk_h +#define WebFullScreenManagerGtk_h + +#if ENABLE(FULLSCREEN_API) + +#include "WebFullScreenManager.h" + +namespace WebKit { + +class WebFullScreenManagerGtk : public WebFullScreenManager { +public: + WebFullScreenManagerGtk(WebPage*); + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*); + +private: + virtual void beginEnterFullScreenAnimation(float duration); + virtual void beginExitFullScreenAnimation(float duration); + +}; + +} + +#endif // ENABLE(FULLSCREEN_API) + +#endif // WebFullScreenManagerGtk_h diff --git a/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h new file mode 100644 index 000000000..27e8aff20 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.h @@ -0,0 +1,71 @@ +/* + * 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 WebFullScreenManagerMac_h +#define WebFullScreenManagerMac_h + +#if ENABLE(FULLSCREEN_API) + +#import "LayerTreeContext.h" +#import "WebFullScreenManager.h" + +#import <WebCore/GraphicsLayer.h> +#import <WebCore/IntRect.h> +#import <wtf/RetainPtr.h> + +typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef; +OBJC_CLASS WebFullScreenManagerAnimationListener; + +namespace WebKit { + +class WebFullScreenManagerMac : public WebFullScreenManager { +public: + static PassRefPtr<WebFullScreenManagerMac> create(WebPage*); + + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*); + +private: + WebFullScreenManagerMac(WebPage*); + virtual ~WebFullScreenManagerMac(); + + virtual void beginEnterFullScreenAnimation(float duration); + virtual void beginExitFullScreenAnimation(float duration); + virtual void disposeOfLayerClient(); + + void animateFullScreen(const CATransform3D& startTransform, const CATransform3D& endTransform, float duration, id listener); + CATransform3D windowedCGTransform(); + + OwnPtr<WebCore::GraphicsLayer> m_rootLayer; + LayerTreeContext m_layerTreeContext; + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; + RetainPtr<id> m_enterFullScreenListener; + RetainPtr<id> m_exitFullScreenListener; +}; + +} + +#endif // ENABLE(FULLSCREEN_API) + +#endif // WebFullScreenManagerMac_h diff --git a/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm new file mode 100644 index 000000000..07060078d --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/mac/WebFullScreenManagerMac.mm @@ -0,0 +1,311 @@ +/* + * 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 "config.h" +#import "WebFullScreenManagerMac.h" + +#if ENABLE(FULLSCREEN_API) + +#import "Connection.h" +#import "LayerTreeContext.h" +#import "MessageID.h" +#import "WebFullScreenManagerProxyMessages.h" +#import "WebPage.h" +#import "WebProcess.h" +#import <QuartzCore/QuartzCore.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/GraphicsLayer.h> +#import <WebCore/Page.h> +#import <WebCore/RenderLayer.h> +#import <WebCore/RenderLayerBacking.h> +#import <WebCore/RenderObject.h> +#import <WebCore/Settings.h> +#import <WebKitSystemInterface.h> + +using namespace WebCore; + +typedef void (WebKit::WebFullScreenManager::*AnimationBeganFunction)(); +typedef void (WebKit::WebFullScreenManager::*AnimationFinishedFunction)(bool); + +#if defined(BUILDING_ON_LEOPARD) +@interface CATransaction(SnowLeopardConvenienceFunctions) ++ (void)setDisableActions:(BOOL)flag; +@end + +@implementation CATransaction(SnowLeopardConvenienceFunctions) ++ (void)setDisableActions:(BOOL)flag +{ + [self setValue:[NSNumber numberWithBool:flag] forKey:kCATransactionDisableActions]; +} +@end +#endif + +@interface WKFullScreenManagerAnimationListener : NSObject { + WebKit::WebFullScreenManager* _manager; + AnimationBeganFunction _began; + AnimationFinishedFunction _finished; +} +- (id)initWithManager:(WebKit::WebFullScreenManager*)manager began:(AnimationBeganFunction)began finished:(AnimationFinishedFunction)finished; +- (void)animationDidStart:(CAAnimation *)anim; +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; +- (void)invalidate; +@end + +@implementation WKFullScreenManagerAnimationListener +- (id)initWithManager:(WebKit::WebFullScreenManager*)manager began:(AnimationBeganFunction)began finished:(AnimationFinishedFunction)finished +{ + self = [super init]; + if (!self) + return nil; + + _manager = manager; + _began = began; + _finished = finished; + return self; +} + +- (void)animationDidStart:(CAAnimation *)anim +{ + if (_manager && _began) + (_manager->*_began)(); +} + +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag +{ + if (_manager && _finished) + (_manager->*_finished)(flag); +} + +- (void)invalidate +{ + _manager = 0; + _began = 0; + _finished = 0; +} +@end + +namespace WebKit { + +PassRefPtr<WebFullScreenManager> WebFullScreenManager::create(WebPage* page) +{ + return WebFullScreenManagerMac::create(page); +} + +PassRefPtr<WebFullScreenManagerMac> WebFullScreenManagerMac::create(WebPage* page) +{ + return adoptRef(new WebFullScreenManagerMac(page)); +} + +WebFullScreenManagerMac::WebFullScreenManagerMac(WebPage* page) + : WebFullScreenManager(page) +{ + m_enterFullScreenListener.adoptNS([[WKFullScreenManagerAnimationListener alloc] initWithManager:this began:&WebFullScreenManagerMac::beganEnterFullScreenAnimation finished:&WebFullScreenManagerMac::finishedEnterFullScreenAnimation]); + m_exitFullScreenListener.adoptNS([[WKFullScreenManagerAnimationListener alloc] initWithManager:this began:&WebFullScreenManagerMac::beganExitFullScreenAnimation finished:&WebFullScreenManagerMac::finishedExitFullScreenAnimation]); +} + +WebFullScreenManagerMac::~WebFullScreenManagerMac() +{ + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + [m_enterFullScreenListener.get() invalidate]; + [m_exitFullScreenListener.get() invalidate]; +} + +void WebFullScreenManagerMac::setRootFullScreenLayer(WebCore::GraphicsLayer* layer) +{ + if (!m_rootLayer && !layer) + return; + + if (!layer) { + PlatformLayer* rootPlatformLayer = m_rootLayer->platformLayer(); + [[NSNotificationCenter defaultCenter] postNotificationName:@"WebKitLayerHostChanged" object:rootPlatformLayer userInfo:nil]; + m_rootLayer->removeAllChildren(); + m_rootLayer->syncCompositingStateForThisLayerOnly(); + m_rootLayer = nullptr; + + m_page->forceRepaintWithoutCallback(); + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + return; + } + + if (m_rootLayer && m_rootLayer->children().contains(layer)) + return; + + if (!m_rootLayer) { + mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); + m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort); + + m_rootLayer = GraphicsLayer::create(NULL); +#ifndef NDEBUG + m_rootLayer->setName("Full screen root layer"); +#endif + m_rootLayer->setDrawsContent(false); + m_rootLayer->setSize(getFullScreenRect().size()); + + [m_rootLayer->platformLayer() setGeometryFlipped:YES]; + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer->platformLayer()); + m_layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); + m_page->send(Messages::WebFullScreenManagerProxy::EnterAcceleratedCompositingMode(m_layerTreeContext)); + } + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + m_rootLayer->removeAllChildren(); + m_rootLayer->addChild(layer); + m_rootLayer->syncCompositingState(getFullScreenRect()); + [CATransaction commit]; + + [[NSNotificationCenter defaultCenter] postNotificationName:@"WebKitLayerHostChanged" object:m_rootLayer->platformLayer() userInfo:nil]; +} + +void WebFullScreenManagerMac::disposeOfLayerClient() +{ + if (!m_remoteLayerClient) + return; + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), 0); + WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get()); + m_remoteLayerClient = nullptr; +} + +void WebFullScreenManagerMac::beginEnterFullScreenAnimation(float duration) +{ + ASSERT(m_element); + + if (!m_rootLayer || m_rootLayer->children().isEmpty()) { + // If we don't have a root layer, we can't animate in and out of full screen + m_page->send(Messages::WebFullScreenManagerProxy::EnterAcceleratedCompositingMode(m_layerTreeContext)); + this->beganEnterFullScreenAnimation(); + this->finishedEnterFullScreenAnimation(true); + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + return; + } + + IntRect destinationFrame = getFullScreenRect(); + m_element->document()->setFullScreenRendererSize(destinationFrame.size()); + m_rootLayer->syncCompositingState(destinationFrame); + + // FIXME: Once we gain the ability to do native WebKit animations of generated + // content, this can change to use them. Meanwhile, we'll have to animate the + // CALayer directly. + animateFullScreen(windowedCGTransform(), CATransform3DIdentity, duration, m_enterFullScreenListener.get()); +} + +void WebFullScreenManagerMac::beginExitFullScreenAnimation(float duration) +{ + ASSERT(m_element); + + if (!m_rootLayer || m_rootLayer->children().isEmpty()) { + // If we don't have a root layer, we can't animate in and out of full screen + m_page->send(Messages::WebFullScreenManagerProxy::EnterAcceleratedCompositingMode(m_layerTreeContext)); + this->beganExitFullScreenAnimation(); + this->finishedExitFullScreenAnimation(true); + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + return; + } + + IntRect destinationFrame = getFullScreenRect(); + m_element->document()->setFullScreenRendererSize(destinationFrame.size()); + m_rootLayer->syncCompositingState(destinationFrame); + + // FIXME: Once we gain the ability to do native WebKit animations of generated + // content, this can change to use them. Meanwhile, we'll have to animate the + // CALayer directly. + CALayer* caLayer = m_rootLayer->children().first()->platformLayer(); + CALayer* presentationLayer = [caLayer presentationLayer] ? (CALayer*)[caLayer presentationLayer] : caLayer; + animateFullScreen([presentationLayer transform], windowedCGTransform(), duration, m_exitFullScreenListener.get()); +} + +void WebFullScreenManagerMac::animateFullScreen(const CATransform3D& startTransform, const CATransform3D& endTransform, float duration, id listener) +{ + // This is the full size of the screen. + IntRect fullScreenRect = getFullScreenRect(); + CALayer* caLayer = m_rootLayer->children().first()->platformLayer(); + + // This animation represents the zoom effect. + CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; + [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:startTransform]]; + [zoomAnimation setToValue:[NSValue valueWithCATransform3D:endTransform]]; + + // This animation provides a position correction to the CALayer, which might be offset based on the page's + // scroll position. We animate it instead of just setting the property because others might try to + // alter its position while the animation is playing. + CGPoint layerAnchor = [caLayer anchorPoint]; + CGPoint fullScreenPosition = CGPointMake( + fullScreenRect.x() + fullScreenRect.width() * layerAnchor.x, + fullScreenRect.y() + fullScreenRect.height() * layerAnchor.y); + CABasicAnimation* positionCorrection = [CABasicAnimation animationWithKeyPath:@"position"]; + [positionCorrection setFromValue:[NSValue valueWithPoint:NSPointFromCGPoint(fullScreenPosition)]]; + [positionCorrection setToValue:[NSValue valueWithPoint:NSPointFromCGPoint(fullScreenPosition)]]; + + // We want to be notified that the animation has completed by way of the CAAnimation delegate. + CAAnimationGroup* transitionAnimation = [CAAnimationGroup animation]; + [transitionAnimation setAnimations:[NSArray arrayWithObjects:zoomAnimation, positionCorrection, nil]]; + [transitionAnimation setDelegate:listener]; + [transitionAnimation setDuration:duration]; + [transitionAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; + [transitionAnimation setFillMode:kCAFillModeForwards]; + [transitionAnimation setRemovedOnCompletion:NO]; + + // Disable implicit animations and set the layer's transformation matrix to its final state. + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [caLayer addAnimation:transitionAnimation forKey:@"zoom"]; + [CATransaction commit]; +} + +CATransform3D WebFullScreenManagerMac::windowedCGTransform() +{ + IntRect fullScreenRect = getFullScreenRect(); + RenderLayer* layer = m_element->renderer() ? m_element->renderer()->enclosingLayer() : 0; + RenderLayerBacking* backing = layer ? layer->backing() : 0; + IntSize fullScreenSize = fullScreenRect.size(); + if (backing) + fullScreenSize = backing->contentsBox().size(); + + CALayer* caLayer = m_rootLayer->children().first()->platformLayer(); + + // Create a transformation matrix that will transform the renderer layer such that + // the fullscreen element appears to move from its starting position and size to its + // final one. + CGPoint layerAnchor = [caLayer anchorPoint]; + CGPoint fullScreenPosition = CGPointMake( + fullScreenRect.x() + fullScreenRect.width() * layerAnchor.x, + fullScreenRect.y() + fullScreenRect.height() * layerAnchor.y); //[presentationLayer position]; + CGPoint windowedPosition = CGPointMake( + m_initialFrame.x() + m_initialFrame.width() * layerAnchor.x, + m_initialFrame.y() + m_initialFrame.height() * layerAnchor.y); + CATransform3D shrinkTransform = CATransform3DMakeScale( + static_cast<CGFloat>(m_initialFrame.width()) / fullScreenSize.width(), + static_cast<CGFloat>(m_initialFrame.height()) / fullScreenSize.height(), 1); + CATransform3D shiftTransform = CATransform3DMakeTranslation( + windowedPosition.x - fullScreenPosition.x, + // Drawing is flipped here, and so must be the translation transformation + fullScreenPosition.y - windowedPosition.y, 0); + + return CATransform3DConcat(shrinkTransform, shiftTransform); +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/FullScreen/qt/WebFullScreenManagerQt.cpp b/Source/WebKit2/WebProcess/FullScreen/qt/WebFullScreenManagerQt.cpp new file mode 100644 index 000000000..5467e5661 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/qt/WebFullScreenManagerQt.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 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 "WebFullScreenManagerQt.h" + +#if ENABLE(FULLSCREEN_API) + +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +WebFullScreenManagerQt::WebFullScreenManagerQt(WebPage* page) + : WebFullScreenManager(page) +{ +} + +PassRefPtr<WebFullScreenManager> WebFullScreenManager::create(WebPage* page) +{ + return adoptRef(new WebFullScreenManagerQt(page)); +} + +void WebFullScreenManagerQt::setRootFullScreenLayer(WebCore::GraphicsLayer* layer) +{ + notImplemented(); +} + +void WebFullScreenManagerQt::beginEnterFullScreenAnimation(float duration) +{ + notImplemented(); +} + +void WebFullScreenManagerQt::beginExitFullScreenAnimation(float duration) +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/FullScreen/qt/WebFullScreenManagerQt.h b/Source/WebKit2/WebProcess/FullScreen/qt/WebFullScreenManagerQt.h new file mode 100644 index 000000000..8281f36f8 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/qt/WebFullScreenManagerQt.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 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 WebFullScreenManagerQt_h +#define WebFullScreenManagerQt_h + +#if ENABLE(FULLSCREEN_API) + +#include "WebFullScreenManager.h" + +namespace WebKit { + +class WebFullScreenManagerQt : public WebFullScreenManager { +public: + WebFullScreenManagerQt(WebPage*); + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*); + +private: + virtual void beginEnterFullScreenAnimation(float duration); + virtual void beginExitFullScreenAnimation(float duration); + +}; + +} + +#endif // ENABLE(FULLSCREEN_API) + +#endif // WebFullScreenManagerQt_h diff --git a/Source/WebKit2/WebProcess/FullScreen/win/WebFullScreenManagerWin.cpp b/Source/WebKit2/WebProcess/FullScreen/win/WebFullScreenManagerWin.cpp new file mode 100644 index 000000000..28ea54b70 --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/win/WebFullScreenManagerWin.cpp @@ -0,0 +1,113 @@ +/* + * 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 "config.h" +#include "WebFullScreenManagerWin.h" + +#if ENABLE(FULLSCREEN_API) + +#include "MessageID.h" +#include "WebFullScreenManagerProxyMessages.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayer.h> +#include <WebCore/Page.h> +#include <WebKitSystemInterface/WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<WebFullScreenManager> WebFullScreenManager::create(WebPage* page) +{ + return WebFullScreenManagerWin::create(page); +} + +PassRefPtr<WebFullScreenManagerWin> WebFullScreenManagerWin::create(WebPage* page) +{ + return adoptRef(new WebFullScreenManagerWin(page)); +} + +WebFullScreenManagerWin::WebFullScreenManagerWin(WebPage* page) + : WebFullScreenManager(page) +{ +} + +WebFullScreenManagerWin::~WebFullScreenManagerWin() +{ + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); +} + +void WebFullScreenManagerWin::setRootFullScreenLayer(WebCore::GraphicsLayer* layer) +{ + // Host the full screen layer if its given to us; otherwise it will be disconnected + // from the layer heirarchy and cause an ASSERT during resync. + // FIXME: Disable setting RenderLayer::setAnimating() to make this unnecessary. + if (m_fullScreenRootLayer == layer) + return; + m_fullScreenRootLayer = layer; + + if (!m_fullScreenRootLayer) { + m_page->send(Messages::WebFullScreenManagerProxy::ExitAcceleratedCompositingMode()); + if (m_rootLayer) { + m_rootLayer->removeAllChildren(); + m_rootLayer = nullptr; + } + return; + } + + if (!m_rootLayer) { + m_rootLayer = GraphicsLayer::create(0); +#ifndef NDEBUG + m_rootLayer->setName("Full screen root layer"); +#endif + m_rootLayer->setDrawsContent(false); + m_rootLayer->setSize(getFullScreenRect().size()); + } + + m_rootLayer->removeAllChildren(); + + if (m_fullScreenRootLayer) + m_rootLayer->addChild(m_fullScreenRootLayer); + + m_rootLayer->syncCompositingStateForThisLayerOnly(); + m_page->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); +} + +void WebFullScreenManagerWin::beginEnterFullScreenAnimation(float) +{ + // FIXME: Add support for animating the content into full screen. +} + +void WebFullScreenManagerWin::beginExitFullScreenAnimation(float) +{ + // FIXME: Add support for animating the content into full screen. +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/FullScreen/win/WebFullScreenManagerWin.h b/Source/WebKit2/WebProcess/FullScreen/win/WebFullScreenManagerWin.h new file mode 100644 index 000000000..22f74f1cf --- /dev/null +++ b/Source/WebKit2/WebProcess/FullScreen/win/WebFullScreenManagerWin.h @@ -0,0 +1,57 @@ +/* + * 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 WebFullScreenManagerWin_h +#define WebFullScreenManagerWin_h + +#if ENABLE(FULLSCREEN_API) + +#include "WebFullScreenManager.h" + +#include <WebCore/IntRect.h> + +namespace WebKit { + +class WebFullScreenManagerWin : public WebFullScreenManager { +public: + static PassRefPtr<WebFullScreenManagerWin> create(WebPage*); + +private: + WebFullScreenManagerWin(WebPage*); + virtual ~WebFullScreenManagerWin(); + + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*); + virtual void beginEnterFullScreenAnimation(float duration); + virtual void beginExitFullScreenAnimation(float duration); + + OwnPtr<WebCore::GraphicsLayer> m_rootLayer; + WebCore::GraphicsLayer* m_fullScreenRootLayer; +}; + +} + +#endif // ENABLE(FULLSCREEN_API) + +#endif // WebFullScreenManagerWin_h diff --git a/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp new file mode 100644 index 000000000..1ac23b1d7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp @@ -0,0 +1,91 @@ +/* + * 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 "config.h" +#include "GeolocationPermissionRequestManager.h" + +#include "WebCoreArgumentCoders.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 000000000..5e37163e7 --- /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 000000000..cee8e0bac --- /dev/null +++ b/Source/WebKit2/WebProcess/Geolocation/WebGeolocationManager.cpp @@ -0,0 +1,112 @@ +/* + * 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 "config.h" +#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 000000000..78fbd5acf --- /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 000000000..f2e9a9da9 --- /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/IconDatabase/WebIconDatabaseProxy.cpp b/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.cpp new file mode 100644 index 000000000..02077912b --- /dev/null +++ b/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.cpp @@ -0,0 +1,151 @@ +/* + * 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 "config.h" +#include "WebIconDatabaseProxy.h" + +#include "DataReference.h" +#include "MessageID.h" +#include "WebIconDatabaseMessages.h" +#include "WebProcess.h" +#include <WebCore/SharedBuffer.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +WebIconDatabaseProxy::~WebIconDatabaseProxy() +{ +} + +WebIconDatabaseProxy::WebIconDatabaseProxy(WebProcess* process) + : m_isEnabled(false) + , m_process(process) +{ +} + +bool WebIconDatabaseProxy::isEnabled() const +{ + return m_isEnabled; +} + +void WebIconDatabaseProxy::setEnabled(bool enabled) +{ + if (enabled == m_isEnabled) + return; + + m_isEnabled = enabled; + setGlobalIconDatabase(enabled ? this : 0); +} + + +void WebIconDatabaseProxy::retainIconForPageURL(const String& pageURL) +{ + m_process->connection()->send(Messages::WebIconDatabase::RetainIconForPageURL(pageURL), 0); +} + +void WebIconDatabaseProxy::releaseIconForPageURL(const String& pageURL) +{ + m_process->connection()->send(Messages::WebIconDatabase::ReleaseIconForPageURL(pageURL), 0); +} + +Image* WebIconDatabaseProxy::synchronousIconForPageURL(const String& pageURL, const IntSize& size) +{ + CoreIPC::DataReference result; + if (!m_process->connection()->sendSync(Messages::WebIconDatabase::SynchronousIconDataForPageURL(pageURL), Messages::WebIconDatabase::SynchronousIconDataForPageURL::Reply(result), 0)) + return 0; + + // FIXME: Return Image created with the above data. + return 0; +} + + +String WebIconDatabaseProxy::synchronousIconURLForPageURL(const String& pageURL) +{ + // FIXME: This needs to ask the UI process for the iconURL, but it can't do so synchronously because it will slow down page loading. + // The parts in WebCore that need this data will have to be changed to work asycnchronously. + return String(); +} + +bool WebIconDatabaseProxy::synchronousIconDataKnownForIconURL(const String& iconURL) +{ + // FIXME: This needs to ask the UI process for the iconURL, but it can't do so synchronously because it will slow down page loading. + // The parts in WebCore that need this data will have to be changed to work asycnchronously. + return false; +} + +IconLoadDecision WebIconDatabaseProxy::synchronousLoadDecisionForIconURL(const String& iconURL, DocumentLoader* documentLoader) +{ + // FIXME: This needs to ask the UI process for the iconURL, but it can't do so synchronously because it will slow down page loading. + // The parts in WebCore that need this data will have to be changed to work asycnchronously. + return IconLoadNo; +} + +bool WebIconDatabaseProxy::supportsAsynchronousMode() +{ + return true; +} + +void WebIconDatabaseProxy::loadDecisionForIconURL(const String& iconURL, PassRefPtr<WebCore::IconLoadDecisionCallback> callback) +{ + uint64_t id = callback->callbackID(); + m_iconLoadDecisionCallbacks.add(id, callback); + + m_process->connection()->send(Messages::WebIconDatabase::GetLoadDecisionForIconURL(iconURL, id), 0); +} + +void WebIconDatabaseProxy::receivedIconLoadDecision(int decision, uint64_t callbackID) +{ + RefPtr<WebCore::IconLoadDecisionCallback> callback = m_iconLoadDecisionCallbacks.take(callbackID); + if (callback) + callback->performCallback(static_cast<WebCore::IconLoadDecision>(decision)); +} + +void WebIconDatabaseProxy::iconDataForIconURL(const String& iconURL, PassRefPtr<WebCore::IconDataCallback> callback) +{ +} + +void WebIconDatabaseProxy::setIconURLForPageURL(const String& iconURL, const String& pageURL) +{ + m_process->connection()->send(Messages::WebIconDatabase::SetIconURLForPageURL(iconURL, pageURL), 0); +} + +void WebIconDatabaseProxy::setIconDataForIconURL(PassRefPtr<SharedBuffer> iconData, const String& iconURL) +{ + CoreIPC::DataReference data(reinterpret_cast<const uint8_t*>(iconData ? iconData->data() : 0), iconData ? iconData->size() : 0); + m_process->connection()->send(Messages::WebIconDatabase::SetIconDataForIconURL(data, iconURL), 0); +} + +void WebIconDatabaseProxy::urlImportFinished() +{ +} + +void WebIconDatabaseProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebIconDatabaseProxyMessage(connection, messageID, arguments); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.h b/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.h new file mode 100644 index 000000000..2096aba4c --- /dev/null +++ b/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.h @@ -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. + */ + +#ifndef WebIconDatabaseProxy_h +#define WebIconDatabaseProxy_h + +#include "APIObject.h" + +#include <WebCore/IconDatabaseBase.h> + +#include <wtf/HashMap.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +class MessageID; +} + +namespace WebKit { + +class WebProcess; + +class WebIconDatabaseProxy : public WebCore::IconDatabaseBase { +public: + explicit WebIconDatabaseProxy(WebProcess*); + virtual ~WebIconDatabaseProxy(); + + virtual bool isEnabled() const; + void setEnabled(bool); + + + virtual void retainIconForPageURL(const String&); + virtual void releaseIconForPageURL(const String&); + virtual void setIconURLForPageURL(const String&, const String&); + virtual void setIconDataForIconURL(PassRefPtr<WebCore::SharedBuffer>, const String&); + + virtual String synchronousIconURLForPageURL(const String&); + virtual bool synchronousIconDataKnownForIconURL(const String&); + virtual WebCore::IconLoadDecision synchronousLoadDecisionForIconURL(const String&, WebCore::DocumentLoader*); + virtual WebCore::Image* synchronousIconForPageURL(const String&, const WebCore::IntSize&); + + // Asynchronous calls we should use to replace the above when supported. + virtual bool supportsAsynchronousMode(); + virtual void loadDecisionForIconURL(const String&, PassRefPtr<WebCore::IconLoadDecisionCallback>); + void receivedIconLoadDecision(int decision, uint64_t callbackID); + virtual void iconDataForIconURL(const String&, PassRefPtr<WebCore::IconDataCallback>); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + void didReceiveWebIconDatabaseProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + // Callbacks from the UIProcess + void urlImportFinished(); + + bool m_isEnabled; + WebProcess* m_process; + + HashMap<uint64_t, RefPtr<WebCore::IconLoadDecisionCallback> > m_iconLoadDecisionCallbacks; +}; + +} // namespace WebKit + +#endif // WebIconDatabaseProxy_h diff --git a/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.messages.in b/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.messages.in new file mode 100644 index 000000000..049a0d918 --- /dev/null +++ b/Source/WebKit2/WebProcess/IconDatabase/WebIconDatabaseProxy.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 -> WebIconDatabaseProxy { + URLImportFinished() + ReceivedIconLoadDecision(int loadDecision, uint64_t callbackID) +} diff --git a/Source/WebKit2/WebProcess/Info.plist b/Source/WebKit2/WebProcess/Info.plist new file mode 100644 index 000000000..fcb76e974 --- /dev/null +++ b/Source/WebKit2/WebProcess/Info.plist @@ -0,0 +1,32 @@ +<?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>CFBundleExecutable</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>${BUNDLE_VERSION}, Copyright 2003-2012 Apple Inc.</string> + <key>CFBundleIconFile</key> + <string>${APP_ICON}</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>LSFileQuarantineEnabled</key> + <true/> + <key>LSMinimumSystemVersion</key> + <string>${MACOSX_DEPLOYMENT_TARGET}</string> + <key>LSUIElement</key> + <true/> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</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 000000000..d88281e1b --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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) +{ + 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()); +} + +WKConnectionRef WKBundleGetApplicationConnection(WKBundleRef bundleRef) +{ + return toAPI(toImpl(bundleRef)->webConnectionToUIProcess()); +} + +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 WKBundleSetAllowUniversalAccessFromFileURLs(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setAllowUniversalAccessFromFileURLs(toImpl(pageGroupRef), enabled); +} + +void WKBundleSetAllowFileAccessFromFileURLs(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setAllowFileAccessFromFileURLs(toImpl(pageGroupRef), enabled); +} + +void WKBundleSetFrameFlatteningEnabled(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setFrameFlatteningEnabled(toImpl(pageGroupRef), enabled); +} + +void WKBundleSetJavaScriptCanAccessClipboard(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setJavaScriptCanAccessClipboard(toImpl(pageGroupRef), enabled); +} + +void WKBundleSetPrivateBrowsingEnabled(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setPrivateBrowsingEnabled(toImpl(pageGroupRef), enabled); +} + +void WKBundleSwitchNetworkLoaderToNewTestingSession(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->switchNetworkLoaderToNewTestingSession(); +} + +void WKBundleSetAuthorAndUserStylesEnabled(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setAuthorAndUserStylesEnabled(toImpl(pageGroupRef), enabled); +} + +void WKBundleAddOriginAccessWhitelistEntry(WKBundleRef bundleRef, WKStringRef sourceOrigin, WKStringRef destinationProtocol, WKStringRef destinationHost, bool allowDestinationSubdomains) +{ + toImpl(bundleRef)->addOriginAccessWhitelistEntry(toImpl(sourceOrigin)->string(), toImpl(destinationProtocol)->string(), toImpl(destinationHost)->string(), allowDestinationSubdomains); +} + +void WKBundleRemoveOriginAccessWhitelistEntry(WKBundleRef bundleRef, WKStringRef sourceOrigin, WKStringRef destinationProtocol, WKStringRef destinationHost, bool allowDestinationSubdomains) +{ + toImpl(bundleRef)->removeOriginAccessWhitelistEntry(toImpl(sourceOrigin)->string(), toImpl(destinationProtocol)->string(), toImpl(destinationHost)->string(), allowDestinationSubdomains); +} + +void WKBundleResetOriginAccessWhitelists(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->resetOriginAccessWhitelists(); +} + +void WKBundleReportException(JSContextRef context, JSValueRef exception) +{ + InjectedBundle::reportException(context, exception); +} + +void WKBundleClearAllDatabases(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->clearAllDatabases(); +} + +void WKBundleSetDatabaseQuota(WKBundleRef bundleRef, uint64_t quota) +{ + toImpl(bundleRef)->setDatabaseQuota(quota); +} + +void WKBundleClearApplicationCache(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->clearApplicationCache(); +} + +void WKBundleSetAppCacheMaximumSize(WKBundleRef bundleRef, uint64_t size) +{ + toImpl(bundleRef)->setAppCacheMaximumSize(size); +} + +int WKBundleNumberOfPages(WKBundleRef bundleRef, WKBundleFrameRef frameRef, double pageWidthInPixels, double pageHeightInPixels) +{ + return toImpl(bundleRef)->numberOfPages(toImpl(frameRef), pageWidthInPixels, pageHeightInPixels); +} + +int WKBundlePageNumberForElementById(WKBundleRef bundleRef, WKBundleFrameRef frameRef, WKStringRef idRef, double pageWidthInPixels, double pageHeightInPixels) +{ + return toImpl(bundleRef)->pageNumberForElementById(toImpl(frameRef), toImpl(idRef)->string(), pageWidthInPixels, pageHeightInPixels); +} + +WKStringRef WKBundlePageSizeAndMarginsInPixels(WKBundleRef bundleRef, WKBundleFrameRef frameRef, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) +{ + return toCopiedAPI(toImpl(bundleRef)->pageSizeAndMarginsInPixels(toImpl(frameRef), pageIndex, width, height, marginTop, marginRight, marginBottom, marginLeft)); +} + +bool WKBundleIsPageBoxVisible(WKBundleRef bundleRef, WKBundleFrameRef frameRef, int pageIndex) +{ + return toImpl(bundleRef)->isPageBoxVisible(toImpl(frameRef), pageIndex); +} + +bool WKBundleIsProcessingUserGesture(WKBundleRef) +{ + return InjectedBundle::isProcessingUserGesture(); +} 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 000000000..9e273bae3 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.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 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; + +enum { kWKBundleClientCurrentVersion = 0 }; + +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 WKConnectionRef WKBundleGetApplicationConnection(WKBundleRef bundle); + +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 000000000..db32716c1 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleAPICast.h @@ -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. + */ + +#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 InjectedBundleNavigationAction; +class InjectedBundleNodeHandle; +class InjectedBundleRangeHandle; +class InjectedBundleScriptWorld; +class PageOverlay; +class WebFrame; +class WebInspector; +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(WKBundleInspectorRef, WebInspector) +WK_ADD_API_MAPPING(WKBundleNavigationActionRef, InjectedBundleNavigationAction) +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 000000000..7ffa3ce1c --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardList.cpp @@ -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. + */ + +#include "config.h" +#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 000000000..7aa573aa6 --- /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 000000000..e9845e355 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleBackForwardListItem.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. + */ + +#include "config.h" +#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 000000000..f256464e6 --- /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 000000000..df729bff5 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKBundleFrame.h" +#include "WKBundleFramePrivate.h" + +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WKData.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()); +} + +WKFrameLoadState WKBundleFrameGetFrameLoadState(WKBundleFrameRef frameRef) +{ + Frame* coreFrame = toImpl(frameRef)->coreFrame(); + if (!coreFrame) + return kWKFrameLoadStateFinished; + + FrameLoader* loader = coreFrame->loader(); + if (!loader) + return kWKFrameLoadStateFinished; + + switch (loader->state()) { + case FrameStateProvisional: + return kWKFrameLoadStateProvisional; + case FrameStateCommittedPage: + return kWKFrameLoadStateCommitted; + case FrameStateComplete: + return kWKFrameLoadStateFinished; + } + + ASSERT_NOT_REACHED(); + return kWKFrameLoadStateFinished; +} + +WKArrayRef WKBundleFrameCopyChildFrames(WKBundleFrameRef frameRef) +{ + return toAPI(toImpl(frameRef)->childFrames().leakRef()); +} + +unsigned WKBundleFrameGetNumberOfActiveAnimations(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->numberOfActiveAnimations(); +} + +bool WKBundleFramePauseAnimationOnElementWithId(WKBundleFrameRef frameRef, WKStringRef animationName, WKStringRef elementID, double time) +{ + return toImpl(frameRef)->pauseAnimationOnElementWithId(toImpl(animationName)->string(), toImpl(elementID)->string(), time); +} + +bool WKBundleFramePauseTransitionOnElementWithId(WKBundleFrameRef frameRef, WKStringRef propertyName, WKStringRef elementID, double time) +{ + return toImpl(frameRef)->pauseTransitionOnElementWithId(toImpl(propertyName)->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(); +} + +WKBundleFrameRef WKBundleFrameForJavaScriptContext(JSContextRef context) +{ + return toAPI(WebFrame::frameForContext(context)); +} + +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()); +} + +void WKBundleFrameClearOpener(WKBundleFrameRef frameRef) +{ + Frame* coreFrame = toImpl(frameRef)->coreFrame(); + if (coreFrame) + coreFrame->loader()->setOpener(0); +} + +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) +{ + return toAPI(toImpl(frameRef)->contentBounds()); +} + +WKRect WKBundleFrameGetVisibleContentBounds(WKBundleFrameRef frameRef) +{ + return toAPI(toImpl(frameRef)->visibleContentBounds()); +} + +WKRect WKBundleFrameGetVisibleContentBoundsExcludingScrollbars(WKBundleFrameRef frameRef) +{ + return toAPI(toImpl(frameRef)->visibleContentBoundsExcludingScrollbars()); +} + +WKSize WKBundleFrameGetScrollOffset(WKBundleFrameRef frameRef) +{ + return toAPI(toImpl(frameRef)->scrollOffset()); +} + +bool WKBundleFrameHasHorizontalScrollbar(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->hasHorizontalScrollbar(); +} + +bool WKBundleFrameHasVerticalScrollbar(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->hasVerticalScrollbar(); +} + +bool WKBundleFrameGetDocumentBackgroundColor(WKBundleFrameRef frameRef, double* red, double* green, double* blue, double* alpha) +{ + return toImpl(frameRef)->getDocumentBackgroundColor(red, green, blue, alpha); +} + +WKStringRef WKBundleFrameCopySuggestedFilenameForResourceWithURL(WKBundleFrameRef frameRef, WKURLRef urlRef) +{ + return toCopiedAPI(toImpl(frameRef)->suggestedFilenameForResourceWithURL(WebCore::KURL(WebCore::KURL(), toImpl(urlRef)->string()))); +} + +WKStringRef WKBundleFrameCopyMIMETypeForResourceWithURL(WKBundleFrameRef frameRef, WKURLRef urlRef) +{ + return toCopiedAPI(toImpl(frameRef)->mimeTypeForResourceWithURL(WebCore::KURL(WebCore::KURL(), toImpl(urlRef)->string()))); +} + +bool WKBundleFrameContainsAnyFormElements(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->containsAnyFormElements(); +} + +void WKBundleFrameSetTextDirection(WKBundleFrameRef frameRef, WKStringRef directionRef) +{ + toImpl(frameRef)->setTextDirection(toImpl(directionRef)->string()); +} + +WKDataRef WKBundleFrameCopyWebArchive(WKBundleFrameRef frameRef) +{ +#if PLATFORM(MAC) || PLATFORM(WIN) + RetainPtr<CFDataRef> data = toImpl(frameRef)->webArchiveData(); + if (data) + return WKDataCreate(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); +#endif + + return 0; +} 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 000000000..ce94badcb --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h @@ -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. + */ + +#ifndef WKBundleFrame_h +#define WKBundleFrame_h + +#include <JavaScriptCore/JavaScript.h> +#include <WebKit2/WKBase.h> +#include <WebKit2/WKFrame.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 WKFrameLoadState WKBundleFrameGetFrameLoadState(WKBundleFrameRef frame); + +WK_EXPORT JSGlobalContextRef WKBundleFrameGetJavaScriptContext(WKBundleFrameRef frame); +WK_EXPORT JSGlobalContextRef WKBundleFrameGetJavaScriptContextForWorld(WKBundleFrameRef frame, WKBundleScriptWorldRef world); + +WK_EXPORT WKBundleFrameRef WKBundleFrameForJavaScriptContext(JSContextRef context); + +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 WKRect WKBundleFrameGetVisibleContentBoundsExcludingScrollbars(WKBundleFrameRef frame); +WK_EXPORT WKSize WKBundleFrameGetScrollOffset(WKBundleFrameRef frame); + +WK_EXPORT bool WKBundleFrameHasHorizontalScrollbar(WKBundleFrameRef frame); +WK_EXPORT bool WKBundleFrameHasVerticalScrollbar(WKBundleFrameRef frame); + +WK_EXPORT bool WKBundleFrameGetDocumentBackgroundColor(WKBundleFrameRef frame, double* red, double* green, double* blue, double* alpha); + +WK_EXPORT WKStringRef WKBundleFrameCopySuggestedFilenameForResourceWithURL(WKBundleFrameRef frame, WKURLRef url); +WK_EXPORT WKStringRef WKBundleFrameCopyMIMETypeForResourceWithURL(WKBundleFrameRef frame, WKURLRef url); + +WK_EXPORT WKDataRef WKBundleFrameCopyWebArchive(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 000000000..a786b2557 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFramePrivate.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 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 animationName, WKStringRef elementID, double time); +WK_EXPORT bool WKBundleFramePauseTransitionOnElementWithId(WKBundleFrameRef frame, WKStringRef propertyName, 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); +WK_EXPORT void WKBundleFrameClearOpener(WKBundleFrameRef frame); + +WK_EXPORT bool WKBundleFrameContainsAnyFormElements(WKBundleFrameRef frame); +WK_EXPORT void WKBundleFrameSetTextDirection(WKBundleFrameRef frame, WKStringRef); + +#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 000000000..9cb225033 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKBundleHitTestResult.h" + +#include "InjectedBundleHitTestResult.h" +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleHitTestResultGetTypeID() +{ + return toAPI(InjectedBundleHitTestResult::APIType); +} + +WKBundleNodeHandleRef WKBundleHitTestResultCopyNodeHandle(WKBundleHitTestResultRef hitTestResultRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = toImpl(hitTestResultRef)->nodeHandle(); + return toAPI(nodeHandle.release().leakRef()); +} + +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 WKBundleHitTestResultCopyAbsolutePDFURL(WKBundleHitTestResultRef hitTestResultRef) +{ + return toCopiedURLAPI(toImpl(hitTestResultRef)->absolutePDFURL()); +} + +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 000000000..37c5019da --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleHitTestResult.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 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 WKBundleHitTestResultCopyNodeHandle(WKBundleHitTestResultRef hitTestResult); + +WK_EXPORT WKBundleFrameRef WKBundleHitTestResultGetFrame(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT WKBundleFrameRef WKBundleHitTestResultGetTargetFrame(WKBundleHitTestResultRef hitTestResult); + +WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsoluteImageURL(WKBundleHitTestResultRef hitTestResult); +WK_EXPORT WKURLRef WKBundleHitTestResultCopyAbsolutePDFURL(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 000000000..f10b7b400 --- /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/WKBundleInspector.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInspector.cpp new file mode 100644 index 000000000..a699eabaa --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInspector.cpp @@ -0,0 +1,71 @@ +/* + * 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 "config.h" +#include "WKBundleInspector.h" + +#if ENABLE(INSPECTOR) + +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebInspector.h" + +using namespace WebCore; +using namespace WebKit; + +WKTypeID WKBundleInspectorGetTypeID() +{ + return toAPI(WebInspector::APIType); +} + +void WKBundleInspectorShow(WKBundleInspectorRef inspectorRef) +{ + return toImpl(inspectorRef)->show(); +} + +void WKBundleInspectorClose(WKBundleInspectorRef inspectorRef) +{ + return toImpl(inspectorRef)->close(); +} + +void WKBundleInspectorEvaluateScriptForTest(WKBundleInspectorRef inspectorRef, long callID, WKStringRef script) +{ + return toImpl(inspectorRef)->evaluateScriptForTest(callID, toImpl(script)->string()); +} + +void WKBundleInspectorSetJavaScriptProfilingEnabled(WKBundleInspectorRef inspectorRef, bool enabled) +{ + toImpl(inspectorRef)->setJavaScriptProfilingEnabled(enabled); +} + +void WKBundleInspectorSetPageProfilingEnabled(WKBundleInspectorRef inspectorRef, bool enabled) +{ + if (enabled) + toImpl(inspectorRef)->startPageProfiling(); + else + toImpl(inspectorRef)->stopPageProfiling(); +} + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInspector.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInspector.h new file mode 100644 index 000000000..593d90aa5 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleInspector.h @@ -0,0 +1,57 @@ +/* + * 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 WKBundleInspector_h +#define WKBundleInspector_h + +#include <WebKit2/WKBase.h> + +#if ENABLE(INSPECTOR) + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleInspectorGetTypeID(); + +WK_EXPORT void WKBundleInspectorShow(WKBundleInspectorRef inspector); +WK_EXPORT void WKBundleInspectorClose(WKBundleInspectorRef inspector); + +WK_EXPORT void WKBundleInspectorEvaluateScriptForTest(WKBundleInspectorRef inspector, long callID, WKStringRef script); +WK_EXPORT void WKBundleInspectorSetJavaScriptProfilingEnabled(WKBundleInspectorRef inspector, bool enabled); +WK_EXPORT void WKBundleInspectorSetPageProfilingEnabled(WKBundleInspectorRef inspector, bool enabled); + +#ifdef __cplusplus +} +#endif + +#endif // ENABLE(INSPECTOR) + +#endif // WKBundleInspector_h + diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.cpp new file mode 100644 index 000000000..c26ec3ecf --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.cpp @@ -0,0 +1,67 @@ +/* + * 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 "config.h" +#include "WKBundleNavigationAction.h" + +#include "InjectedBundleHitTestResult.h" +#include "InjectedBundleNavigationAction.h" +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +WKTypeID WKBundleNavigationActionGetTypeID() +{ + return toAPI(InjectedBundleNavigationAction::APIType); +} + +WKFrameNavigationType WKBundleNavigationActionGetNavigationType(WKBundleNavigationActionRef navigationActionRef) +{ + return toAPI(toImpl(navigationActionRef)->navigationType()); +} + +WKEventModifiers WKBundleNavigationActionGetEventModifiers(WKBundleNavigationActionRef navigationActionRef) +{ + return toAPI(toImpl(navigationActionRef)->modifiers()); +} + +WKEventMouseButton WKBundleNavigationActionGetEventMouseButton(WKBundleNavigationActionRef navigationActionRef) +{ + return toAPI(toImpl(navigationActionRef)->mouseButton()); +} + +WKBundleHitTestResultRef WKBundleNavigationActionCopyHitTestResult(WKBundleNavigationActionRef navigationActionRef) +{ + RefPtr<InjectedBundleHitTestResult> hitTestResult = toImpl(navigationActionRef)->hitTestResult(); + return toAPI(hitTestResult.release().leakRef()); +} + +WKBundleNodeHandleRef WKBundleNavigationActionCopyFormElement(WKBundleNavigationActionRef navigationActionRef) +{ + RefPtr<InjectedBundleNodeHandle> formElement = toImpl(navigationActionRef)->formElement(); + return toAPI(formElement.release().leakRef()); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.h new file mode 100644 index 000000000..03f083a29 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNavigationAction.h @@ -0,0 +1,49 @@ +/* + * 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 WKBundleNavigationAction_h +#define WKBundleNavigationAction_h + +#include <WebKit2/WKBase.h> +#include <WebKit2/WKEvent.h> +#include <WebKit2/WKPageLoadTypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKBundleNavigationActionGetTypeID(); + +WK_EXPORT WKFrameNavigationType WKBundleNavigationActionGetNavigationType(WKBundleNavigationActionRef navigationAction); +WK_EXPORT WKEventModifiers WKBundleNavigationActionGetEventModifiers(WKBundleNavigationActionRef navigationAction); +WK_EXPORT WKEventMouseButton WKBundleNavigationActionGetEventMouseButton(WKBundleNavigationActionRef navigationAction); +WK_EXPORT WKBundleHitTestResultRef WKBundleNavigationActionCopyHitTestResult(WKBundleNavigationActionRef navigationAction); +WK_EXPORT WKBundleNodeHandleRef WKBundleNavigationActionCopyFormElement(WKBundleNavigationActionRef navigationAction); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleNavigationAction_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 000000000..77b87c90d --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.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 "config.h" +#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().leakRef()); +} + +WKBundleNodeHandleRef WKBundleNodeHandleCopyDocument(WKBundleNodeHandleRef nodeHandleRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = toImpl(nodeHandleRef)->document(); + return toAPI(nodeHandle.release().leakRef()); +} + +WKRect WKBundleNodeHandleGetRenderRect(WKBundleNodeHandleRef nodeHandleRef, bool* isReplaced) +{ + return toAPI(toImpl(nodeHandleRef)->renderRect(isReplaced)); +} + +WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef elementHandleRef) +{ + return toAPI(toImpl(elementHandleRef)->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); +} + +bool WKBundleNodeHandleGetHTMLInputElementLastChangeWasUserEdit(WKBundleNodeHandleRef htmlInputElementHandleRef) +{ + return toImpl(htmlInputElementHandleRef)->htmlInputElementLastChangeWasUserEdit(); +} + +bool WKBundleNodeHandleGetHTMLTextAreaElementLastChangeWasUserEdit(WKBundleNodeHandleRef htmlTextAreaElementHandleRef) +{ + return toImpl(htmlTextAreaElementHandleRef)->htmlTextAreaElementLastChangeWasUserEdit(); +} + +WKBundleNodeHandleRef WKBundleNodeHandleCopyHTMLTableCellElementCellAbove(WKBundleNodeHandleRef htmlTableCellElementHandleRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = toImpl(htmlTableCellElementHandleRef)->htmlTableCellElementCellAbove(); + return toAPI(nodeHandle.release().leakRef()); +} + +WKBundleFrameRef WKBundleNodeHandleCopyDocumentFrame(WKBundleNodeHandleRef documentHandleRef) +{ + RefPtr<WebFrame> frame = toImpl(documentHandleRef)->documentFrame(); + return toAPI(frame.release().leakRef()); +} + +WKBundleFrameRef WKBundleNodeHandleCopyHTMLFrameElementContentFrame(WKBundleNodeHandleRef htmlFrameElementHandleRef) +{ + RefPtr<WebFrame> frame = toImpl(htmlFrameElementHandleRef)->htmlFrameElementContentFrame(); + return toAPI(frame.release().leakRef()); +} + +WKBundleFrameRef WKBundleNodeHandleCopyHTMLIFrameElementContentFrame(WKBundleNodeHandleRef htmlIFrameElementHandleRef) +{ + RefPtr<WebFrame> frame = toImpl(htmlIFrameElementHandleRef)->htmlIFrameElementContentFrame(); + return toAPI(frame.release().leakRef()); +} 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 000000000..3cdad1761 --- /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 000000000..245c56555 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h @@ -0,0 +1,75 @@ +/* + * 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); + +/* Convenience Operations */ +WK_EXPORT WKBundleNodeHandleRef WKBundleNodeHandleCopyDocument(WKBundleNodeHandleRef nodeHandle); + + +/* Additional DOM Operations */ + +WK_EXPORT WKRect WKBundleNodeHandleGetRenderRect(WKBundleNodeHandleRef nodeHandle, bool* isReplaced); + +/* Element Specific Operations */ +WK_EXPORT WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef elementHandle); + +/* 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); +WK_EXPORT bool WKBundleNodeHandleGetHTMLInputElementLastChangeWasUserEdit(WKBundleNodeHandleRef htmlInputElementHandle); + +/* HTMLTextAreaElement Specific Operations */ +WK_EXPORT bool WKBundleNodeHandleGetHTMLTextAreaElementLastChangeWasUserEdit(WKBundleNodeHandleRef htmlTextAreaElementHandle); + +/* 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 000000000..97347f2f9 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp @@ -0,0 +1,374 @@ +/* + * 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 "config.h" +#include "WKBundlePage.h" +#include "WKBundlePagePrivate.h" + +#include "InjectedBundleBackForwardList.h" +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebFullScreenManager.h" +#include "WebImage.h" +#include "WebPage.h" +#include "WebURL.h" +#include "WebURLRequest.h" + +#include <WebCore/AXObjectCache.h> +#include <WebCore/AccessibilityObject.h> +#include <WebCore/Frame.h> +#include <WebCore/KURL.h> +#include <WebCore/Page.h> + +using namespace WebKit; + +WKTypeID WKBundlePageGetTypeID() +{ + return toAPI(WebPage::APIType); +} + +void WKBundlePageSetContextMenuClient(WKBundlePageRef pageRef, WKBundlePageContextMenuClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundleContextMenuClient(wkClient); +} + +void WKBundlePageSetEditorClient(WKBundlePageRef pageRef, WKBundlePageEditorClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundleEditorClient(wkClient); +} + +void WKBundlePageSetFormClient(WKBundlePageRef pageRef, WKBundlePageFormClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundleFormClient(wkClient); +} + +void WKBundlePageSetPageLoaderClient(WKBundlePageRef pageRef, WKBundlePageLoaderClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundleLoaderClient(wkClient); +} + +void WKBundlePageSetResourceLoadClient(WKBundlePageRef pageRef, WKBundlePageResourceLoadClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundleResourceLoadClient(wkClient); +} + +void WKBundlePageSetPolicyClient(WKBundlePageRef pageRef, WKBundlePagePolicyClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundlePolicyClient(wkClient); +} + +void WKBundlePageSetUIClient(WKBundlePageRef pageRef, WKBundlePageUIClient* wkClient) +{ + toImpl(pageRef)->initializeInjectedBundleUIClient(wkClient); +} + +void WKBundlePageSetFullScreenClient(WKBundlePageRef pageRef, WKBundlePageFullScreenClient* wkClient) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->initializeInjectedBundleFullScreenClient(wkClient); +#endif +} + +void WKBundlePageWillEnterFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->willEnterFullScreen(); +#endif +} + +void WKBundlePageDidEnterFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->didEnterFullScreen(); +#endif +} + +void WKBundlePageWillExitFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->willExitFullScreen(); +#endif +} + +void WKBundlePageDidExitFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->didExitFullScreen(); +#endif +} + +WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->pageGroup()); +} + +WKBundleFrameRef WKBundlePageGetMainFrame(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->mainWebFrame()); +} + +void* WKAccessibilityRootObject(WKBundlePageRef pageRef) +{ +#if HAVE(ACCESSIBILITY) + if (!pageRef) + return 0; + + WebCore::Page* page = toImpl(pageRef)->corePage(); + if (!page) + return 0; + + WebCore::Frame* core = page->mainFrame(); + if (!core || !core->document()) + return 0; + + WebCore::AXObjectCache::enableAccessibility(); + + WebCore::AccessibilityObject* root = core->document()->axObjectCache()->rootObject(); + if (!root) + return 0; + + return root->wrapper(); +#else + return 0; +#endif +} + +void* WKAccessibilityFocusedObject(WKBundlePageRef pageRef) +{ +#if HAVE(ACCESSIBILITY) + if (!pageRef) + return 0; + + WebCore::Page* page = toImpl(pageRef)->corePage(); + if (!page) + return 0; + + WebCore::AXObjectCache::enableAccessibility(); + + WebCore::AccessibilityObject* focusedObject = WebCore::AXObjectCache::focusedUIElementForPage(page); + if (!focusedObject) + return 0; + + return focusedObject->wrapper(); +#else + return 0; +#endif +} + +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); +} + +void WKBundlePageSetScaleAtOrigin(WKBundlePageRef pageRef, double scale, WKPoint origin) +{ + toImpl(pageRef)->scalePage(scale, toIntPoint(origin)); +} + +WKBundleBackForwardListRef WKBundlePageGetBackForwardList(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->backForwardList()); +} + +void WKBundlePageSetUnderlayPage(WKBundlePageRef pageRef, WKBundlePageRef pageUnderlayRef) +{ + toImpl(pageRef)->setUnderlayPage(toImpl(pageUnderlayRef)); +} + +void WKBundlePageInstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef) +{ + toImpl(pageRef)->installPageOverlay(toImpl(pageOverlayRef)); +} + +void WKBundlePageUninstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef) +{ + toImpl(pageRef)->uninstallPageOverlay(toImpl(pageOverlayRef), false); +} + +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()); +} + +WKImageRef WKBundlePageCreateScaledSnapshotInDocumentCoordinates(WKBundlePageRef pageRef, WKRect rect, double scaleFactor, WKImageOptions options) +{ + RefPtr<WebImage> webImage = toImpl(pageRef)->scaledSnapshotInDocumentCoordinates(toIntRect(rect), scaleFactor, toImageOptions(options)); + return toAPI(webImage.release().leakRef()); +} + +double WKBundlePageGetBackingScaleFactor(WKBundlePageRef pageRef) +{ + return toImpl(pageRef)->deviceScaleFactor(); +} + +#if defined(ENABLE_INSPECTOR) && ENABLE_INSPECTOR +WKBundleInspectorRef WKBundlePageGetInspector(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->inspector()); +} +#endif + +void WKBundlePageForceRepaint(WKBundlePageRef page) +{ + toImpl(page)->forceRepaintWithoutCallback(); +} + +void WKBundlePageSimulateMouseDown(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + toImpl(page)->simulateMouseDown(button, toIntPoint(position), clickCount, modifiers, time); +} + +void WKBundlePageSimulateMouseUp(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + toImpl(page)->simulateMouseUp(button, toIntPoint(position), clickCount, modifiers, time); +} + +void WKBundlePageSimulateMouseMotion(WKBundlePageRef page, WKPoint position, double time) +{ + toImpl(page)->simulateMouseMotion(toIntPoint(position), time); +} + +uint64_t WKBundlePageGetRenderTreeSize(WKBundlePageRef pageRef) +{ + return toImpl(pageRef)->renderTreeSize(); +} + +void WKBundlePageSetTracksRepaints(WKBundlePageRef pageRef, bool trackRepaints) +{ + toImpl(pageRef)->setTracksRepaints(trackRepaints); +} + +bool WKBundlePageIsTrackingRepaints(WKBundlePageRef pageRef) +{ + return toImpl(pageRef)->isTrackingRepaints(); +} + +void WKBundlePageResetTrackedRepaints(WKBundlePageRef pageRef) +{ + toImpl(pageRef)->resetTrackedRepaints(); +} + +WKArrayRef WKBundlePageCopyTrackedRepaintRects(WKBundlePageRef pageRef) +{ + return toAPI(toImpl(pageRef)->trackedRepaintRects().leakRef()); +} + +WKStringRef WKBundlePageViewportConfigurationAsText(WKBundlePageRef pageRef, int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight) +{ + return toCopiedAPI(toImpl(pageRef)->viewportConfigurationAsText(deviceDPI, deviceWidth, deviceHeight, availableWidth, availableHeight)); +} + +void WKBundlePageSetComposition(WKBundlePageRef pageRef, WKStringRef text, int from, int length) +{ + toImpl(pageRef)->setCompositionForTesting(toImpl(text)->string(), from, length); +} + +bool WKBundlePageHasComposition(WKBundlePageRef pageRef) +{ + return toImpl(pageRef)->hasCompositionForTesting(); +} + +void WKBundlePageConfirmComposition(WKBundlePageRef pageRef) +{ + toImpl(pageRef)->confirmCompositionForTesting(String()); +} + +void WKBundlePageConfirmCompositionWithText(WKBundlePageRef pageRef, WKStringRef text) +{ + toImpl(pageRef)->confirmCompositionForTesting(toImpl(text)->string()); +} 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 000000000..7da8d0a3d --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h @@ -0,0 +1,354 @@ +/* + * 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; + +enum { + WKFullScreenNoKeyboard, + WKFullScreenKeyboard, +}; +typedef uint32_t WKFullScreenKeyboardRequestType; + +enum { + WKScrollDirectionLeft, + WKScrollDirectionRight +}; +typedef uint32_t WKScrollDirection; + +// 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 (*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); +typedef void (*WKBundlePageDidDetectXSSForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFirstLayoutForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidFirstVisuallyNonEmptyLayoutForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); +typedef void (*WKBundlePageDidLayoutForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, const void* clientInfo); +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); + +struct WKBundlePageLoaderClient { + int version; + const void * clientInfo; + + // Version 0. + WKBundlePageDidStartProvisionalLoadForFrameCallback didStartProvisionalLoadForFrame; + WKBundlePageDidReceiveServerRedirectForProvisionalLoadForFrameCallback didReceiveServerRedirectForProvisionalLoadForFrame; + WKBundlePageDidFailProvisionalLoadWithErrorForFrameCallback didFailProvisionalLoadWithErrorForFrame; + WKBundlePageDidCommitLoadForFrameCallback didCommitLoadForFrame; + WKBundlePageDidFinishDocumentLoadForFrameCallback didFinishDocumentLoadForFrame; + WKBundlePageDidFinishLoadForFrameCallback didFinishLoadForFrame; + WKBundlePageDidFailLoadWithErrorForFrameCallback didFailLoadWithErrorForFrame; + WKBundlePageDidSameDocumentNavigationForFrameCallback didSameDocumentNavigationForFrame; + WKBundlePageDidReceiveTitleForFrameCallback didReceiveTitleForFrame; + WKBundlePageDidFirstLayoutForFrameCallback didFirstLayoutForFrame; + WKBundlePageDidFirstVisuallyNonEmptyLayoutForFrameCallback didFirstVisuallyNonEmptyLayoutForFrame; + WKBundlePageDidRemoveFrameFromHierarchyCallback didRemoveFrameFromHierarchy; + WKBundlePageDidDisplayInsecureContentForFrameCallback didDisplayInsecureContentForFrame; + WKBundlePageDidRunInsecureContentForFrameCallback didRunInsecureContentForFrame; + WKBundlePageDidClearWindowObjectForFrameCallback didClearWindowObjectForFrame; + WKBundlePageDidCancelClientRedirectForFrameCallback didCancelClientRedirectForFrame; + WKBundlePageWillPerformClientRedirectForFrameCallback willPerformClientRedirectForFrame; + WKBundlePageDidHandleOnloadEventsForFrameCallback didHandleOnloadEventsForFrame; + + // Version 1. + WKBundlePageDidLayoutForFrameCallback didLayoutForFrame; + WKBundlePageDidDetectXSSForFrameCallback didDetectXSSForFrame; +}; +typedef struct WKBundlePageLoaderClient WKBundlePageLoaderClient; + +enum { kWKBundlePageLoaderClientCurrentVersion = 1 }; + +enum { + WKBundlePagePolicyActionPassThrough, + WKBundlePagePolicyActionUse +}; +typedef uint32_t WKBundlePagePolicyAction; + +// Policy Client +typedef WKBundlePagePolicyAction (*WKBundlePageDecidePolicyForNavigationActionCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleNavigationActionRef navigationAction, WKURLRequestRef request, WKTypeRef* userData, const void* clientInfo); +typedef WKBundlePagePolicyAction (*WKBundlePageDecidePolicyForNewWindowActionCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleNavigationActionRef navigationAction, WKURLRequestRef request, WKStringRef frameName, WKTypeRef* userData, const void* clientInfo); +typedef WKBundlePagePolicyAction (*WKBundlePageDecidePolicyForResponseCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, WKTypeRef* userData, const void* clientInfo); +typedef void (*WKBundlePageUnableToImplementPolicyCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKErrorRef error, WKTypeRef* userData, const void* clientInfo); + +struct WKBundlePagePolicyClient { + int version; + const void * clientInfo; + WKBundlePageDecidePolicyForNavigationActionCallback decidePolicyForNavigationAction; + WKBundlePageDecidePolicyForNewWindowActionCallback decidePolicyForNewWindowAction; + WKBundlePageDecidePolicyForResponseCallback decidePolicyForResponse; + WKBundlePageUnableToImplementPolicyCallback unableToImplementPolicy; +}; +typedef struct WKBundlePagePolicyClient WKBundlePagePolicyClient; + +enum { kWKBundlePagePolicyClientCurrentVersion = 0 }; + +// Resource Load Client +typedef void (*WKBundlePageDidInitiateLoadForResourceCallback)(WKBundlePageRef, WKBundleFrameRef, uint64_t resourceIdentifier, WKURLRequestRef, bool pageIsProvisionallyLoading, const void* clientInfo); +typedef WKURLRequestRef (*WKBundlePageWillSendRequestForFrameCallback)(WKBundlePageRef, WKBundleFrameRef, uint64_t resourceIdentifier, WKURLRequestRef, WKURLResponseRef redirectResponse, const void *clientInfo); +typedef void (*WKBundlePageDidReceiveResponseForResourceCallback)(WKBundlePageRef, WKBundleFrameRef, uint64_t resourceIdentifier, WKURLResponseRef, const void* clientInfo); +typedef void (*WKBundlePageDidReceiveContentLengthForResourceCallback)(WKBundlePageRef, WKBundleFrameRef, uint64_t resourceIdentifier, uint64_t contentLength, const void* clientInfo); +typedef void (*WKBundlePageDidFinishLoadForResourceCallback)(WKBundlePageRef, WKBundleFrameRef, uint64_t resourceIdentifier, const void* clientInfo); +typedef void (*WKBundlePageDidFailLoadForResourceCallback)(WKBundlePageRef, WKBundleFrameRef, uint64_t resourceIdentifier, WKErrorRef, const void* clientInfo); + +struct WKBundlePageResourceLoadClient { + int version; + const void * clientInfo; + WKBundlePageDidInitiateLoadForResourceCallback didInitiateLoadForResource; + + // willSendRequestForFrame is supposed to return a retained reference to the URL request. + WKBundlePageWillSendRequestForFrameCallback willSendRequestForFrame; + + WKBundlePageDidReceiveResponseForResourceCallback didReceiveResponseForResource; + WKBundlePageDidReceiveContentLengthForResourceCallback didReceiveContentLengthForResource; + WKBundlePageDidFinishLoadForResourceCallback didFinishLoadForResource; + WKBundlePageDidFailLoadForResourceCallback didFailLoadForResource; +}; +typedef struct WKBundlePageResourceLoadClient WKBundlePageResourceLoadClient; + +enum { kWKBundlePageResourceLoadClientCurrentVersion = 0 }; + +enum { + WKBundlePageUIElementVisibilityUnknown, + WKBundlePageUIElementVisible, + WKBundlePageUIElementHidden +}; +typedef uint32_t WKBundlePageUIElementVisibility; + +// 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); +typedef void (*WKBundlePagePaintCustomOverhangAreaCallback)(WKBundlePageRef page, WKGraphicsContextRef graphicsContext, WKRect horizontalOverhang, WKRect verticalOverhang, WKRect dirtyRect, const void* clientInfo); +typedef WKStringRef (*WKBundlePageGenerateFileForUploadCallback)(WKBundlePageRef page, WKStringRef originalFilePath, const void* clientInfo); +typedef bool (*WKBundlePageShouldRubberBandInDirectionCallback)(WKBundlePageRef page, WKScrollDirection scrollDirection, const void* clientInfo); +typedef WKBundlePageUIElementVisibility (*WKBundlePageStatusBarIsVisibleCallback)(WKBundlePageRef page, const void *clientInfo); +typedef WKBundlePageUIElementVisibility (*WKBundlePageMenuBarIsVisibleCallback)(WKBundlePageRef page, const void *clientInfo); +typedef WKBundlePageUIElementVisibility (*WKBundlePageToolbarsAreVisibleCallback)(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; + WKBundlePagePaintCustomOverhangAreaCallback paintCustomOverhangArea; + WKBundlePageGenerateFileForUploadCallback shouldGenerateFileForUpload; + WKBundlePageGenerateFileForUploadCallback generateFileForUpload; + WKBundlePageShouldRubberBandInDirectionCallback shouldRubberBandInDirection; + WKBundlePageStatusBarIsVisibleCallback statusBarIsVisible; + WKBundlePageMenuBarIsVisibleCallback menuBarIsVisible; + WKBundlePageToolbarsAreVisibleCallback toolbarsAreVisible; +}; +typedef struct WKBundlePageUIClient WKBundlePageUIClient; + +enum { kWKBundlePageUIClientCurrentVersion = 0 }; + +// 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; + +enum { kWKBundlePageEditorClientCurrentVersion = 0 }; + +// 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; + +enum { kWKBundlePageFormClientCurrentVersion = 0 }; + +// 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; + +enum { kWKBundlePageContextMenuClientCurrentVersion = 0 }; + +// Full Screen client +typedef bool (*WKBundlePageSupportsFullScreen)(WKBundlePageRef page, WKFullScreenKeyboardRequestType requestType); +typedef void (*WKBundlePageEnterFullScreenForElement)(WKBundlePageRef page, WKBundleNodeHandleRef element); +typedef void (*WKBundlePageExitFullScreenForElement)(WKBundlePageRef page, WKBundleNodeHandleRef element); + +struct WKBundlePageFullScreenClient { + int version; + const void * clientInfo; + WKBundlePageSupportsFullScreen supportsFullScreen; + WKBundlePageEnterFullScreenForElement enterFullScreenForElement; + WKBundlePageExitFullScreenForElement exitFullScreenForElement; +}; +typedef struct WKBundlePageFullScreenClient WKBundlePageFullScreenClient; + +enum { kWKBundlePageFullScreenClientCurrentVersion = 0 }; + +WK_EXPORT void WKBundlePageWillEnterFullScreen(WKBundlePageRef page); +WK_EXPORT void WKBundlePageDidEnterFullScreen(WKBundlePageRef page); +WK_EXPORT void WKBundlePageWillExitFullScreen(WKBundlePageRef page); +WK_EXPORT void WKBundlePageDidExitFullScreen(WKBundlePageRef page); + +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 WKBundlePageSetPageLoaderClient(WKBundlePageRef page, WKBundlePageLoaderClient* client); +WK_EXPORT void WKBundlePageSetResourceLoadClient(WKBundlePageRef page, WKBundlePageResourceLoadClient* client); +WK_EXPORT void WKBundlePageSetPolicyClient(WKBundlePageRef page, WKBundlePagePolicyClient* client); +WK_EXPORT void WKBundlePageSetUIClient(WKBundlePageRef page, WKBundlePageUIClient* client); + +WK_EXPORT void WKBundlePageSetFullScreenClient(WKBundlePageRef page, WKBundlePageFullScreenClient* client); + +WK_EXPORT WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef page); +WK_EXPORT WKBundleFrameRef WKBundlePageGetMainFrame(WKBundlePageRef page); + +WK_EXPORT WKBundleBackForwardListRef WKBundlePageGetBackForwardList(WKBundlePageRef page); + +WK_EXPORT void WKBundlePageSetUnderlayPage(WKBundlePageRef page, WKBundlePageRef pageUnderlay); + +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); +WK_EXPORT WKImageRef WKBundlePageCreateScaledSnapshotInDocumentCoordinates(WKBundlePageRef page, WKRect rect, double scaleFactor, WKImageOptions options); + +WK_EXPORT double WKBundlePageGetBackingScaleFactor(WKBundlePageRef page); + +#if defined(ENABLE_INSPECTOR) && ENABLE_INSPECTOR +WK_EXPORT WKBundleInspectorRef WKBundlePageGetInspector(WKBundlePageRef page); +#endif + +#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 000000000..e076cb97f --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageGroup.cpp @@ -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. + */ + +#include "config.h" +#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 000000000..e0bf64525 --- /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 000000000..4364ce97c --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.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 "config.h" +#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))); +} + +float WKBundlePageOverlayFractionFadedIn(WKBundlePageOverlayRef bundlePageOverlayRef) +{ + return toImpl(bundlePageOverlayRef)->fractionFadedIn(); +} 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 000000000..eeb20c902 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h @@ -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. + */ + +#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; + +enum { kWKBundlePageOverlayClientCurrentVersion = 0 }; + +WK_EXPORT WKTypeID WKBundlePageOverlayGetTypeID(); + +WK_EXPORT WKBundlePageOverlayRef WKBundlePageOverlayCreate(WKBundlePageOverlayClient* client); +WK_EXPORT void WKBundlePageOverlaySetNeedsDisplay(WKBundlePageOverlayRef bundlePageOverlay, WKRect rect); +WK_EXPORT float WKBundlePageOverlayFractionFadedIn(WKBundlePageOverlayRef bundlePageOverlay); + +#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 000000000..73351b9fe --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h @@ -0,0 +1,77 @@ +/* + * 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 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); + +WK_EXPORT void WKBundlePageSetScaleAtOrigin(WKBundlePageRef page, double scale, WKPoint origin); + +WK_EXPORT void WKBundlePageForceRepaint(WKBundlePageRef page); + +WK_EXPORT void WKBundlePageSimulateMouseDown(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time); +WK_EXPORT void WKBundlePageSimulateMouseUp(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time); +WK_EXPORT void WKBundlePageSimulateMouseMotion(WKBundlePageRef page, WKPoint position, double time); + +WK_EXPORT uint64_t WKBundlePageGetRenderTreeSize(WKBundlePageRef page); + +WK_EXPORT void WKBundlePageSetTracksRepaints(WKBundlePageRef page, bool trackRepaints); +WK_EXPORT bool WKBundlePageIsTrackingRepaints(WKBundlePageRef page); +WK_EXPORT void WKBundlePageResetTrackedRepaints(WKBundlePageRef page); +WK_EXPORT WKArrayRef WKBundlePageCopyTrackedRepaintRects(WKBundlePageRef page); + +WK_EXPORT WKStringRef WKBundlePageViewportConfigurationAsText(WKBundlePageRef, int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight); + +WK_EXPORT void WKBundlePageSetComposition(WKBundlePageRef page, WKStringRef text, int from, int length); +WK_EXPORT bool WKBundlePageHasComposition(WKBundlePageRef page); +WK_EXPORT void WKBundlePageConfirmComposition(WKBundlePageRef page); +WK_EXPORT void WKBundlePageConfirmCompositionWithText(WKBundlePageRef page, WKStringRef text); + +WK_EXPORT void* WKAccessibilityRootObject(WKBundlePageRef); +WK_EXPORT void* WKAccessibilityFocusedObject(WKBundlePageRef); + +#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 000000000..95ca7ce7e --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.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 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); +WK_EXPORT void WKBundleSetAllowUniversalAccessFromFileURLs(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleSetAllowFileAccessFromFileURLs(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleSetFrameFlatteningEnabled(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleSetJavaScriptCanAccessClipboard(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleSetPrivateBrowsingEnabled(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleSetAuthorAndUserStylesEnabled(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleClearAllDatabases(WKBundleRef bundle); +WK_EXPORT void WKBundleSetDatabaseQuota(WKBundleRef bundle, uint64_t); +WK_EXPORT void WKBundleClearApplicationCache(WKBundleRef bundle); +WK_EXPORT void WKBundleSetAppCacheMaximumSize(WKBundleRef bundle, uint64_t size); +WK_EXPORT int WKBundleNumberOfPages(WKBundleRef bundle, WKBundleFrameRef frameRef, double pageWidthInPixels, double pageHeightInPixels); +WK_EXPORT int WKBundlePageNumberForElementById(WKBundleRef bundle, WKBundleFrameRef frameRef, WKStringRef idRef, double pageWidthInPixels, double pageHeightInPixels); +WK_EXPORT WKStringRef WKBundlePageSizeAndMarginsInPixels(WKBundleRef bundle, WKBundleFrameRef frameRef, int, int, int, int, int, int, int); +WK_EXPORT bool WKBundleIsPageBoxVisible(WKBundleRef bundle, WKBundleFrameRef frameRef, int); +WK_EXPORT void WKBundleAddOriginAccessWhitelistEntry(WKBundleRef bundle, WKStringRef, WKStringRef, WKStringRef, bool); +WK_EXPORT void WKBundleRemoveOriginAccessWhitelistEntry(WKBundleRef bundle, WKStringRef, WKStringRef, WKStringRef, bool); +WK_EXPORT void WKBundleResetOriginAccessWhitelists(WKBundleRef bundle); + +WK_EXPORT bool WKBundleIsProcessingUserGesture(WKBundleRef bundle); + +WK_EXPORT void WKBundleSwitchNetworkLoaderToNewTestingSession(WKBundleRef bundle); + +#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 000000000..c868fab77 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleRangeHandle.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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 000000000..8d1d35928 --- /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 000000000..87ccf11e9 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.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 "config.h" +#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().leakRef()); +} + +WKBundleScriptWorldRef WKBundleScriptWorldNormalWorld() +{ + return toAPI(InjectedBundleScriptWorld::normalWorld()); +} + +void WKBundleScriptWorldClearWrappers(WKBundleScriptWorldRef scriptWorldRef) +{ + toImpl(scriptWorldRef)->clearWrappers(); +} 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 000000000..013cdc9a3 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleScriptWorld.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 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(); +WK_EXPORT void WKBundleScriptWorldClearWrappers(WKBundleScriptWorldRef scriptWorld); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundleScriptWorld_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp new file mode 100644 index 000000000..463a21155 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp @@ -0,0 +1,43 @@ +/* + * 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 "config.h" +#include "WKBundlePrivateWin.h" + +#include "InjectedBundle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebKit; + +void WKBundleSetHostAllowsAnyHTTPSCertificate(WKBundleRef bundleRef, WKStringRef host) +{ + toImpl(bundleRef)->setHostAllowsAnyHTTPSCertificate(toWTFString(host)); +} + +void WKBundleSetClientCertificate(WKBundleRef bundleRef, WKStringRef host, WKStringRef certificateSystemStoreName, WKCertificateInfoRef certificateInfoRef) +{ + toImpl(bundleRef)->setClientCertificate(toWTFString(host), toWTFString(certificateSystemStoreName), toImpl(certificateInfoRef)); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h new file mode 100644 index 000000000..03006dc11 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h @@ -0,0 +1,42 @@ +/* + * 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 WKBundlePrivateWin_h +#define WKBundlePrivateWin_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT void WKBundleSetHostAllowsAnyHTTPSCertificate(WKBundleRef bundle, WKStringRef host); +WK_EXPORT void WKBundleSetClientCertificate(WKBundleRef bundle, WKStringRef host, WKStringRef certificateSystemStoreName, WKCertificateInfoRef certificateInfo); + +#ifdef __cplusplus +} +#endif + +#endif /* WKBundlePrivateWin_h */ diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp new file mode 100644 index 000000000..cebbb30c1 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InjectedBundleNodeHandle.h" + +#include "WebFrame.h" +#include "WebFrameLoaderClient.h" +#include <JavaScriptCore/APICast.h> +#include <WebCore/Document.h> +#include <WebCore/Frame.h> +#include <WebCore/HTMLFrameElement.h> +#include <WebCore/HTMLIFrameElement.h> +#include <WebCore/HTMLInputElement.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLTableCellElement.h> +#include <WebCore/HTMLTextAreaElement.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(); +} + +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::document() +{ + return getOrCreate(m_node->document()); +} + +// 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())->boundsInRootViewSpace(); +} + +IntRect InjectedBundleNodeHandle::renderRect(bool* isReplaced) const +{ + return m_node.get()->renderRect(isReplaced); +} + +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); +} + +bool InjectedBundleNodeHandle::htmlInputElementLastChangeWasUserEdit() +{ + if (!m_node->hasTagName(inputTag)) + return false; + + return static_cast<HTMLInputElement*>(m_node.get())->lastChangeWasUserEdit(); +} + +bool InjectedBundleNodeHandle::htmlTextAreaElementLastChangeWasUserEdit() +{ + if (!m_node->hasTagName(textareaTag)) + return false; + + return static_cast<HTMLTextAreaElement*>(m_node.get())->lastChangeWasUserEdit(); +} + +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 000000000..e4a5ab91e --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.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 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; + + // Convenience DOM Operations + PassRefPtr<InjectedBundleNodeHandle> document(); + + // Additional DOM Operations + // Note: These should only be operations that are not exposed to JavaScript. + WebCore::IntRect elementBounds() const; + WebCore::IntRect renderRect(bool*) const; + void setHTMLInputElementValueForUser(const String&); + bool isHTMLInputElementAutofilled() const; + void setHTMLInputElementAutofilled(bool); + bool htmlInputElementLastChangeWasUserEdit(); + bool htmlTextAreaElementLastChangeWasUserEdit(); + + 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 000000000..e94edfd34 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.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 "config.h" +#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 000000000..4d6789a88 --- /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 000000000..b87151e42 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InjectedBundle.h" + +#include "Arguments.h" +#include "ImmutableArray.h" +#include "InjectedBundleMessageKinds.h" +#include "InjectedBundleScriptWorld.h" +#include "InjectedBundleUserMessageCoders.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebApplicationCacheManager.h" +#include "WebContextMessageKinds.h" +#include "WebCoreArgumentCoders.h" +#include "WebDatabaseManager.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/JSLock.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GCController.h> +#include <WebCore/JSDOMWindow.h> +#include <WebCore/Page.h> +#include <WebCore/PageGroup.h> +#include <WebCore/PrintContext.h> +#include <WebCore/ResourceHandle.h> +#include <WebCore/ScriptController.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityPolicy.h> +#include <WebCore/Settings.h> +#include <WebCore/UserGestureIndicator.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()->deprecatedSend(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()->deprecatedSendSync(WebContextLegacyMessage::PostSynchronousMessage, 0, CoreIPC::In(messageName, InjectedBundleUserMessageEncoder(messageBody)), CoreIPC::Out(messageDecoder)); + + if (!succeeded) + return; + + returnData = returnDataTmp; +} + +WebConnection* InjectedBundle::webConnectionToUIProcess() const +{ + return WebProcess::shared().webConnectionToUIProcess(); +} + +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); +} + +void InjectedBundle::setAllowUniversalAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) +{ + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setAllowUniversalAccessFromFileURLs(enabled); +} + +void InjectedBundle::setAllowFileAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) +{ + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setAllowFileAccessFromFileURLs(enabled); +} + +void InjectedBundle::setFrameFlatteningEnabled(WebPageGroupProxy* pageGroup, bool enabled) +{ + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setFrameFlatteningEnabled(enabled); +} + +void InjectedBundle::setJavaScriptCanAccessClipboard(WebPageGroupProxy* pageGroup, bool enabled) +{ + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setJavaScriptCanAccessClipboard(enabled); +} + +void InjectedBundle::setPrivateBrowsingEnabled(WebPageGroupProxy* pageGroup, bool enabled) +{ + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setPrivateBrowsingEnabled(enabled); +} + +void InjectedBundle::switchNetworkLoaderToNewTestingSession() +{ +#if USE(CFURLSTORAGESESSIONS) + // Set a private session for testing to avoid interfering with global cookies. This should be different from private browsing session. + RetainPtr<CFURLStorageSessionRef> session = ResourceHandle::createPrivateBrowsingStorageSession(CFSTR("Private WebKit Session")); + ResourceHandle::setDefaultStorageSession(session.get()); +#endif +} + +void InjectedBundle::setAuthorAndUserStylesEnabled(WebPageGroupProxy* pageGroup, bool enabled) +{ + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setAuthorAndUserStylesEnabled(enabled); +} + +void InjectedBundle::addOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains) +{ + SecurityPolicy::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); +} + +void InjectedBundle::removeOriginAccessWhitelistEntry(const String& sourceOrigin, const String& destinationProtocol, const String& destinationHost, bool allowDestinationSubdomains) +{ + SecurityPolicy::removeOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); +} + +void InjectedBundle::resetOriginAccessWhitelists() +{ + SecurityPolicy::resetOriginAccessWhitelists(); +} + +void InjectedBundle::clearAllDatabases() +{ + WebDatabaseManager::shared().deleteAllDatabases(); +} + +void InjectedBundle::setDatabaseQuota(uint64_t quota) +{ + WebDatabaseManager::shared().setQuotaForOrigin("file:///", quota); +} + +void InjectedBundle::clearApplicationCache() +{ + WebApplicationCacheManager::shared().deleteAllEntries(); +} + +void InjectedBundle::setAppCacheMaximumSize(uint64_t size) +{ + WebApplicationCacheManager::shared().setAppCacheMaximumSize(size); +} + +int InjectedBundle::numberOfPages(WebFrame* frame, double pageWidthInPixels, double pageHeightInPixels) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return -1; + if (!pageWidthInPixels) + pageWidthInPixels = coreFrame->view()->width(); + if (!pageHeightInPixels) + pageHeightInPixels = coreFrame->view()->height(); + + return PrintContext::numberOfPages(coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels)); +} + +int InjectedBundle::pageNumberForElementById(WebFrame* frame, const String& id, double pageWidthInPixels, double pageHeightInPixels) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return -1; + + Element* element = coreFrame->document()->getElementById(AtomicString(id)); + if (!element) + return -1; + + if (!pageWidthInPixels) + pageWidthInPixels = coreFrame->view()->width(); + if (!pageHeightInPixels) + pageHeightInPixels = coreFrame->view()->height(); + + return PrintContext::pageNumberForElement(element, FloatSize(pageWidthInPixels, pageHeightInPixels)); +} + +String InjectedBundle::pageSizeAndMarginsInPixels(WebFrame* frame, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return String(); + + return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageIndex, width, height, marginTop, marginRight, marginBottom, marginLeft); +} + +bool InjectedBundle::isPageBoxVisible(WebFrame* frame, int pageIndex) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return false; + + return PrintContext::isPageBoxVisible(coreFrame, pageIndex); +} + +bool InjectedBundle::isProcessingUserGesture() +{ + return ScriptController::processingUserGesture(); +} + +static PassOwnPtr<Vector<String> > toStringVector(ImmutableArray* patterns) +{ + if (!patterns) + return nullptr; + + size_t size = patterns->size(); + if (!size) + return nullptr; + + OwnPtr<Vector<String> > patternsVector = adoptPtr(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.release(); +} + +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 000000000..6ff2cfa8e --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h @@ -0,0 +1,165 @@ +/* + * 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 + +#if PLATFORM(GTK) +typedef struct _GModule GModule; +#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 ::GModule* PlatformBundle; +#endif + +class ImmutableArray; +class InjectedBundleScriptWorld; +class WebCertificateInfo; +class WebConnection; +class WebFrame; +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); +#if PLATFORM(WIN) + void setHostAllowsAnyHTTPSCertificate(const String&); + void setClientCertificate(const String& host, const String& certificateSystemStoreName, const WebCertificateInfo*); +#endif + + WebConnection* webConnectionToUIProcess() const; + + // TestRunner only SPI + void setShouldTrackVisitedLinks(bool); + void removeAllVisitedLinks(); + void activateMacFontAscentHack(); + void overrideXSSAuditorEnabledForTestRunner(WebPageGroupProxy* pageGroup, bool enabled); + void setAllowUniversalAccessFromFileURLs(WebPageGroupProxy*, bool); + void setAllowFileAccessFromFileURLs(WebPageGroupProxy*, bool); + void setFrameFlatteningEnabled(WebPageGroupProxy*, bool); + void setJavaScriptCanAccessClipboard(WebPageGroupProxy*, bool); + void setPrivateBrowsingEnabled(WebPageGroupProxy*, bool); + void switchNetworkLoaderToNewTestingSession(); + void setAuthorAndUserStylesEnabled(WebPageGroupProxy*, bool); + void addOriginAccessWhitelistEntry(const String&, const String&, const String&, bool); + void removeOriginAccessWhitelistEntry(const String&, const String&, const String&, bool); + void resetOriginAccessWhitelists(); + int numberOfPages(WebFrame*, double, double); + int pageNumberForElementById(WebFrame*, const String&, double, double); + String pageSizeAndMarginsInPixels(WebFrame*, int, int, int, int, int, int, int); + bool isPageBoxVisible(WebFrame*, int); + + // 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*); + + // Local storage API + void clearAllDatabases(); + void setDatabaseQuota(uint64_t); + + // Application Cache API + void clearApplicationCache(); + void setAppCacheMaximumSize(uint64_t); + + // 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); + + static bool isProcessingUserGesture(); + +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 000000000..d7fb9ec01 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardList.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 "config.h" +#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 000000000..952bdb6bc --- /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 000000000..92a7e695e --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleBackForwardListItem.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 "config.h" +#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 000000000..6cd9ec682 --- /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 000000000..f2e4f2b9f --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleClient.cpp @@ -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. + */ + +#include "config.h" +#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 000000000..32be290c9 --- /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, kWKBundleClientCurrentVersion> { +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 000000000..8c91cb875 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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/FrameView.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::absolutePDFURL() const +{ + return m_hitTestResult.absolutePDFURL().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 +{ + WebCore::IntRect imageRect = m_hitTestResult.imageRect(); + if (imageRect.isEmpty()) + return imageRect; + + // The image rect in WebCore::HitTestResult is in frame coordinates, but we need it in WKView + // coordinates since WebKit2 clients don't have enough context to do the conversion themselves. + WebFrame* webFrame = frame(); + if (!webFrame) + return imageRect; + + WebCore::Frame* coreFrame = webFrame->coreFrame(); + if (!coreFrame) + return imageRect; + + WebCore::FrameView* view = coreFrame->view(); + if (!view) + return imageRect; + + return view->contentsToRootView(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 000000000..292fce1ba --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleHitTestResult.h @@ -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. + */ + +#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 absolutePDFURL() 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/InjectedBundleNavigationAction.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp new file mode 100644 index 000000000..7a40ee6fb --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.cpp @@ -0,0 +1,105 @@ +/* + * 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 "config.h" +#include "InjectedBundleNavigationAction.h" + +#include "WebFrame.h" +#include <WebCore/Frame.h> +#include <WebCore/HTMLFormElement.h> +#include <WebCore/MouseEvent.h> +#include <WebCore/NavigationAction.h> +#include <WebCore/UIEventWithKeyState.h> + +using namespace WebCore; + +namespace WebKit { + +static const MouseEvent* mouseEventForNavigationAction(const NavigationAction& navigationAction) +{ + for (const Event* e = navigationAction.event(); e; e = e->underlyingEvent()) { + if (e->isMouseEvent()) + return static_cast<const MouseEvent*>(e); + } + return 0; +} + +static WebMouseEvent::Button mouseButtonForMouseEvent(const MouseEvent* mouseEvent) +{ + if (!mouseEvent) + return WebMouseEvent::NoButton; + + if (!mouseEvent->buttonDown()) + return WebMouseEvent::NoButton; + + return static_cast<WebMouseEvent::Button>(mouseEvent->button()); +} + +WebEvent::Modifiers InjectedBundleNavigationAction::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 static_cast<WebEvent::Modifiers>(modifiers); +} + +WebMouseEvent::Button InjectedBundleNavigationAction::mouseButtonForNavigationAction(const NavigationAction& navigationAction) +{ + return mouseButtonForMouseEvent(mouseEventForNavigationAction(navigationAction)); +} + + +PassRefPtr<InjectedBundleNavigationAction> InjectedBundleNavigationAction::create(WebFrame* frame, const NavigationAction& action, PassRefPtr<FormState> formState) +{ + return adoptRef(new InjectedBundleNavigationAction(frame, action, formState)); +} + +InjectedBundleNavigationAction::InjectedBundleNavigationAction(WebFrame* frame, const NavigationAction& navigationAction, PassRefPtr<FormState> prpFormState) +{ + m_navigationType = navigationAction.type(); + m_modifiers = modifiersForNavigationAction(navigationAction); + + if (const MouseEvent* mouseEvent = mouseEventForNavigationAction(navigationAction)) { + m_hitTestResult = InjectedBundleHitTestResult::create(frame->coreFrame()->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)); + m_mouseButton = mouseButtonForMouseEvent(mouseEvent); + } + + RefPtr<FormState> formState = prpFormState; + if (formState) { + ASSERT(formState->form()); + m_formElement = InjectedBundleNodeHandle::getOrCreate(formState->form()); + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.h new file mode 100644 index 000000000..128c9fbd0 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleNavigationAction.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 InjectedBundleNavigationAction_h +#define InjectedBundleNavigationAction_h + +#include "APIObject.h" +#include "InjectedBundleHitTestResult.h" +#include "InjectedBundleNodeHandle.h" +#include "WebEvent.h" +#include <WebCore/FrameLoaderTypes.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + class FormState; + class NavigationAction; +} + +namespace WebKit { + +class WebFrame; + +class InjectedBundleNavigationAction : public APIObject { +public: + static const Type APIType = TypeBundleNavigationAction; + + static PassRefPtr<InjectedBundleNavigationAction> create(WebFrame*, const WebCore::NavigationAction&, PassRefPtr<WebCore::FormState>); + + static WebEvent::Modifiers modifiersForNavigationAction(const WebCore::NavigationAction&); + static WebMouseEvent::Button mouseButtonForNavigationAction(const WebCore::NavigationAction&); + + WebCore::NavigationType navigationType() const { return m_navigationType; } + WebEvent::Modifiers modifiers() const { return m_modifiers; } + WebMouseEvent::Button mouseButton() const { return m_mouseButton; } + InjectedBundleHitTestResult* hitTestResult() const { return m_hitTestResult.get(); } + InjectedBundleNodeHandle* formElement() const { return m_formElement.get(); } + +private: + InjectedBundleNavigationAction(WebFrame*, const WebCore::NavigationAction&, PassRefPtr<WebCore::FormState>); + + virtual Type type() const { return APIType; } + + WebCore::NavigationType m_navigationType; + WebEvent::Modifiers m_modifiers; + WebMouseEvent::Button m_mouseButton; + RefPtr<InjectedBundleHitTestResult> m_hitTestResult; + RefPtr<InjectedBundleNodeHandle> m_formElement; +}; + +} // namespace WebKit + +#endif // InjectedBundleNavigationAction_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.cpp new file mode 100644 index 000000000..9df00819d --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageContextMenuClient.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 "config.h" +#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 000000000..0d8ea5f83 --- /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, kWKBundlePageContextMenuClientCurrentVersion> { +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 000000000..633936be1 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageEditorClient.cpp @@ -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. + */ + +#include "config.h" +#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 000000000..3bb782233 --- /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, kWKBundlePageEditorClientCurrentVersion> { +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 000000000..39924ec16 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFormClient.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 "config.h" +#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 000000000..89369dfb2 --- /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, kWKBundlePageFormClientCurrentVersion> { +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/InjectedBundlePageFullScreenClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.cpp new file mode 100644 index 000000000..d8e986f7d --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.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 "config.h" + +#if ENABLE(FULLSCREEN_API) + +#include "InjectedBundlePageFullScreenClient.h" + +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebFullScreenManagerProxyMessages.h" +#include "WebPage.h" +#include <WebCore/Element.h> + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundlePageFullScreenClient::supportsFullScreen(WebPage *page, bool withKeyboard) +{ + if (m_client.supportsFullScreen) + return m_client.supportsFullScreen(toAPI(page), withKeyboard); + + bool supports = true; + page->sendSync(Messages::WebFullScreenManagerProxy::SupportsFullScreen(withKeyboard), supports); + return supports; +} + +void InjectedBundlePageFullScreenClient::enterFullScreenForElement(WebPage *page, WebCore::Element *element) +{ + if (m_client.enterFullScreenForElement) { + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(element); + m_client.enterFullScreenForElement(toAPI(page), toAPI(nodeHandle.get())); + } else + page->send(Messages::WebFullScreenManagerProxy::EnterFullScreen()); +} + +void InjectedBundlePageFullScreenClient::exitFullScreenForElement(WebPage *page, WebCore::Element *element) +{ + if (m_client.exitFullScreenForElement) { + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(element); + m_client.exitFullScreenForElement(toAPI(page), toAPI(nodeHandle.get())); + } else + page->send(Messages::WebFullScreenManagerProxy::ExitFullScreen()); +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.h new file mode 100644 index 000000000..c45b21780 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.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 InjectedBundlePageFullScreenClient_h +#define InjectedBundlePageFullScreenClient_h + +#if ENABLE(FULLSCREEN_API) + +#include "APIClient.h" +#include "WKBundlePage.h" +#include "WebEvent.h" +#include <wtf/Forward.h> + +namespace WebCore { +class Element; +} + +namespace WebKit { + +class WebPage; + +class InjectedBundlePageFullScreenClient : public APIClient<WKBundlePageFullScreenClient, kWKBundlePageFullScreenClientCurrentVersion> { +public: + bool supportsFullScreen(WebPage*, bool withKeyboard); + void enterFullScreenForElement(WebPage*, WebCore::Element*); + void exitFullScreenForElement(WebPage*, WebCore::Element*); +}; + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) + +#endif // InjectedBundlePageFullScreenClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.cpp new file mode 100644 index 000000000..69e357ebe --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.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. + */ + +#include "config.h" +#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::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)); +} + +void InjectedBundlePageLoaderClient::didDetectXSSForFrame(WebPage* page, WebFrame* frame, RefPtr<APIObject>& userData) +{ + if (!m_client.didDetectXSSForFrame) + return; + + WKTypeRef userDataToPass = 0; + m_client.didDetectXSSForFrame(toAPI(page), 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::didLayoutForFrame(WebPage* page, WebFrame* frame) +{ + if (!m_client.didLayoutForFrame) + return; + + m_client.didLayoutForFrame(toAPI(page), toAPI(frame), 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 000000000..c366c6d00 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageLoaderClient.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 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; +class ResourceRequest; +class ResourceResponse; +} + +namespace WebKit { + +class APIObject; +class WebPage; +class WebFrame; + +class InjectedBundlePageLoaderClient : public APIClient<WKBundlePageLoaderClient, kWKBundlePageLoaderClientCurrentVersion> { +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 didRemoveFrameFromHierarchy(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didDisplayInsecureContentForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didRunInsecureContentForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didDetectXSSForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + + void didFirstLayoutForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didFirstVisuallyNonEmptyLayoutForFrame(WebPage*, WebFrame*, RefPtr<APIObject>& userData); + void didLayoutForFrame(WebPage*, WebFrame*); + + 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/InjectedBundlePagePolicyClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePagePolicyClient.cpp new file mode 100644 index 000000000..b90cf1f9e --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePagePolicyClient.cpp @@ -0,0 +1,87 @@ +/* + * 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 "config.h" +#include "InjectedBundlePagePolicyClient.h" + +#include "WKBundleAPICast.h" +#include "WebError.h" +#include "WebURLRequest.h" + +using namespace WebCore; + +namespace WebKit { + +WKBundlePagePolicyAction InjectedBundlePagePolicyClient::decidePolicyForNavigationAction(WebPage* page, WebFrame* frame, InjectedBundleNavigationAction* action, const ResourceRequest& resourceRequest, RefPtr<APIObject>& userData) +{ + if (!m_client.decidePolicyForNavigationAction) + return WKBundlePagePolicyActionPassThrough; + + RefPtr<WebURLRequest> request = WebURLRequest::create(resourceRequest); + + WKTypeRef userDataToPass = 0; + WKBundlePagePolicyAction policy = m_client.decidePolicyForNavigationAction(toAPI(page), toAPI(frame), toAPI(action), toAPI(request.get()), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); + return policy; +} + +WKBundlePagePolicyAction InjectedBundlePagePolicyClient::decidePolicyForNewWindowAction(WebPage* page, WebFrame* frame, InjectedBundleNavigationAction* action, const ResourceRequest& resourceRequest, const String& frameName, RefPtr<APIObject>& userData) +{ + if (!m_client.decidePolicyForNewWindowAction) + return WKBundlePagePolicyActionPassThrough; + + RefPtr<WebURLRequest> request = WebURLRequest::create(resourceRequest); + + WKTypeRef userDataToPass = 0; + WKBundlePagePolicyAction policy = m_client.decidePolicyForNewWindowAction(toAPI(page), toAPI(frame), toAPI(action), toAPI(request.get()), toAPI(frameName.impl()), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); + return policy; +} + +WKBundlePagePolicyAction InjectedBundlePagePolicyClient::decidePolicyForResponse(WebPage* page, WebFrame* frame, const ResourceResponse& resourceResponse, const ResourceRequest& resourceRequest, RefPtr<APIObject>& userData) +{ + if (!m_client.decidePolicyForResponse) + return WKBundlePagePolicyActionPassThrough; + + RefPtr<WebURLResponse> response = WebURLResponse::create(resourceResponse); + RefPtr<WebURLRequest> request = WebURLRequest::create(resourceRequest); + + WKTypeRef userDataToPass = 0; + WKBundlePagePolicyAction policy = m_client.decidePolicyForResponse(toAPI(page), toAPI(frame), toAPI(response.get()), toAPI(request.get()), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); + return policy; +} + +void InjectedBundlePagePolicyClient::unableToImplementPolicy(WebPage* page, WebFrame* frame, const WebCore::ResourceError& error, RefPtr<APIObject>& userData) +{ + if (!m_client.unableToImplementPolicy) + return; + + WKTypeRef userDataToPass = 0; + m_client.unableToImplementPolicy(toAPI(page), toAPI(frame), toAPI(error), &userDataToPass, m_client.clientInfo); + userData = adoptRef(toImpl(userDataToPass)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePagePolicyClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePagePolicyClient.h new file mode 100644 index 000000000..3cdbebe60 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePagePolicyClient.h @@ -0,0 +1,56 @@ +/* + * 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 InjectedBundlePagePolicyClient_h +#define InjectedBundlePagePolicyClient_h + +#include "APIClient.h" +#include "APIObject.h" +#include "WKBundlePage.h" +#include <wtf/Forward.h> + +namespace WebCore { + class ResourceError; + class ResourceRequest; + class ResourceResponse; +} + +namespace WebKit { + +class InjectedBundleNavigationAction; +class WebFrame; +class WebPage; + +class InjectedBundlePagePolicyClient : public APIClient<WKBundlePagePolicyClient, kWKBundlePagePolicyClientCurrentVersion> { +public: + WKBundlePagePolicyAction decidePolicyForNavigationAction(WebPage*, WebFrame*, InjectedBundleNavigationAction*, const WebCore::ResourceRequest&, RefPtr<APIObject>& userData); + WKBundlePagePolicyAction decidePolicyForNewWindowAction(WebPage*, WebFrame*, InjectedBundleNavigationAction*, const WebCore::ResourceRequest&, const String& frameName, RefPtr<APIObject>& userData); + WKBundlePagePolicyAction decidePolicyForResponse(WebPage*, WebFrame*, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, RefPtr<APIObject>& userData); + void unableToImplementPolicy(WebPage*, WebFrame*, const WebCore::ResourceError&, RefPtr<APIObject>& userData); +}; + +} // namespace WebKit + +#endif // InjectedBundlePagePolicyClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageResourceLoadClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageResourceLoadClient.cpp new file mode 100644 index 000000000..49dcac6cc --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageResourceLoadClient.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 "config.h" +#include "InjectedBundlePageResourceLoadClient.h" + +#include "WKAPICast.h" +#include "WKBundleAPICast.h" + +using namespace WebCore; + +namespace WebKit { + +void InjectedBundlePageResourceLoadClient::didInitiateLoadForResource(WebPage* page, WebFrame* frame, uint64_t identifier, const WebCore::ResourceRequest& request, bool pageIsProvisionallyLoading) +{ + if (!m_client.didInitiateLoadForResource) + return; + + m_client.didInitiateLoadForResource(toAPI(page), toAPI(frame), identifier, toAPI(request), pageIsProvisionallyLoading, m_client.clientInfo); +} + +void InjectedBundlePageResourceLoadClient::willSendRequestForFrame(WebPage* page, WebFrame* frame, uint64_t identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) +{ + if (!m_client.willSendRequestForFrame) + return; + + RefPtr<WebURLRequest> returnedRequest = adoptRef(toImpl(m_client.willSendRequestForFrame(toAPI(page), toAPI(frame), identifier, toAPI(request), toAPI(redirectResponse), m_client.clientInfo))); + if (returnedRequest) + request = returnedRequest->resourceRequest(); + else + request = ResourceRequest(); +} + +void InjectedBundlePageResourceLoadClient::didReceiveResponseForResource(WebPage* page, WebFrame* frame, uint64_t identifier, const WebCore::ResourceResponse& response) +{ + if (!m_client.didReceiveResponseForResource) + return; + + m_client.didReceiveResponseForResource(toAPI(page), toAPI(frame), identifier, toAPI(response), m_client.clientInfo); +} + +void InjectedBundlePageResourceLoadClient::didReceiveContentLengthForResource(WebPage* page, WebFrame* frame, uint64_t identifier, uint64_t contentLength) +{ + if (!m_client.didReceiveContentLengthForResource) + return; + + m_client.didReceiveContentLengthForResource(toAPI(page), toAPI(frame), identifier, contentLength, m_client.clientInfo); +} + +void InjectedBundlePageResourceLoadClient::didFinishLoadForResource(WebPage* page, WebFrame* frame, uint64_t identifier) +{ + if (!m_client.didFinishLoadForResource) + return; + + m_client.didFinishLoadForResource(toAPI(page), toAPI(frame), identifier, m_client.clientInfo); +} + +void InjectedBundlePageResourceLoadClient::didFailLoadForResource(WebPage* page, WebFrame* frame, uint64_t identifier, const WebCore::ResourceError& error) +{ + if (!m_client.didFailLoadForResource) + return; + + m_client.didFailLoadForResource(toAPI(page), toAPI(frame), identifier, toAPI(error), m_client.clientInfo); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageResourceLoadClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageResourceLoadClient.h new file mode 100644 index 000000000..68c68205c --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageResourceLoadClient.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 InjectedBundlePageResourceLoadClient_h +#define InjectedBundlePageResourceLoadClient_h + +#include "APIClient.h" +#include "SameDocumentNavigationType.h" +#include "WKBundlePage.h" +#include <JavaScriptCore/JSBase.h> +#include <wtf/Forward.h> + +namespace WebCore { +class ResourceError; +class ResourceRequest; +class ResourceResponse; +} + +namespace WebKit { + +class APIObject; +class WebPage; +class WebFrame; + +class InjectedBundlePageResourceLoadClient : public APIClient<WKBundlePageResourceLoadClient, kWKBundlePageResourceLoadClientCurrentVersion> { +public: + void didInitiateLoadForResource(WebPage*, WebFrame*, uint64_t identifier, const WebCore::ResourceRequest&, bool pageIsProvisionallyLoading); + void willSendRequestForFrame(WebPage*, WebFrame*, uint64_t identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse&); + void didReceiveResponseForResource(WebPage*, WebFrame*, uint64_t identifier, const WebCore::ResourceResponse&); + void didReceiveContentLengthForResource(WebPage*, WebFrame*, uint64_t identifier, uint64_t contentLength); + void didFinishLoadForResource(WebPage*, WebFrame*, uint64_t identifier); + void didFailLoadForResource(WebPage*, WebFrame*, uint64_t identifier, const WebCore::ResourceError&); +}; + +} // namespace WebKit + +#endif // InjectedBundlePageResourceLoadClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp new file mode 100644 index 000000000..b8c9c6206 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.cpp @@ -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. + */ + +#include "config.h" +#include "InjectedBundlePageUIClient.h" + +#include "InjectedBundleHitTestResult.h" +#include "WKAPICast.h" +#include "WebGraphicsContext.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) + return; + + m_client.pageDidScroll(toAPI(page), m_client.clientInfo); +} + +bool InjectedBundlePageUIClient::shouldPaintCustomOverhangArea() +{ + return m_client.paintCustomOverhangArea; +} + +void InjectedBundlePageUIClient::paintCustomOverhangArea(WebPage* page, GraphicsContext* graphicsContext, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect) +{ + ASSERT(shouldPaintCustomOverhangArea()); + + RefPtr<WebGraphicsContext> context = WebGraphicsContext::create(graphicsContext); + m_client.paintCustomOverhangArea(toAPI(page), toAPI(context.get()), toAPI(horizontalOverhangArea), toAPI(verticalOverhangArea), toAPI(dirtyRect), m_client.clientInfo); +} + +String InjectedBundlePageUIClient::shouldGenerateFileForUpload(WebPage* page, const String& originalFilePath) +{ + if (!m_client.shouldGenerateFileForUpload) + return String(); + RefPtr<WebString> generatedFilePath = adoptRef(toImpl(m_client.shouldGenerateFileForUpload(toAPI(page), toAPI(originalFilePath.impl()), m_client.clientInfo))); + return generatedFilePath ? generatedFilePath->string() : String(); +} + +String InjectedBundlePageUIClient::generateFileForUpload(WebPage* page, const String& originalFilePath) +{ + if (!m_client.shouldGenerateFileForUpload) + return String(); + RefPtr<WebString> generatedFilePath = adoptRef(toImpl(m_client.generateFileForUpload(toAPI(page), toAPI(originalFilePath.impl()), m_client.clientInfo))); + return generatedFilePath ? generatedFilePath->string() : String(); +} + +bool InjectedBundlePageUIClient::shouldRubberBandInDirection(WebPage* page, WKScrollDirection direction) const +{ + if (!m_client.shouldRubberBandInDirection) + return true; + return m_client.shouldRubberBandInDirection(toAPI(page), direction, m_client.clientInfo); +} + +WKBundlePageUIElementVisibility InjectedBundlePageUIClient::statusBarIsVisible(WebPage* page) +{ + if (!m_client.statusBarIsVisible) + return WKBundlePageUIElementVisibilityUnknown; + + return m_client.statusBarIsVisible(toAPI(page), m_client.clientInfo); +} + +WKBundlePageUIElementVisibility InjectedBundlePageUIClient::menuBarIsVisible(WebPage* page) +{ + if (!m_client.menuBarIsVisible) + return WKBundlePageUIElementVisibilityUnknown; + + return m_client.menuBarIsVisible(toAPI(page), m_client.clientInfo); +} + +WKBundlePageUIElementVisibility InjectedBundlePageUIClient::toolbarsAreVisible(WebPage* page) +{ + if (!m_client.toolbarsAreVisible) + return WKBundlePageUIElementVisibilityUnknown; + + return m_client.toolbarsAreVisible(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 000000000..de2928aa5 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageUIClient.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 InjectedBundlePageUIClient_h +#define InjectedBundlePageUIClient_h + +#include "APIClient.h" +#include "WKBundlePage.h" +#include "WebEvent.h" +#include <wtf/Forward.h> + +namespace WebCore { + class GraphicsContext; + class HitTestResult; + class IntRect; +} + +namespace WebKit { + +class APIObject; +class WebFrame; +class WebPage; + +class InjectedBundlePageUIClient : public APIClient<WKBundlePageUIClient, kWKBundlePageUIClientCurrentVersion> { +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*); + + bool shouldPaintCustomOverhangArea(); + void paintCustomOverhangArea(WebPage*, WebCore::GraphicsContext*, const WebCore::IntRect&, const WebCore::IntRect&, const WebCore::IntRect&); + + String shouldGenerateFileForUpload(WebPage*, const String& originalFilePath); + String generateFileForUpload(WebPage*, const String& originalFilePath); + + bool shouldRubberBandInDirection(WebPage*, WKScrollDirection) const; + + WKBundlePageUIElementVisibility statusBarIsVisible(WebPage*); + WKBundlePageUIElementVisibility menuBarIsVisible(WebPage*); + WKBundlePageUIElementVisibility toolbarsAreVisible(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 000000000..2f40fd305 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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(); +} + +void InjectedBundleScriptWorld::clearWrappers() +{ + m_world->clearWrappers(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.h new file mode 100644 index 000000000..7562a6f8f --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundleScriptWorld.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 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; + + void clearWrappers(); + +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 000000000..49d66966a --- /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/efl/InjectedBundleEfl.cpp b/Source/WebKit2/WebProcess/InjectedBundle/efl/InjectedBundleEfl.cpp new file mode 100644 index 000000000..294ca06a6 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/efl/InjectedBundleEfl.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" +#include <WebCore/NotImplemented.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/gtk/InjectedBundleGtk.cpp b/Source/WebKit2/WebProcess/InjectedBundle/gtk/InjectedBundleGtk.cpp new file mode 100644 index 000000000..ca1a43f8c --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/gtk/InjectedBundleGtk.cpp @@ -0,0 +1,61 @@ +/* + * 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 "config.h" +#include "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" +#include <WebCore/FileSystem.h> +#include <wtf/text/CString.h> + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundle::load(APIObject* initializationUserData) +{ + m_platformBundle = g_module_open(fileSystemRepresentation(m_path).data(), G_MODULE_BIND_LOCAL); + if (!m_platformBundle) { + g_warning("Error loading the injected bundle (%s): %s", m_path.utf8().data(), g_module_error()); + return false; + } + + WKBundleInitializeFunctionPtr initializeFunction = 0; + if (!g_module_symbol(m_platformBundle, "WKBundleInitialize", reinterpret_cast<void**>(&initializeFunction)) || !initializeFunction) { + g_warning("Error loading WKBundleInitialize symbol from injected bundle."); + return false; + } + + initializeFunction(toAPI(this), toAPI(initializationUserData)); + return true; +} + +void InjectedBundle::activateMacFontAscentHack() +{ +} + +} // 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 000000000..b9973ad17 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/mac/InjectedBundleMac.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 "config.h" +#include "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" +#include <stdio.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 000000000..a5183b135 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/qt/InjectedBundleQt.cpp @@ -0,0 +1,61 @@ +/* + * 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 "config.h" +#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 000000000..08c9a937b --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.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 "config.h" +#include "InjectedBundle.h" + +#include "WKBundleAPICast.h" +#include "WKBundleInitialize.h" +#include "WebCertificateInfo.h" +#include <WebCore/ResourceHandle.h> +#include <WebCore/SimpleFontData.h> +#include <wtf/text/CString.h> + +#include <windows.h> +#include <winbase.h> +#include <shlobj.h> +#include <shlwapi.h> + +#if USE(CFNETWORK) +#include <WebCore/CertificateCFWin.h> +#endif + +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); +} + +void InjectedBundle::setHostAllowsAnyHTTPSCertificate(const String& host) +{ +#if USE(CFNETWORK) + ResourceHandle::setHostAllowsAnyHTTPSCertificate(host); +#endif +} + +void InjectedBundle::setClientCertificate(const String& host, const String& certificateSystemStoreName, const WebCertificateInfo* certificateInfo) +{ +#if USE(CFNETWORK) + ASSERT_ARG(certificateInfo, certificateInfo); + if (!certificateInfo) + return; + + const Vector<PCCERT_CONTEXT> certificateChain = certificateInfo->platformCertificateInfo().certificateChain(); + ASSERT(certificateChain.size() == 1); + if (certificateChain.size() != 1) + return; + + ASSERT_ARG(certificateSystemStoreName, !certificateSystemStoreName.isEmpty()); + if (certificateSystemStoreName.isEmpty()) + return; + + // The PCCERT_CONTEXT in the WebCertificateInfo we created using the message from the UI process doesn't contain enough information + // to actually use it in a request, we need to get the real certificate from the certificate store (which is typically the "MY" store). + String mutableCertificateSystemStoreName = certificateSystemStoreName; + HCERTSTORE certStore = ::CertOpenSystemStore(0, mutableCertificateSystemStoreName.charactersWithNullTermination()); + if (!certStore) { + LOG_ERROR("Could not open system certificate store %s", certificateSystemStoreName.ascii().data()); + return; + } + + PCCERT_CONTEXT realCert = ::CertFindCertificateInStore(certStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, certificateChain.first(), 0); + if (!realCert) { + LOG_ERROR("Could not find certificate in system certificate store"); + return; + } + + ResourceHandle::setClientCertificate(host, WebCore::copyCertificateToData(realCert).get()); + CertFreeCertificateContext(realCert); + + // We can't close certStore here, since the certificate is still in use. +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp new file mode 100644 index 000000000..1137bae21 --- /dev/null +++ b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp @@ -0,0 +1,133 @@ +/* + * 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 "config.h" +#include "WebKeyValueStorageManager.h" + +#include "MessageID.h" +#include "SecurityOriginData.h" +#include "WebKeyValueStorageManagerProxyMessages.h" +#include "WebProcess.h" + +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityOriginHash.h> +#include <WebCore/StorageTracker.h> + +using namespace WebCore; + +namespace WebKit { + +WebKeyValueStorageManager& WebKeyValueStorageManager::shared() +{ + static WebKeyValueStorageManager& shared = *new WebKeyValueStorageManager; + return shared; +} + +WebKeyValueStorageManager::WebKeyValueStorageManager() +{ +} + +void WebKeyValueStorageManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebKeyValueStorageManagerMessage(connection, messageID, arguments); +} + +static void keyValueStorageOriginIdentifiers(Vector<SecurityOriginData>& identifiers) +{ + ASSERT(identifiers.isEmpty()); + + Vector<RefPtr<SecurityOrigin> > coreOrigins; + + StorageTracker::tracker().origins(coreOrigins); + + size_t size = coreOrigins.size(); + identifiers.reserveCapacity(size); + + for (size_t i = 0; i < size; ++i) { + SecurityOriginData originData; + + originData.protocol = coreOrigins[i]->protocol(); + originData.host = coreOrigins[i]->host(); + originData.port = coreOrigins[i]->port(); + + identifiers.uncheckedAppend(originData); + } +} + +static void dispatchDidGetKeyValueStorageOrigins(const Vector<SecurityOriginData>& identifiers, uint64_t callbackID) +{ + WebProcess::shared().connection()->send(Messages::WebKeyValueStorageManagerProxy::DidGetKeyValueStorageOrigins(identifiers, callbackID), 0); +} + +void WebKeyValueStorageManager::getKeyValueStorageOrigins(uint64_t callbackID) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + if (!StorageTracker::tracker().originsLoaded()) { + m_originsRequestCallbackIDs.append(callbackID); + return; + } + + Vector<SecurityOriginData> identifiers; + keyValueStorageOriginIdentifiers(identifiers); + dispatchDidGetKeyValueStorageOrigins(identifiers, callbackID); +} + +void WebKeyValueStorageManager::didFinishLoadingOrigins() +{ + if (m_originsRequestCallbackIDs.isEmpty()) + return; + + Vector<SecurityOriginData> identifiers; + keyValueStorageOriginIdentifiers(identifiers); + + for (size_t i = 0; i < m_originsRequestCallbackIDs.size(); ++i) + dispatchDidGetKeyValueStorageOrigins(identifiers, m_originsRequestCallbackIDs[i]); + + m_originsRequestCallbackIDs.clear(); +} + +void WebKeyValueStorageManager::dispatchDidModifyOrigin(const String&) +{ +} + +void WebKeyValueStorageManager::deleteEntriesForOrigin(const SecurityOriginData& originData) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + RefPtr<SecurityOrigin> origin = SecurityOrigin::create(originData.protocol, originData.host, originData.port); + if (!origin) + return; + + StorageTracker::tracker().deleteOrigin(origin.get()); +} + +void WebKeyValueStorageManager::deleteAllEntries() +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + StorageTracker::tracker().deleteAllOrigins(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.h b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.h new file mode 100644 index 000000000..e8de0adc2 --- /dev/null +++ b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.h @@ -0,0 +1,70 @@ +/* + * 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 WebKeyValueStorageManager_h +#define WebKeyValueStorageManager_h + +#include <WebCore/StorageTrackerClient.h> +#include <wtf/Noncopyable.h> +#include <wtf/text/WTFString.h> + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebKit { + +struct SecurityOriginData; + +class WebKeyValueStorageManager : public WebCore::StorageTrackerClient { + WTF_MAKE_NONCOPYABLE(WebKeyValueStorageManager); + +public: + static WebKeyValueStorageManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + WebKeyValueStorageManager(); + + void getKeyValueStorageOrigins(uint64_t callbackID); + void deleteEntriesForOrigin(const SecurityOriginData&); + void deleteAllEntries(); + + // WebCore::StorageTrackerClient + virtual void dispatchDidModifyOrigin(const String&) OVERRIDE; + virtual void didFinishLoadingOrigins() OVERRIDE; + + void didReceiveWebKeyValueStorageManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + Vector<uint64_t> m_originsRequestCallbackIDs; + bool m_originsLoaded; +}; + +} // namespace WebKit + +#endif // WebKeyValueStorageManager_h diff --git a/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.messages.in b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.messages.in new file mode 100644 index 000000000..2f0d64845 --- /dev/null +++ b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.messages.in @@ -0,0 +1,27 @@ +# 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 -> WebKeyValueStorageManager { + void GetKeyValueStorageOrigins(uint64_t callbackID) + void DeleteEntriesForOrigin(WebKit::SecurityOriginData originIdentifier) + void DeleteAllEntries() +} diff --git a/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp new file mode 100644 index 000000000..4a5d7f95e --- /dev/null +++ b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp @@ -0,0 +1,85 @@ +/* + * 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 "config.h" +#include "WebMediaCacheManager.h" + +#include "MessageID.h" +#include "SecurityOriginData.h" +#include "WebMediaCacheManagerProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/HTMLMediaElement.h> + +using namespace WebCore; + +namespace WebKit { + +WebMediaCacheManager& WebMediaCacheManager::shared() +{ + static WebMediaCacheManager& shared = *new WebMediaCacheManager; + return shared; +} + +WebMediaCacheManager::WebMediaCacheManager() +{ +} + +void WebMediaCacheManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebMediaCacheManagerMessage(connection, messageID, arguments); +} + +void WebMediaCacheManager::getHostnamesWithMediaCache(uint64_t callbackID) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + Vector<String> mediaCacheHostnames; + +#if ENABLE(VIDEO) + HTMLMediaElement::getSitesInMediaCache(mediaCacheHostnames); +#endif + + WebProcess::shared().connection()->send(Messages::WebMediaCacheManagerProxy::DidGetHostnamesWithMediaCache(mediaCacheHostnames, callbackID), 0); +} + +void WebMediaCacheManager::clearCacheForHostname(const String& hostname) +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + +#if ENABLE(VIDEO) + HTMLMediaElement::clearMediaCacheForSite(hostname); +#endif +} + +void WebMediaCacheManager::clearCacheForAllHostnames() +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + +#if ENABLE(VIDEO) + HTMLMediaElement::clearMediaCache(); +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.h b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.h new file mode 100644 index 000000000..909be97ba --- /dev/null +++ b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.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 WebMediaCacheManager_h +#define WebMediaCacheManager_h + +#include <wtf/Noncopyable.h> +#include <wtf/text/WTFString.h> + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebKit { + +class WebMediaCacheManager { + WTF_MAKE_NONCOPYABLE(WebMediaCacheManager); + +public: + static WebMediaCacheManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + WebMediaCacheManager(); + + void getHostnamesWithMediaCache(uint64_t callbackID); + void clearCacheForHostname(const String&); + void clearCacheForAllHostnames(); + + void didReceiveWebMediaCacheManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +}; + +} // namespace WebKit + +#endif // WebMediaCacheManager_h diff --git a/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.messages.in b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.messages.in new file mode 100644 index 000000000..5eee8cc8d --- /dev/null +++ b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.messages.in @@ -0,0 +1,27 @@ +# 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 -> WebMediaCacheManager { + void GetHostnamesWithMediaCache(uint64_t callbackID) + void ClearCacheForHostname(WTF::String hostname) + void ClearCacheForAllHostnames() +} diff --git a/Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.cpp new file mode 100644 index 000000000..3eeaa5022 --- /dev/null +++ b/Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.cpp @@ -0,0 +1,119 @@ +/* + * 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 "config.h" +#include "NotificationPermissionRequestManager.h" + +#include "WebCoreArgumentCoders.h" +#include "WebNotificationManagerProxyMessages.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/Notification.h> +#include <WebCore/ScriptExecutionContext.h> +#include <WebCore/SecurityOrigin.h> + +using namespace WebCore; + +namespace WebKit { + +#if ENABLE(NOTIFICATIONS) +static uint64_t generateRequestID() +{ + static uint64_t uniqueRequestID = 1; + return uniqueRequestID++; +} +#endif + +PassRefPtr<NotificationPermissionRequestManager> NotificationPermissionRequestManager::create(WebPage* page) +{ + return adoptRef(new NotificationPermissionRequestManager(page)); +} + +NotificationPermissionRequestManager::NotificationPermissionRequestManager(WebPage* page) + : m_page(page) +{ +} + +void NotificationPermissionRequestManager::startRequest(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) +{ +#if ENABLE(NOTIFICATIONS) + uint64_t requestID = generateRequestID(); + m_originToIDMap.set(origin, requestID); + m_idToOriginMap.set(requestID, origin); + m_idToCallbackMap.set(requestID, callback); + m_page->send(Messages::WebPageProxy::RequestNotificationPermission(requestID, origin->databaseIdentifier())); +#else + UNUSED_PARAM(origin); + UNUSED_PARAM(callback); +#endif +} + +void NotificationPermissionRequestManager::cancelRequest(SecurityOrigin* origin) +{ +#if ENABLE(NOTIFICATIONS) + uint64_t id = m_originToIDMap.take(origin); + if (!id) + return; + + m_idToOriginMap.remove(id); + m_idToCallbackMap.remove(id); +#else + UNUSED_PARAM(origin); +#endif +} + +NotificationPresenter::Permission NotificationPermissionRequestManager::permissionLevel(SecurityOrigin* securityOrigin) +{ +#if ENABLE(NOTIFICATIONS) + uint64_t permissionLevel; + WebProcess::shared().connection()->sendSync(Messages::WebNotificationManagerProxy::NotificationPermissionLevel(securityOrigin->databaseIdentifier()), + Messages::WebNotificationManagerProxy::NotificationPermissionLevel::Reply(permissionLevel), + 0); + return static_cast<NotificationPresenter::Permission>(permissionLevel); +#else + UNUSED_PARAM(securityOrigin); + return NotificationPresenter::PermissionDenied; +#endif +} + +void NotificationPermissionRequestManager::didReceiveNotificationPermissionDecision(uint64_t requestID, bool allowed) +{ +#if ENABLE(NOTIFICATIONS) + if (!isRequestIDValid(requestID)) + return; + + RefPtr<VoidCallback> callback = m_idToCallbackMap.take(requestID); + if (!callback) + return; + + callback->handleEvent(); +#else + UNUSED_PARAM(requestID); + UNUSED_PARAM(allowed); +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.h b/Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.h new file mode 100644 index 000000000..5573c6a11 --- /dev/null +++ b/Source/WebKit2/WebProcess/Notifications/NotificationPermissionRequestManager.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 NotificationPermissionRequestManager_h +#define NotificationPermissionRequestManager_h + +#include <WebCore/NotificationPresenter.h> +#include <WebCore/VoidCallback.h> +#include <wtf/HashMap.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> + +namespace WebCore { +class Notification; +class SecurityOrigin; +} + +namespace WebKit { + +class WebPage; + +/// FIXME: Need to keep a queue of pending notifications which permission is still being requested. +class NotificationPermissionRequestManager : public RefCounted<NotificationPermissionRequestManager> { +public: + static PassRefPtr<NotificationPermissionRequestManager> create(WebPage*); + + void startRequest(WebCore::SecurityOrigin*, PassRefPtr<WebCore::VoidCallback>); + void cancelRequest(WebCore::SecurityOrigin*); + + // Synchronous call to retrieve permission level for given security origin + WebCore::NotificationPresenter::Permission permissionLevel(WebCore::SecurityOrigin*); + + void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed); + +private: + NotificationPermissionRequestManager(WebPage*); + + HashMap<uint64_t, RefPtr<WebCore::VoidCallback> > m_idToCallbackMap; + HashMap<RefPtr<WebCore::SecurityOrigin>, uint64_t> m_originToIDMap; + HashMap<uint64_t, RefPtr<WebCore::SecurityOrigin> > m_idToOriginMap; + + WebPage* m_page; +}; + +inline bool isRequestIDValid(uint64_t id) +{ + // This check makes sure that the ID is not equal to values needed by + // HashMap for bucketing. + return id && id != static_cast<uint64_t>(-1); +} + +} // namespace WebKit + +#endif // NotificationPermissionRequestManager_h diff --git a/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.cpp b/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.cpp new file mode 100644 index 000000000..dfc30f5f3 --- /dev/null +++ b/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.cpp @@ -0,0 +1,154 @@ +/* + * 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 "config.h" +#include "WebNotificationManager.h" + +#include "WebPage.h" +#include "WebProcess.h" + +#if ENABLE(NOTIFICATIONS) +#include "WebNotification.h" +#include "WebNotificationManagerProxyMessages.h" +#include "WebPageProxyMessages.h" +#include <WebCore/Notification.h> +#include <WebCore/ScriptExecutionContext.h> +#include <WebCore/SecurityOrigin.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +#if ENABLE(NOTIFICATIONS) +static uint64_t generateNotificationID() +{ + static uint64_t uniqueNotificationID = 1; + return uniqueNotificationID++; +} +#endif + +WebNotificationManager::WebNotificationManager(WebProcess* process) + : m_process(process) +{ +} + +WebNotificationManager::~WebNotificationManager() +{ +} + +void WebNotificationManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebNotificationManagerMessage(connection, messageID, arguments); +} + +bool WebNotificationManager::show(Notification* notification, WebPage* page) +{ +#if ENABLE(NOTIFICATIONS) + if (!notification) + return true; + + uint64_t notificationID = generateNotificationID(); + m_notificationMap.set(notification, notificationID); + m_notificationIDMap.set(notificationID, notification); + + m_process->connection()->send(Messages::WebPageProxy::ShowNotification(notification->contents().title, notification->contents().body, notification->scriptExecutionContext()->securityOrigin()->databaseIdentifier(), notificationID), page->pageID()); +#endif + return true; +} + +void WebNotificationManager::cancel(Notification* notification, WebPage* page) +{ +#if ENABLE(NOTIFICATIONS) + if (!notification) + return; + + uint64_t notificationID = m_notificationMap.get(notification); + if (!notificationID) + return; + + m_process->connection()->send(Messages::WebNotificationManagerProxy::Cancel(notificationID), page->pageID()); +#endif +} + +void WebNotificationManager::didDestroyNotification(Notification* notification, WebPage* page) +{ +#if ENABLE(NOTIFICATIONS) + uint64_t notificationID = m_notificationMap.take(notification); + if (!notificationID) + return; + + m_notificationIDMap.take(notificationID); + m_process->connection()->send(Messages::WebNotificationManagerProxy::DidDestroyNotification(notificationID), page->pageID()); +#endif +} + +void WebNotificationManager::didShowNotification(uint64_t notificationID) +{ +#if ENABLE(NOTIFICATIONS) + if (!isNotificationIDValid(notificationID)) + return; + + RefPtr<Notification> notification = m_notificationIDMap.get(notificationID); + if (!notification) + return; + + notification->dispatchShowEvent(); +#endif +} + +void WebNotificationManager::didClickNotification(uint64_t notificationID) +{ +#if ENABLE(NOTIFICATIONS) + if (!isNotificationIDValid(notificationID)) + return; + + RefPtr<Notification> notification = m_notificationIDMap.get(notificationID); + if (!notification) + return; + + notification->dispatchClickEvent(); +#endif +} + +void WebNotificationManager::didCloseNotifications(const Vector<uint64_t>& notificationIDs) +{ +#if ENABLE(NOTIFICATIONS) + size_t count = notificationIDs.size(); + for (size_t i = 0; i < count; ++i) { + uint64_t notificationID = notificationIDs[i]; + if (!isNotificationIDValid(notificationID)) + continue; + + RefPtr<Notification> notification = m_notificationIDMap.get(notificationID); + if (!notification) + continue; + + notification->dispatchCloseEvent(); + } +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.h b/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.h new file mode 100644 index 000000000..3b32f0ade --- /dev/null +++ b/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.h @@ -0,0 +1,83 @@ +/* + * 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 WebNotificationManager_h +#define WebNotificationManager_h + +#include "MessageID.h" +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +} + +namespace WebCore { +class Notification; +} + +namespace WebKit { + +class WebPage; +class WebProcess; + +class WebNotificationManager { + WTF_MAKE_NONCOPYABLE(WebNotificationManager); +public: + explicit WebNotificationManager(WebProcess*); + ~WebNotificationManager(); + + bool show(WebCore::Notification*, WebPage*); + void cancel(WebCore::Notification*, WebPage*); + // This callback comes from WebCore, not messaged from the UI process. + void didDestroyNotification(WebCore::Notification*, WebPage*); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + // Implemented in generated WebNotificationManagerMessageReceiver.cpp + void didReceiveWebNotificationManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void didShowNotification(uint64_t notificationID); + void didClickNotification(uint64_t notificationID); + void didCloseNotifications(const Vector<uint64_t>& notificationIDs); + + WebProcess* m_process; + +#if ENABLE(NOTIFICATIONS) + typedef HashMap<RefPtr<WebCore::Notification>, uint64_t> NotificationMap; + NotificationMap m_notificationMap; + + typedef HashMap<uint64_t, RefPtr<WebCore::Notification> > NotificationIDMap; + NotificationIDMap m_notificationIDMap; +#endif +}; + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.messages.in b/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.messages.in new file mode 100644 index 000000000..13d97ff7a --- /dev/null +++ b/Source/WebKit2/WebProcess/Notifications/WebNotificationManager.messages.in @@ -0,0 +1,27 @@ +# 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 -> WebNotificationManager { + DidShowNotification(uint64_t notificationID); + DidClickNotification(uint64_t notificationID); + DidCloseNotifications(Vector<uint64_t> notificationIDs); +} diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp new file mode 100644 index 000000000..898147135 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.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 "config.h" +#include "JSNPMethod.h" + +#include "JSNPObject.h" +#include <JavaScriptCore/Error.h> +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/JSGlobalObject.h> +#include <JavaScriptCore/JSObject.h> +#include <WebCore/JSHTMLElement.h> +#include <WebCore/JSPluginElementFunctions.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSNPMethod); + +const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPMethod) }; + +JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIdentifier npIdentifier) + : InternalFunction(globalObject, structure) + , m_npIdentifier(npIdentifier) +{ +} + +void JSNPMethod::finishCreation(JSGlobalData& globalData, const Identifier& name) +{ + Base::finishCreation(globalData, name); + ASSERT(inherits(&s_info)); +} + +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(JSCell*, 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 000000000..ff0961c38 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.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 JSNPMethod_h +#define JSNPMethod_h + +#include <JavaScriptCore/FunctionPrototype.h> +#include <JavaScriptCore/InternalFunction.h> +#include <JavaScriptCore/JSGlobalObject.h> + +typedef void* NPIdentifier; + +namespace WebKit { + +// A JSObject that wraps an NPMethod. +class JSNPMethod : public JSC::InternalFunction { +public: + typedef JSC::InternalFunction Base; + + static JSNPMethod* create(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject, const JSC::Identifier& name, NPIdentifier npIdent) + { + JSC::Structure* structure = createStructure(exec->globalData(), globalObject, globalObject->functionPrototype()); + JSNPMethod* method = new (JSC::allocateCell<JSNPMethod>(*exec->heap())) JSNPMethod(globalObject, structure, npIdent); + method->finishCreation(exec->globalData(), name); + return method; + } + + static const JSC::ClassInfo s_info; + + NPIdentifier npIdentifier() const { return m_npIdentifier; } + +protected: + void finishCreation(JSC::JSGlobalData&, const JSC::Identifier& name); + +private: + JSNPMethod(JSC::JSGlobalObject*, JSC::Structure*, NPIdentifier); + + static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info); + } + + static JSC::CallType getCallData(JSC::JSCell*, JSC::CallData&); + + 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 000000000..aa56a3752 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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/Assertions.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", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) }; + +JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRuntimeObjectMap* objectMap, NPObject* npObject) + : JSNonFinalObject(globalObject->globalData(), structure) + , m_objectMap(objectMap) + , m_npObject(npObject) +{ + ASSERT(globalObject == structure->globalObject()); +} + +void JSNPObject::finishCreation(JSGlobalObject* globalObject) +{ + Base::finishCreation(globalObject->globalData()); + ASSERT(inherits(&s_info)); + + // We should never have an NPJSObject inside a JSNPObject. + ASSERT(!NPJSObject::isNPJSObject(m_npObject)); + + retainNPObject(m_npObject); +} + +JSNPObject::~JSNPObject() +{ + ASSERT(!m_npObject); +} + +void JSNPObject::destroy(JSCell* cell) +{ + jsCast<JSNPObject*>(cell)->JSNPObject::~JSNPObject(); +} + +void JSNPObject::invalidate() +{ + ASSERT(m_npObject); + ASSERT_GC_OBJECT_INHERITS(this, &s_info); + + releaseNPObject(m_npObject); + m_npObject = 0; +} + +NPObject* JSNPObject::leakNPObject() +{ + ASSERT(m_npObject); + ASSERT_GC_OBJECT_INHERITS(this, &s_info); + + NPObject* object = m_npObject; + m_npObject = 0; + return object; +} + +JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) +{ + ASSERT_GC_OBJECT_INHERITS(this, &s_info); + 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) +{ + ASSERT_GC_OBJECT_INHERITS(this, &s_info); + 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) +{ + ASSERT_GC_OBJECT_INHERITS(this, &s_info); + 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::JSCell* cell, JSC::CallData& callData) +{ + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + if (!thisObject->m_npObject || !thisObject->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(JSCell* cell, ConstructData& constructData) +{ + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + if (!thisObject->m_npObject || !thisObject->m_npObject->_class->construct) + return ConstructTypeNone; + + constructData.native.function = constructWithConstructor; + return ConstructTypeHost; +} + +bool JSNPObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +{ + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + if (!thisObject->m_npObject) { + throwInvalidAccessError(exec); + return false; + } + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + + // First, check if the NPObject has a property with this name. + if (thisObject->m_npObject->_class->hasProperty && thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) { + slot.setCustom(thisObject, thisObject->propertyGetter); + return true; + } + + // Second, check if the NPObject has a method with this name. + if (thisObject->m_npObject->_class->hasMethod && thisObject->m_npObject->_class->hasMethod(thisObject->m_npObject, npIdentifier)) { + slot.setCustom(thisObject, thisObject->methodGetter); + return true; + } + + return false; +} + +bool JSNPObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + JSNPObject* thisObject = jsCast<JSNPObject*>(object); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + if (!thisObject->m_npObject) { + throwInvalidAccessError(exec); + return false; + } + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + + // First, check if the NPObject has a property with this name. + if (thisObject->m_npObject->_class->hasProperty && thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) { + PropertySlot slot; + slot.setCustom(thisObject, propertyGetter); + descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete); + return true; + } + + // Second, check if the NPObject has a method with this name. + if (thisObject->m_npObject->_class->hasMethod && thisObject->m_npObject->_class->hasMethod(thisObject->m_npObject, npIdentifier)) { + PropertySlot slot; + slot.setCustom(thisObject, methodGetter); + descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly); + return true; + } + + return false; +} + +void JSNPObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&) +{ + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + if (!thisObject->m_npObject) { + throwInvalidAccessError(exec); + return; + } + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + + if (!thisObject->m_npObject->_class->hasProperty || !thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) { + // FIXME: Should we throw an exception here? + return; + } + + if (!thisObject->m_npObject->_class->setProperty) + return; + + NPVariant variant; + thisObject->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(thisObject->m_objectMap); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant); + + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + + // FIXME: Should we throw an exception if setProperty returns false? + } + + releaseNPVariantValue(&variant); +} + +bool JSNPObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName) +{ + return jsCast<JSNPObject*>(cell)->deleteProperty(exec, npIdentifierFromIdentifier(propertyName)); +} + +bool JSNPObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName) +{ + return jsCast<JSNPObject*>(cell)->deleteProperty(exec, static_cast<NPIdentifier>(IdentifierRep::get(propertyName))); +} + +bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) +{ + ASSERT_GC_OBJECT_INHERITS(this, &s_info); + if (!m_npObject) { + throwInvalidAccessError(exec); + return false; + } + + if (!m_npObject->_class->removeProperty) { + // FIXME: Should we throw an exception here? + return false; + } + + // 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); + + // FIXME: Should we throw an exception if removeProperty returns false? + if (!m_npObject->_class->removeProperty(m_npObject, propertyName)) + return false; + + NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); + } + + return true; +} + +void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNameArray, EnumerationMode mode) +{ + JSNPObject* thisObject = jsCast<JSNPObject*>(object); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + if (!thisObject->m_npObject) { + throwInvalidAccessError(exec); + return; + } + + if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(thisObject->m_npObject->_class) || !thisObject->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(thisObject->m_objectMap); + + { + JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); + + // FIXME: Should we throw an exception if enumerate returns false? + if (!thisObject->m_npObject->_class->enumerate(thisObject->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)); + ASSERT_GC_OBJECT_INHERITS(thisObj, &s_info); + + 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)); + ASSERT_GC_OBJECT_INHERITS(thisObj, &s_info); + + if (!thisObj->m_npObject) + return throwInvalidAccessError(exec); + + NPIdentifier npIdentifier = npIdentifierFromIdentifier(methodName); + return JSNPMethod::create(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 000000000..7f26f0d67 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h @@ -0,0 +1,107 @@ +/* + * 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/JSGlobalObject.h> +#include <JavaScriptCore/JSObject.h> +#include <JavaScriptCore/ObjectPrototype.h> + +typedef void* NPIdentifier; +struct NPObject; + +namespace WebKit { + +class NPRuntimeObjectMap; + +// JSNPObject is a JSObject that wraps an NPObject. + +class JSNPObject : public JSC::JSNonFinalObject { +public: + typedef JSC::JSNonFinalObject Base; + + static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject) + { + JSC::Structure* structure = createStructure(globalObject->globalData(), globalObject, globalObject->objectPrototype()); + JSNPObject* object = new (JSC::allocateCell<JSNPObject>(globalObject->globalData().heap)) JSNPObject(globalObject, structure, objectMap, npObject); + object->finishCreation(globalObject); + return object; + } + + ~JSNPObject(); + static void destroy(JSCell*); + + void invalidate(); + + // Used to invalidate an NPObject asynchronously. + NPObject* leakNPObject(); + + 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; } + +protected: + void finishCreation(JSC::JSGlobalObject*); + +private: + JSNPObject(JSC::JSGlobalObject*, JSC::Structure*, NPRuntimeObjectMap*, NPObject*); + + static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; + + static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info); + } + + static JSC::CallType getCallData(JSC::JSCell*, JSC::CallData&); + static JSC::ConstructType getConstructData(JSC::JSCell*, JSC::ConstructData&); + + static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + static bool getOwnPropertyDescriptor(JSC::JSObject*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&); + static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); + + static bool deleteProperty(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName); + static bool deletePropertyByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName); + + bool deleteProperty(JSC::ExecState*, NPIdentifier propertyName); + + static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode); + + 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*); + + 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 000000000..f0ed9f74c --- /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 "config.h" +#include "NPJSObject.h" + +#include "JSNPObject.h" +#include "NPRuntimeObjectMap.h" +#include "NPRuntimeUtilities.h" +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/JSObject.h> +#include <JavaScriptCore/StrongInlines.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(JSGlobalData& globalData, 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(globalData, 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(JSGlobalData& globalData, NPRuntimeObjectMap* objectMap, JSObject* jsObject) +{ + ASSERT(!m_objectMap); + ASSERT(!m_jsObject); + + m_objectMap = objectMap; + m_jsObject.set(globalData, 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.get(); + 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->methodTable()->put(m_jsObject.get(), exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot); + } else + m_jsObject->methodTable()->putByIndex(m_jsObject.get(), 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->methodTable()->deleteProperty(m_jsObject.get(), exec, identifier); + } else { + if (!m_jsObject->hasProperty(exec, identifierRep->number())) { + exec->clearException(); + return false; + } + + m_jsObject->methodTable()->deletePropertyByIndex(m_jsObject.get(), 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->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, ExcludeDontEnumProperties); + + 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.get(), 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.get(), 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->methodTable()->toThisObject(m_jsObject.get(), exec), 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 000000000..f0ee07a5c --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h @@ -0,0 +1,98 @@ +/* + * 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/Strong.h> +#include <WebCore/npruntime_internal.h> +#include <wtf/Noncopyable.h> + +namespace JSC { + +class JSGlobalData; +class JSGlobalObject; +class JSObject; + +} + +namespace WebKit { + +class NPRuntimeObjectMap; + +// NPJSObject is an NPObject that wraps a JSObject. +class NPJSObject : public NPObject { + WTF_MAKE_NONCOPYABLE(NPJSObject); +public: + static NPJSObject* create(JSC::JSGlobalData&, NPRuntimeObjectMap*, JSC::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(JSC::JSGlobalData&, NPRuntimeObjectMap*, JSC::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::Strong<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 000000000..5aadd13f4 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NPRuntimeObjectMap.h" + +#include "JSNPObject.h" +#include "NPJSObject.h" +#include "NPRuntimeUtilities.h" +#include "PluginView.h" +#include "WebProcess.h" +#include <JavaScriptCore/Completion.h> +#include <JavaScriptCore/Error.h> +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/SourceCode.h> +#include <JavaScriptCore/Strong.h> +#include <JavaScriptCore/StrongInlines.h> +#include <WebCore/Frame.h> + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + + +NPRuntimeObjectMap::NPRuntimeObjectMap(PluginView* pluginView) + : m_pluginView(pluginView) + , m_finalizationTimer(WebProcess::shared().runLoop(), this, &NPRuntimeObjectMap::invalidateQueuedObjects) +{ +} + +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(JSGlobalData& globalData, 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(globalData, 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 (JSC::Weak<JSNPObject> jsNPObject = m_jsNPObjects.get(npObject)) + return jsNPObject.get(); + + JSNPObject* jsNPObject = JSNPObject::create(globalObject, this, npObject); + m_jsNPObjects.set(npObject, JSC::Weak<JSNPObject>(globalObject->globalData(), jsNPObject, this, npObject)); + + return jsNPObject; +} + +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(exec->globalData(), asObject(value)); + OBJECT_TO_NPVARIANT(npObject, variant); + return; + } + + ASSERT_NOT_REACHED(); +} + +bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String&scriptString, NPVariant* result) +{ + Strong<JSGlobalObject> globalObject(this->globalObject()->globalData(), this->globalObject()); + if (!globalObject) + return false; + + ExecState* exec = globalObject->globalExec(); + + JSLock lock(SilenceAssertionsOnly); + JSValue thisValue = getOrCreateJSObject(globalObject.get(), npObject); + + globalObject->globalData().timeoutChecker.start(); + JSValue resultValue = JSC::evaluate(exec, globalObject->globalScopeChain(), makeSource(UString(scriptString.impl())), thisValue); + globalObject->globalData().timeoutChecker.stop(); + + 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<NPObject*> objects; + + for (HashMap<NPObject*, JSC::Weak<JSNPObject> >::iterator ptr = m_jsNPObjects.begin(), end = m_jsNPObjects.end(); ptr != end; ++ptr) + objects.append(ptr->second->leakNPObject()); + + m_jsNPObjects.clear(); + + for (size_t i = 0; i < objects.size(); ++i) + releaseNPObject(objects[i]); + + // Deal with any objects that were scheduled for delayed destruction + if (m_npObjectsToFinalize.isEmpty()) + return; + ASSERT(m_finalizationTimer.isActive()); + m_finalizationTimer.stop(); + invalidateQueuedObjects(); +} + +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(); +} + +void NPRuntimeObjectMap::invalidateQueuedObjects() +{ + ASSERT(m_npObjectsToFinalize.size()); + // We deliberately re-request m_npObjectsToFinalize.size() as custom dealloc + // functions may execute JS and so get more objects added to the dealloc queue + for (size_t i = 0; i < m_npObjectsToFinalize.size(); ++i) + deallocateNPObject(m_npObjectsToFinalize[i]); + m_npObjectsToFinalize.clear(); +} + +void NPRuntimeObjectMap::addToInvalidationQueue(NPObject* npObject) +{ + if (trySafeReleaseNPObject(npObject)) + return; + if (m_npObjectsToFinalize.isEmpty()) + m_finalizationTimer.startOneShot(0); + ASSERT(m_finalizationTimer.isActive()); + m_npObjectsToFinalize.append(npObject); +} + +void NPRuntimeObjectMap::finalize(JSC::Handle<JSC::Unknown> handle, void* context) +{ + HashMap<NPObject*, JSC::Weak<JSNPObject> >::iterator found = m_jsNPObjects.find(static_cast<NPObject*>(context)); + ASSERT(found != m_jsNPObjects.end()); + ASSERT_UNUSED(handle, asObject(handle.get()) == found->second); + JSNPObject* object = found->second.get(); + m_jsNPObjects.remove(found); + addToInvalidationQueue(object->leakNPObject()); +} + +} // 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 000000000..bef701bee --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h @@ -0,0 +1,106 @@ +/* + * 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 "RunLoop.h" + +#include <heap/Weak.h> +#include <wtf/Forward.h> +#include <wtf/HashMap.h> + +struct NPObject; +typedef struct _NPVariant NPVariant; + +namespace JSC { + class ExecState; + class JSGlobalData; + 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 : private JSC::WeakHandleOwner { +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::JSGlobalData&, 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: + // WeakHandleOwner + virtual void finalize(JSC::Handle<JSC::Unknown>, void* context); + void addToInvalidationQueue(NPObject*); + void invalidateQueuedObjects(); + + PluginView* m_pluginView; + + HashMap<JSC::JSObject*, NPJSObject*> m_npJSObjects; + HashMap<NPObject*, JSC::Weak<JSNPObject> > m_jsNPObjects; + Vector<NPObject*> m_npObjectsToFinalize; + RunLoop::Timer<NPRuntimeObjectMap> m_finalizationTimer; +}; + +} // 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 000000000..71bf90b4d --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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++; +} + +bool trySafeReleaseNPObject(NPObject* npObject) +{ + ASSERT(npObject); + if (!npObject) + return true; + + ASSERT(npObject->referenceCount >= 1); + + npObject->referenceCount--; + if (npObject->referenceCount) + return true; + if (npObject->_class->deallocate) + return false; + deallocateNPObject(npObject); + return true; +} + +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 000000000..2f135b250 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeUtilities.h @@ -0,0 +1,70 @@ +/* + * 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*); + +// This function decrements the refcount of the specified object. If the +// refcount reaches 0 it will attempt to destroy the object. If the object has +// a custom deallocate function it will fail and return false, so it will be +// up to the caller to call deallocateNPObject. +// This function is used to implement the delayed finalization of NPObjects +// released during GC. +bool trySafeReleaseNPObject(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 000000000..a8a806e01 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp @@ -0,0 +1,1064 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetscapeBrowserFuncs.h" + +#include "NPRuntimeUtilities.h" +#include "NetscapePlugin.h" +#include "PluginController.h" +#include <WebCore/HTTPHeaderMap.h> +#include <WebCore/IdentifierRep.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/ProtectionSpace.h> +#include <WebCore/SharedBuffer.h> +#include <utility> + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +// Helper class for delaying destruction of a plug-in. +class PluginDestructionProtector { +public: + explicit PluginDestructionProtector(NetscapePlugin* plugin) + : m_protector(static_cast<Plugin*>(plugin)->controller()) + { + } + +private: + PluginController::PluginDestructionProtector m_protector; +}; + +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) +// Whether the browser supports compositing of Core Animation plug-ins. +static const unsigned WKNVSupportsCompositingCoreAnimationPluginsBool = 74656; + +// Whether the browser expects a non-retained Core Animation layer. +static const unsigned WKNVExpectsNonretainedLayer = 74657; + +// The Core Animation render server port. +static const unsigned WKNVCALayerRenderServerPort = 71879; + +#endif + +static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) +{ + switch (variable) { + case NPNVWindowNPObject: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + NPObject* windowNPObject = plugin->windowScriptNPObject(); + if (!windowNPObject) + return NPERR_GENERIC_ERROR; + + *(NPObject**)value = windowNPObject; + break; + } + case NPNVPluginElementNPObject: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + 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 NPNVcontentsScaleFactor: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + *(double*)value = plugin->contentsScaleFactor(); + break; + } + case NPNVsupportsCocoaBool: + // Always claim to support the Cocoa event model. + *(NPBool*)value = true; + break; + + case NPNVsupportsUpdatedCocoaTextInputBool: { + // The plug-in is asking whether we support the updated Cocoa text input model. + // If we haven't yet delivered a key down event to the plug-in, we can opt into the updated + // model and say that we support it. Otherwise, we'll just fall back and say that we don't support it. + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + bool supportsUpdatedTextInput = !plugin->hasHandledAKeyDownEvent(); + if (supportsUpdatedTextInput) + plugin->setPluginWantsLegacyCocoaTextInput(false); + + *reinterpret_cast<NPBool*>(value) = supportsUpdatedTextInput; + break; + } + + case WKNVCALayerRenderServerPort: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + *(mach_port_t*)value = plugin->compositingRenderServerPort(); + break; + } + + case WKNVExpectsNonretainedLayer: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + // Asking for this will make us expect a non-retained layer from the plug-in. + plugin->setPluginReturnsNonretainedLayer(true); + *(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: + *(NPBool*)value = true; + 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; +#elif PLUGIN_ARCHITECTURE(X11) + case NPNVxDisplay: { + if (!npp) + return NPERR_GENERIC_ERROR; + *reinterpret_cast<Display**>(value) = NetscapePlugin::x11HostDisplay(); + break; + } + case NPNVSupportsXEmbedBool: + *static_cast<NPBool*>(value) = true; + break; + case NPNVSupportsWindowless: + *static_cast<NPBool*>(value) = true; + break; + + case NPNVToolkit: { +#if PLATFORM(GTK) + *reinterpret_cast<uint32_t*>(value) = 2; +#else + const uint32_t expectedGTKToolKitVersion = 2; + + // Set the expected GTK version if we know that this plugin needs it or if the plugin call us + // with a null instance. The latter is the case with NSPluginWrapper plugins. + bool requiresGTKToolKitVersion; + if (!npp) + requiresGTKToolKitVersion = true; + else { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + requiresGTKToolKitVersion = plugin->quirks().contains(PluginQuirks::RequiresGTKToolKit); + } + + *reinterpret_cast<uint32_t*>(value) = requiresGTKToolKitVersion ? expectedGTKToolKitVersion : 0; +#endif + break; + } + + // TODO: implement NPNVnetscapeWindow once we want to support windowed plugins. +#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: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->setIsTransparent(value); + return NPERR_NO_ERROR; + } + + default: + notImplemented(); + return NPERR_GENERIC_ERROR; + } +} + +static void NPN_InvalidateRect(NPP npp, NPRect* invalidRect) +{ +#if PLUGIN_ARCHITECTURE(X11) + // NSPluginWrapper, a plugin wrapper binary that allows running 32-bit plugins + // on 64-bit architectures typically used in X11, will sometimes give us a null NPP here. + if (!npp) + return; +#endif + 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 npp, NPObject *npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + if (RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp)) { + bool returnValue; + if (plugin->tryToShortCircuitInvoke(npObject, methodName, arguments, argumentCount, returnValue, *result)) + return returnValue; + } + + 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); + PluginDestructionProtector protector(plugin.get()); + + String scriptString = String::fromUTF8WithLatin1Fallback(script->UTF8Characters, script->UTF8Length); + + return plugin->evaluate(npObject, scriptString, result); +} + +static bool NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NPVariant* result) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + if (npObject->_class->getProperty) + return npObject->_class->getProperty(npObject, propertyName, result); + + return false; +} + +static bool NPN_SetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, const NPVariant* value) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + if (npObject->_class->setProperty) + return npObject->_class->setProperty(npObject, propertyName, value); + + return false; +} + +static bool NPN_RemoveProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + if (npObject->_class->removeProperty) + return npObject->_class->removeProperty(npObject, propertyName); + + return false; +} + +static bool NPN_HasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + if (npObject->_class->hasProperty) + return npObject->_class->hasProperty(npObject, propertyName); + + return false; +} + +static bool NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + 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 npp, NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + 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 npp, void (*function)(void*), void* userData) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + plugin->pluginThreadAsyncCall(function, userData); +} + +static bool NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + + 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); + PluginDestructionProtector protector(plugin.get()); + + 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); + PluginDestructionProtector protector(plugin.get()); + + 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); + PluginDestructionProtector protector(plugin.get()); + + 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 bool initializeProtectionSpace(const char* protocol, const char* host, int port, const char* scheme, const char* realm, ProtectionSpace& protectionSpace) +{ + ProtectionSpaceServerType serverType; + if (!strcasecmp(protocol, "http")) + serverType = ProtectionSpaceServerHTTP; + else if (!strcasecmp(protocol, "https")) + serverType = ProtectionSpaceServerHTTPS; + else { + // We only care about http and https. + return false; + } + + ProtectionSpaceAuthenticationScheme authenticationScheme = ProtectionSpaceAuthenticationSchemeDefault; + if (serverType == ProtectionSpaceServerHTTP) { + if (!strcasecmp(scheme, "basic")) + authenticationScheme = ProtectionSpaceAuthenticationSchemeHTTPBasic; + else if (!strcmp(scheme, "digest")) + authenticationScheme = ProtectionSpaceAuthenticationSchemeHTTPDigest; + } + + protectionSpace = ProtectionSpace(host, port, serverType, realm, authenticationScheme); + return true; +} + +static NPError NPN_GetAuthenticationInfo(NPP npp, const char* protocol, const char* host, int32_t port, const char* scheme, + const char* realm, char** username, uint32_t* usernameLength, char** password, uint32_t* passwordLength) +{ + if (!protocol || !host || !scheme || !realm || !username || !usernameLength || !password || !passwordLength) + return NPERR_GENERIC_ERROR; + + ProtectionSpace protectionSpace; + if (!initializeProtectionSpace(protocol, host, port, scheme, realm, protectionSpace)) + return NPERR_GENERIC_ERROR; + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + String usernameString; + String passwordString; + if (!plugin->getAuthenticationInfo(protectionSpace, usernameString, passwordString)) + return NPERR_GENERIC_ERROR; + + NPError result = copyCString(usernameString.utf8(), username, usernameLength); + if (result != NPERR_NO_ERROR) + return result; + + result = copyCString(passwordString.utf8(), password, passwordLength); + if (result != NPERR_NO_ERROR) { + npnMemFree(*username); + return result; + } + + return NPERR_NO_ERROR; +} + +static uint32_t NPN_ScheduleTimer(NPP npp, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + return plugin->scheduleTimer(interval, repeat, timerFunc); +} + +static void NPN_UnscheduleTimer(NPP npp, uint32_t timerID) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + plugin->unscheduleTimer(timerID); +} + +#if PLATFORM(MAC) +static NPError NPN_PopUpContextMenu(NPP npp, NPMenu* menu) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + return plugin->popUpContextMenu(menu); +} + +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 000000000..49a7f3a9d --- /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 000000000..1f09dc408 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -0,0 +1,964 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetscapePlugin.h" + +#include "NPRuntimeObjectMap.h" +#include "NPRuntimeUtilities.h" +#include "NetscapePluginStream.h" +#include "PluginController.h" +#include "ShareableBitmap.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_nextRequestID(0) + , m_pluginModule(pluginModule) + , m_npWindow() + , m_isStarted(false) +#if PLATFORM(MAC) + , m_isWindowed(false) +#else + , m_isWindowed(true) +#endif + , m_isTransparent(false) + , m_inNPPNew(false) + , m_loadManually(false) + , m_nextTimerID(0) +#if PLATFORM(MAC) + , m_drawingModel(static_cast<NPDrawingModel>(-1)) + , m_eventModel(static_cast<NPEventModel>(-1)) + , m_pluginReturnsNonretainedLayer(!m_pluginModule->pluginQuirks().contains(PluginQuirks::ReturnsRetainedCoreAnimationLayer)) + , m_currentMouseEvent(0) + , m_pluginHasFocus(false) + , m_windowHasFocus(false) + , m_pluginWantsLegacyCocoaTextInput(true) + , m_isComplexTextInputEnabled(false) + , m_hasHandledAKeyDownEvent(false) + , m_ignoreNextKeyUpEventCounter(0) +#ifndef NP_NO_CARBON + , m_nullEventTimer(RunLoop::main(), this, &NetscapePlugin::nullEventTimerFired) + , m_npCGContext() +#endif +#elif PLUGIN_ARCHITECTURE(X11) + , m_drawable(0) + , m_pluginDisplay(0) +#endif +{ + m_npp.ndata = this; + m_npp.pdata = 0; + + m_pluginModule->incrementLoadCount(); +} + +NetscapePlugin::~NetscapePlugin() +{ + ASSERT(!m_isStarted); + ASSERT(m_timers.isEmpty()); + + m_pluginModule->decrementLoadCount(); +} + +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_pluginSize.width(), m_pluginSize.height()); + else + rect = IntRect(invalidRect->left, invalidRect->top, invalidRect->right - invalidRect->left, invalidRect->bottom - invalidRect->top); + + if (platformInvalidate(rect)) + return; + + controller()->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 PLUGIN_ARCHITECTURE(WIN) + static const char* MozillaUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0"; + + if (quirks().contains(PluginQuirks::WantsMozillaUserAgent)) + return MozillaUserAgent; +#endif + + if (m_userAgent.isNull()) { + String userAgent = controller()->userAgent(); + ASSERT(!userAgent.isNull()); + +#if PLUGIN_ARCHITECTURE(MAC) + if (quirks().contains(PluginQuirks::AppendVersion3UserAgent)) + userAgent += " Version/3.2.1"; +#endif + + m_userAgent = userAgent.utf8(); + } + 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; + + controller()->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, urlString, 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::setIsTransparent(bool isTransparent) +{ + m_isTransparent = isTransparent; +} + +void NetscapePlugin::setStatusbarText(const String& statusbarText) +{ + controller()->setStatusbarText(statusbarText); +} + +static void (*setExceptionFunction)(const String&); + +void NetscapePlugin::setSetExceptionFunction(void (*function)(const String&)) +{ + ASSERT(!setExceptionFunction || setExceptionFunction == function); + setExceptionFunction = function; +} + +void NetscapePlugin::setException(const String& exceptionString) +{ + ASSERT(setExceptionFunction); + setExceptionFunction(exceptionString); +} + +bool NetscapePlugin::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result) +{ + return controller()->evaluate(npObject, scriptString, result, allowPopups()); +} + +bool NetscapePlugin::isPrivateBrowsingEnabled() +{ + return controller()->isPrivateBrowsingEnabled(); +} + +NPObject* NetscapePlugin::windowScriptNPObject() +{ + return controller()->windowScriptNPObject(); +} + +NPObject* NetscapePlugin::pluginElementNPObject() +{ + return controller()->pluginElementNPObject(); +} + +bool NetscapePlugin::tryToShortCircuitInvoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result) +{ + return controller()->tryToShortCircuitInvoke(npObject, methodName, arguments, argumentCount, returnValue, result); +} + +void NetscapePlugin::cancelStreamLoad(NetscapePluginStream* pluginStream) +{ + if (pluginStream == m_manualStream) { + controller()->cancelManualStreamLoad(); + return; + } + + // Ask the plug-in controller to cancel this stream load. + controller()->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 controller()->isAcceleratedCompositingEnabled(); +#else + return false; +#endif +} + +void NetscapePlugin::pushPopupsEnabledState(bool state) +{ + m_popupEnabledStates.append(state); +} + +void NetscapePlugin::popPopupsEnabledState() +{ + ASSERT(!m_popupEnabledStates.isEmpty()); + + m_popupEnabledStates.removeLast(); +} + +void NetscapePlugin::pluginThreadAsyncCall(void (*function)(void*), void* userData) +{ + RunLoop::main()->dispatch(bind(&NetscapePlugin::handlePluginThreadAsyncCall, this, function, userData)); +} + +void NetscapePlugin::handlePluginThreadAsyncCall(void (*function)(void*), void* userData) +{ + if (!m_isStarted) + return; + + function(userData); +} + +PassOwnPtr<NetscapePlugin::Timer> NetscapePlugin::Timer::create(NetscapePlugin* netscapePlugin, unsigned timerID, unsigned interval, bool repeat, TimerFunc timerFunc) +{ + return adoptPtr(new Timer(netscapePlugin, timerID, interval, repeat, timerFunc)); +} + +NetscapePlugin::Timer::Timer(NetscapePlugin* netscapePlugin, unsigned timerID, unsigned interval, bool repeat, TimerFunc timerFunc) + : m_netscapePlugin(netscapePlugin) + , m_timerID(timerID) + , m_interval(interval) + , m_repeat(repeat) + , m_timerFunc(timerFunc) + , m_timer(RunLoop::main(), this, &Timer::timerFired) +{ +} + +NetscapePlugin::Timer::~Timer() +{ +} + +void NetscapePlugin::Timer::start() +{ + double timeInterval = m_interval / 1000.0; + + if (m_repeat) + m_timer.startRepeating(timeInterval); + else + m_timer.startOneShot(timeInterval); +} + +void NetscapePlugin::Timer::stop() +{ + m_timer.stop(); +} + +void NetscapePlugin::Timer::timerFired() +{ + m_timerFunc(&m_netscapePlugin->m_npp, m_timerID); + + if (!m_repeat) + m_netscapePlugin->unscheduleTimer(m_timerID); +} + +uint32_t NetscapePlugin::scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID)) +{ + if (!timerFunc) + return 0; + + // FIXME: Handle wrapping around. + unsigned timerID = ++m_nextTimerID; + + OwnPtr<Timer> timer = Timer::create(this, timerID, interval, repeat, timerFunc); + + // FIXME: Based on the plug-in visibility, figure out if we should throttle the timer, or if we should start it at all. + timer->start(); + m_timers.set(timerID, timer.leakPtr()); + + return timerID; +} + +void NetscapePlugin::unscheduleTimer(unsigned timerID) +{ + TimerMap::iterator it = m_timers.find(timerID); + if (it == m_timers.end()) + return; + + OwnPtr<Timer> timer = adoptPtr(it->second); + m_timers.remove(it); + + timer->stop(); +} + +double NetscapePlugin::contentsScaleFactor() +{ + return controller()->contentsScaleFactor(); +} + +String NetscapePlugin::proxiesForURL(const String& urlString) +{ + return controller()->proxiesForURL(urlString); +} + +String NetscapePlugin::cookiesForURL(const String& urlString) +{ + return controller()->cookiesForURL(urlString); +} + +void NetscapePlugin::setCookiesForURL(const String& urlString, const String& cookieString) +{ + controller()->setCookiesForURL(urlString, cookieString); +} + +bool NetscapePlugin::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password) +{ + return controller()->getAuthenticationInfo(protectionSpace, username, password); +} + +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() +{ + if (wantsPluginRelativeNPWindowCoordinates()) { + m_npWindow.x = 0; + m_npWindow.y = 0; + m_npWindow.clipRect.top = m_clipRect.y(); + m_npWindow.clipRect.left = m_clipRect.x(); + } else { + IntPoint pluginLocationInRootViewCoordinates = convertToRootView(IntPoint()); + IntPoint clipRectInRootViewCoordinates = convertToRootView(m_clipRect.location()); + + m_npWindow.x = pluginLocationInRootViewCoordinates.x(); + m_npWindow.y = pluginLocationInRootViewCoordinates.y(); + m_npWindow.clipRect.top = clipRectInRootViewCoordinates.y(); + m_npWindow.clipRect.left = clipRectInRootViewCoordinates.x(); + } + + m_npWindow.width = m_pluginSize.width(); + m_npWindow.height = m_pluginSize.height(); + m_npWindow.clipRect.right = m_npWindow.clipRect.left + m_clipRect.width(); + m_npWindow.clipRect.bottom = m_npWindow.clipRect.top + m_clipRect.height(); + + 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(const Parameters& parameters) +{ + 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) { + String parameterName = parameters.names[i]; + +#if PLUGIN_ARCHITECTURE(MAC) + if (m_pluginModule->pluginQuirks().contains(PluginQuirks::WantsLowercaseParameterNames)) + parameterName = parameterName.lower(); +#endif + + paramNames.append(parameterName.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()); + } + +#if PLUGIN_ARCHITECTURE(MAC) + if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeTransparentIfBackgroundAttributeExists)) { + for (size_t i = 0; i < parameters.names.size(); ++i) { + if (equalIgnoringCase(parameters.names[i], "background")) { + setIsTransparent(true); + break; + } + } + } +#endif + + 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(); + +#if !PLUGIN_ARCHITECTURE(MAC) && !PLUGIN_ARCHITECTURE(X11) + m_npWindow.window = 0; + callSetWindow(); +#endif + + NPP_Destroy(0); + + m_isStarted = false; + + platformDestroy(); + + deleteAllValues(m_timers); + m_timers.clear(); +} + +void NetscapePlugin::paint(GraphicsContext* context, const IntRect& dirtyRect) +{ + ASSERT(m_isStarted); + + platformPaint(context, dirtyRect); +} + +PassRefPtr<ShareableBitmap> NetscapePlugin::snapshot() +{ + if (!supportsSnapshotting() || m_pluginSize.isEmpty()) + return 0; + + ASSERT(m_isStarted); + + IntSize backingStoreSize = m_pluginSize; + backingStoreSize.scale(contentsScaleFactor()); + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha); + OwnPtr<GraphicsContext> context = bitmap->createGraphicsContext(); + + // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI + // which we currently don't have initiated in the plug-in process. + context->scale(FloatSize(contentsScaleFactor(), contentsScaleFactor())); + + platformPaint(context.get(), IntRect(IntPoint(), m_pluginSize), true); + + return bitmap.release(); +} + +bool NetscapePlugin::isTransparent() +{ + return m_isTransparent; +} + +void NetscapePlugin::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform) +{ + ASSERT(m_isStarted); + + if (pluginSize == m_pluginSize && m_clipRect == clipRect && m_pluginToRootViewTransform == pluginToRootViewTransform) { + // Nothing to do. + return; + } + + bool shouldCallWindow = true; + + // If the plug-in doesn't want window relative coordinates, we don't need to call setWindow unless its size or clip rect changes. + if (wantsPluginRelativeNPWindowCoordinates() && m_pluginSize == pluginSize && m_clipRect == clipRect) + shouldCallWindow = false; + + m_pluginSize = pluginSize; + m_clipRect = clipRect; + m_pluginToRootViewTransform = pluginToRootViewTransform; + + IntPoint frameRectLocationInWindowCoordinates = m_pluginToRootViewTransform.mapPoint(IntPoint()); + m_frameRectInWindowCoordinates = IntRect(frameRectLocationInWindowCoordinates, m_pluginSize); + + platformGeometryDidChange(); + + if (!shouldCallWindow) + return; + + callSetWindow(); +} + +void NetscapePlugin::visibilityDidChange() +{ + ASSERT(m_isStarted); + + platformVisibilityDidChange(); +} + +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& result) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(requestID)) + pluginStream->sendJavaScriptStream(result); +} + +void NetscapePlugin::streamDidReceiveResponse(uint64_t streamID, const KURL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& /* suggestedFileName */) +{ + 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, const String& /* suggestedFileName */) +{ + ASSERT(m_isStarted); + ASSERT(m_loadManually); + ASSERT(!m_manualStream); + + m_manualStream = NetscapePluginStream::create(this, 0, responseURL.string(), 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); + + if (!m_manualStream) + return; + 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::handleContextMenuEvent(const WebMouseEvent&) +{ + // We don't know if the plug-in has handled mousedown event by displaying a context menu, so we never want WebKit to show a default one. + return true; +} + +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; + +#if PLUGIN_ARCHITECTURE(MAC) + if (m_pluginModule->pluginQuirks().contains(PluginQuirks::ReturnsNonRetainedScriptableNPObject)) + retainNPObject(scriptableNPObject); +#endif + + return scriptableNPObject; +} + +void NetscapePlugin::contentsScaleFactorChanged(float scaleFactor) +{ + ASSERT(m_isStarted); + +#if PLUGIN_ARCHITECTURE(MAC) + double contentsScaleFactor = scaleFactor; + NPP_SetValue(NPNVcontentsScaleFactor, &contentsScaleFactor); +#endif +} + +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); +} + +bool NetscapePlugin::getFormValue(String& formValue) +{ + ASSERT(m_isStarted); + + char* formValueString = 0; + if (NPP_GetValue(NPPVformValue, &formValueString) != NPERR_NO_ERROR) + return false; + + formValue = String::fromUTF8(formValueString); + + // The plug-in allocates the form value string with NPN_MemAlloc so it needs to be freed with NPN_MemFree. + npnMemFree(formValueString); + return true; +} + +bool NetscapePlugin::handleScroll(ScrollDirection, ScrollGranularity) +{ + return false; +} + +Scrollbar* NetscapePlugin::horizontalScrollbar() +{ + return 0; +} + +Scrollbar* NetscapePlugin::verticalScrollbar() +{ + return 0; +} + +bool NetscapePlugin::supportsSnapshotting() const +{ +#if PLATFORM(MAC) + return m_pluginModule && m_pluginModule->pluginQuirks().contains(PluginQuirks::SupportsSnapshotting); +#endif + return false; +} + +IntPoint NetscapePlugin::convertToRootView(const IntPoint& pointInPluginCoordinates) const +{ + return m_pluginToRootViewTransform.mapPoint(pointInPluginCoordinates); +} + +bool NetscapePlugin::convertFromRootView(const IntPoint& pointInRootViewCoordinates, IntPoint& pointInPluginCoordinates) +{ + if (!m_pluginToRootViewTransform.isInvertible()) + return false; + + pointInPluginCoordinates = m_pluginToRootViewTransform.inverse().mapPoint(pointInRootViewCoordinates); + return true; +} + +} // 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 000000000..84541820c --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -0,0 +1,352 @@ +/* + * 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/AffineTransform.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; + class ProtectionSpace; +} + +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); + NPError popUpContextMenu(NPMenu*); + + void setPluginReturnsNonretainedLayer(bool pluginReturnsNonretainedLayer) { m_pluginReturnsNonretainedLayer = pluginReturnsNonretainedLayer; } + void setPluginWantsLegacyCocoaTextInput(bool pluginWantsLegacyCocoaTextInput) { m_pluginWantsLegacyCocoaTextInput = pluginWantsLegacyCocoaTextInput; } + + bool hasHandledAKeyDownEvent() const { return m_hasHandledAKeyDownEvent; } + + mach_port_t compositingRenderServerPort(); + + // Computes an affine transform from the given coordinate space to the screen coordinate space. + bool getScreenTransform(NPCoordinateSpace sourceSpace, WebCore::AffineTransform&); + +#ifndef NP_NO_CARBON + WindowRef windowRef() const; + bool isWindowActive() const { return m_windowHasFocus; } + void updateFakeWindowBounds(); + + static NetscapePlugin* netscapePluginFromWindow(WindowRef); + static unsigned buttonState(); +#endif + +#elif PLATFORM(WIN) + HWND containingWindow(); +#endif + + PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); } + + 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 setIsTransparent(bool); + void setStatusbarText(const String&); + static void setException(const String&); + bool evaluate(NPObject*, const String&scriptString, NPVariant* result); + bool isPrivateBrowsingEnabled(); + + static void setSetExceptionFunction(void (*)(const String&)); + + // These return retained objects. + NPObject* windowScriptNPObject(); + NPObject* pluginElementNPObject(); + + bool tryToShortCircuitInvoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result); + + void cancelStreamLoad(NetscapePluginStream*); + void removePluginStream(NetscapePluginStream*); + + bool isAcceleratedCompositingEnabled(); + + void pushPopupsEnabledState(bool enabled); + void popPopupsEnabledState(); + + void pluginThreadAsyncCall(void (*function)(void*), void* userData); + + // Called on the plug-in run loop (which is currently the main thread run loop). + void handlePluginThreadAsyncCall(void (*function)(void*), void* userData); + + unsigned scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID)); + void unscheduleTimer(unsigned timerID); + + double contentsScaleFactor(); + String proxiesForURL(const String& urlString); + String cookiesForURL(const String& urlString); + void setCookiesForURL(const String& urlString, const String& cookieString); + bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); + + // 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 platformVisibilityDidChange(); + void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect, bool isSnapshot = false); + + bool platformHandleMouseEvent(const WebMouseEvent&); + bool platformHandleWheelEvent(const WebWheelEvent&); + bool platformHandleMouseEnterEvent(const WebMouseEvent&); + bool platformHandleMouseLeaveEvent(const WebMouseEvent&); + bool platformHandleKeyboardEvent(const WebKeyboardEvent&); + void platformSetFocus(bool); + + static bool wantsPluginRelativeNPWindowCoordinates(); + + // Plugin + virtual bool initialize(const Parameters&); + virtual void destroy(); + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + virtual PassRefPtr<ShareableBitmap> snapshot(); +#if PLATFORM(MAC) + virtual PlatformLayer* pluginLayer(); +#endif + virtual bool isTransparent(); + virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform); + virtual void visibilityDidChange(); + virtual void frameDidFinishLoading(uint64_t requestID); + virtual void frameDidFail(uint64_t requestID, bool wasCancelled); + virtual void didEvaluateJavaScript(uint64_t requestID, 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, const String& suggestedFileName); + 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, const String& suggestedFileName); + 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 handleContextMenuEvent(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); + + void pluginFocusOrWindowFocusChanged(); + void setComplexTextInputEnabled(bool); +#endif + + virtual void contentsScaleFactorChanged(float); + virtual void privateBrowsingStateChanged(bool); + virtual bool getFormValue(String& formValue); + virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); + virtual WebCore::Scrollbar* horizontalScrollbar(); + virtual WebCore::Scrollbar* verticalScrollbar(); + + bool supportsSnapshotting() const; + + // Convert the given point from plug-in coordinates to root view coordinates. + WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const; + + // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be + // converted (if the transformation matrix isn't invertible). + bool convertFromRootView(const WebCore::IntPoint& pointInRootViewCoordinates, WebCore::IntPoint& pointInPluginCoordinates); + +#if PLUGIN_ARCHITECTURE(WIN) + static BOOL WINAPI hookedTrackPopupMenu(HMENU, UINT uFlags, int x, int y, int nReserved, HWND, const RECT*); + void scheduleWindowedGeometryUpdate(); +#endif + + 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::IntSize m_pluginSize; + + // The clip rect in plug-in coordinates. + WebCore::IntRect m_clipRect; + + // A transform that can be used to convert from root view coordinates to plug-in coordinates. + WebCore::AffineTransform m_pluginToRootViewTransform; + + // FIXME: Get rid of these. + WebCore::IntRect m_frameRectInWindowCoordinates; + + CString m_userAgent; + + bool m_isStarted; + bool m_isWindowed; + bool m_isTransparent; + bool m_inNPPNew; + bool m_loadManually; + RefPtr<NetscapePluginStream> m_manualStream; + Vector<bool, 8> m_popupEnabledStates; + + class Timer { + WTF_MAKE_NONCOPYABLE(Timer); + + public: + typedef void (*TimerFunc)(NPP, uint32_t timerID); + + static PassOwnPtr<Timer> create(NetscapePlugin*, unsigned timerID, unsigned interval, bool repeat, TimerFunc); + ~Timer(); + + void start(); + void stop(); + + private: + Timer(NetscapePlugin*, unsigned timerID, unsigned interval, bool repeat, TimerFunc); + + void timerFired(); + + // This is a weak pointer since Timer objects are destroyed before the NetscapePlugin object itself is destroyed. + NetscapePlugin* m_netscapePlugin; + + unsigned m_timerID; + unsigned m_interval; + bool m_repeat; + TimerFunc m_timerFunc; + + RunLoop::Timer<Timer> m_timer; + }; + typedef HashMap<unsigned, Timer*> TimerMap; + TimerMap m_timers; + unsigned m_nextTimerID; + +#if PLUGIN_ARCHITECTURE(MAC) + NPDrawingModel m_drawingModel; + NPEventModel m_eventModel; + + RetainPtr<PlatformLayer> m_pluginLayer; + bool m_pluginReturnsNonretainedLayer; + + NPCocoaEvent* m_currentMouseEvent; + + bool m_pluginHasFocus; + bool m_windowHasFocus; + + // Whether the plug-in wants to use the legacy Cocoa text input handling that + // existed in WebKit1, or the updated Cocoa text input handling specified on + // https://wiki.mozilla.org/NPAPI:CocoaEventModel#Text_Input + bool m_pluginWantsLegacyCocoaTextInput; + + // Whether complex text input is enabled. + bool m_isComplexTextInputEnabled; + + // Whether the plug-in has handled a keydown event. This is used to determine + // if we can tell the plug-in that we support the updated Cocoa text input specification. + bool m_hasHandledAKeyDownEvent; + + // The number of NPCocoaEventKeyUp events that should be ignored. + unsigned m_ignoreNextKeyUpEventCounter; + + 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 PLUGIN_ARCHITECTURE(WIN) + HWND m_window; + HWND m_contextMenuOwnerWindow; +#elif PLUGIN_ARCHITECTURE(X11) + Pixmap m_drawable; + Display* m_pluginDisplay; + +public: // Need to call it in the NPN_GetValue browser callback. + static Display* x11HostDisplay(); +#endif +}; + +} // namespace WebKit + +#endif // NetscapePlugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp new file mode 100644 index 000000000..b5cf547b4 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 "config.h" +#if PLUGIN_ARCHITECTURE(UNSUPPORTED) + +#include "NetscapePlugin.h" + +using namespace WebCore; + +namespace WebKit { + +bool NetscapePlugin::platformPostInitialize() +{ + return false; +} + +void NetscapePlugin::platformDestroy() +{ +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ +} + +void NetscapePlugin::platformVisibilityDidChange() +{ +} + +void NetscapePlugin::platformPaint(GraphicsContext*, const IntRect&, bool) +{ +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent&) +{ + return false; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) +{ + return false; +} + +void NetscapePlugin::platformSetFocus(bool) +{ +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent&) +{ + return false; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent&) +{ + return false; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +{ + return false; +} + +bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() +{ + return true; +} + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(UNSUPPORTED) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp new file mode 100644 index 000000000..23a83fe6d --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetscapePluginStream.h" + +#include "NetscapePlugin.h" +#include <utility> + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +NetscapePluginStream::NetscapePluginStream(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData) + : m_plugin(plugin) + , m_streamID(streamID) + , m_requestURLString(requestURLString) + , 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& 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 = result.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(m_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 = adoptPtr(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) { + cancel(); + 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) { + ASSERT(reason != NPRES_DONE); + notifyAndDestroyStream(reason); + 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 = nullptr; + 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.utf8().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(m_filePath); + m_filePath = String(); + + // 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_requestURLString.utf8().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 000000000..de26827fc --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h @@ -0,0 +1,113 @@ +/* + * 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, const String& requestURLString, bool sendNotification, void* notificationData) + { + return adoptRef(new NetscapePluginStream(plugin, streamID, requestURLString, 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& result); + + void stop(NPReason); + NPError destroy(NPReason); + +private: + NetscapePluginStream(PassRefPtr<NetscapePlugin>, uint64_t streamID, const String& requestURLString, 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; + + String m_requestURLString; + bool m_sendNotification; + void* m_notificationData; + + NPStream m_npStream; + uint16_t m_transferMode; + int32_t m_offset; + + String 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/PluginProxyGtk.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/PluginProxyGtk.cpp new file mode 100644 index 000000000..996af20ca --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/PluginProxyGtk.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +bool PluginProxy::needsBackingStore() const +{ + notImplemented(); + return true; +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) 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 000000000..7e436958c --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm @@ -0,0 +1,1072 @@ +/* + * 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 "config.h" +#import "NetscapePlugin.h" + +#import "PluginController.h" +#import "WebEvent.h" +#import <Carbon/Carbon.h> +#import <WebCore/GraphicsContext.h> +#import <WebCore/NotImplemented.h> +#import <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; +} + +bool NetscapePlugin::getScreenTransform(NPCoordinateSpace sourceSpace, AffineTransform& transform) +{ + ASSERT(transform.isIdentity()); + + switch (sourceSpace) { + case NPCoordinateSpacePlugin: { + transform.translate(m_windowFrameInScreenCoordinates.x(), m_windowFrameInScreenCoordinates.y()); + transform.translate(m_viewFrameInWindowCoordinates.x(), m_viewFrameInWindowCoordinates.height() + m_viewFrameInWindowCoordinates.y()); + transform.flipY(); + transform *= m_pluginToRootViewTransform; + return true; + } + + case NPCoordinateSpaceWindow: { + transform.translate(m_windowFrameInScreenCoordinates.x(), m_windowFrameInScreenCoordinates.y()); + return true; + } + + case NPCoordinateSpaceFlippedWindow: { + transform.translate(m_windowFrameInScreenCoordinates.x(), m_windowFrameInScreenCoordinates.height() + m_windowFrameInScreenCoordinates.y()); + transform.flipY(); + return true; + } + + case NPCoordinateSpaceScreen: { + // Nothing to do. + return true; + } + + case NPCoordinateSpaceFlippedScreen: { + double screenHeight = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height; + transform.translate(0, screenHeight); + transform.flipY(); + return true; + } + + default: + return false; + } +} + +NPBool NetscapePlugin::convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace) +{ + AffineTransform sourceTransform; + if (!getScreenTransform(sourceSpace, sourceTransform)) + return false; + + AffineTransform destTransform; + if (!getScreenTransform(destSpace, destTransform)) + return false; + + if (!destTransform.isInvertible()) + return false; + + AffineTransform transform = destTransform.inverse() * sourceTransform; + + FloatPoint destinationPoint = transform.mapPoint(FloatPoint(sourceX, sourceY)); + + destX = destinationPoint.x(); + destY = destinationPoint.y(); + return true; +} + + +NPError NetscapePlugin::popUpContextMenu(NPMenu* npMenu) +{ + if (!m_currentMouseEvent) + return NPERR_GENERIC_ERROR; + + double screenX, screenY; + if (!convertPoint(m_currentMouseEvent->data.mouse.pluginX, m_currentMouseEvent->data.mouse.pluginY, NPCoordinateSpacePlugin, screenX, screenY, NPCoordinateSpaceScreen)) + ASSERT_NOT_REACHED(); + + WKPopupContextMenu(reinterpret_cast<NSMenu *>(npMenu), NSMakePoint(screenX, screenY)); + return NPERR_NO_ERROR; +} + +mach_port_t NetscapePlugin::compositingRenderServerPort() +{ + return controller()->compositingRenderServerPort(); +} + +#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 && + !m_pluginModule->pluginQuirks().contains(PluginQuirks::AllowHalfBakedQuickDrawSupport)) + 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); + + // The original Core Animation drawing model required that plug-ins pass a retained layer + // to the browser, which the browser would then adopt. However, the final spec changed this + // (See https://wiki.mozilla.org/NPAPI:CoreAnimationDrawingModel for more information) + // after a version of WebKit1 with the original implementation had shipped, but that now means + // that any plug-ins that expect the WebKit1 behavior would leak the CALayer. + // For plug-ins that we know return retained layers, we have the ReturnsRetainedCoreAnimationLayer + // plug-in quirk. Plug-ins can also check for whether the browser expects a non-retained layer to + // be returned by using NPN_GetValue and pass the WKNVExpectsNonretainedLayer parameter. + // https://bugs.webkit.org/show_bug.cgi?id=58282 describes the bug where WebKit expects retained layers. + if (m_pluginReturnsNonretainedLayer) + m_pluginLayer = reinterpret_cast<CALayer *>(value); + else + m_pluginLayer.adoptNS(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&) +{ + // NPN_InvalidateRect is just a no-op in the Core Animation drawing model. + if (m_drawingModel == NPDrawingModelCoreAnimation) + return true; + + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + switch (m_eventModel) { + case NPEventModelCocoa: + // Nothing to do + break; +#ifndef NP_NO_CARBON + case NPEventModelCarbon: + updateFakeWindowBounds(); + break; +#endif + default: + ASSERT_NOT_REACHED(); + } +} + +void NetscapePlugin::platformVisibilityDidChange() +{ + // FIXME: Implement this. <http://webkit.org/b/44368>. + notImplemented(); +} + +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); +} + +void NetscapePlugin::updateFakeWindowBounds() +{ + double screenX, screenY; + bool didConvert = convertPoint(0, 0, NPCoordinateSpacePlugin, screenX, screenY, NPCoordinateSpaceFlippedScreen); + ASSERT_UNUSED(didConvert, didConvert); + + Rect bounds; + bounds.top = screenY; + bounds.left = screenX; + bounds.bottom = screenY + m_pluginSize.height(); + bounds.right = screenX + m_pluginSize.width(); + + ::SetWindowBounds(windowRef(), kWindowStructureRgn, &bounds); +} + +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, bool isSnapshot) +{ + CGContextRef platformContext = context->platformContext(); + + switch (m_eventModel) { + case NPEventModelCocoa: { + // Don't send draw events when we're using the Core Animation drawing model. + if (!isSnapshot && m_drawingModel == NPDrawingModelCoreAnimation) + return; + + NPCocoaEvent event = initializeEvent(NPCocoaEventDrawRect); + + event.data.draw.context = platformContext; + event.data.draw.x = dirtyRect.x(); + event.data.draw.y = dirtyRect.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& eventPositionInPluginCoordinates) +{ + event.data.mouse.modifierFlags = modifierFlags(mouseEvent); + event.data.mouse.pluginX = eventPositionInPluginCoordinates.x(); + event.data.mouse.pluginY = eventPositionInPluginCoordinates.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& eventPositionInPluginCoordinates) +{ + 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, eventPositionInPluginCoordinates); + return event; +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& mouseEvent) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + IntPoint eventPositionInPluginCoordinates; + if (!convertFromRootView(mouseEvent.position(), eventPositionInPluginCoordinates)) + return true; + + NPCocoaEvent event = initializeMouseEvent(mouseEvent, eventPositionInPluginCoordinates); + + NPCocoaEvent* previousMouseEvent = m_currentMouseEvent; + m_currentMouseEvent = &event; + + // Protect against NPP_HandleEvent causing the plug-in to be destroyed, since we + // access m_currentMouseEvent afterwards. + RefPtr<NetscapePlugin> protect(this); + + NPP_HandleEvent(&event); + + m_currentMouseEvent = previousMouseEvent; + + // Some plug-ins return false even if the mouse event has been handled. + // This leads to bugs such as <rdar://problem/9167611>. Work around this + // by always returning true. + return true; + } + +#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(); + + NPP_HandleEvent(&event); + + // Some plug-ins return false even if the mouse event has been handled. + // This leads to bugs such as <rdar://problem/9167611>. Work around this + // by always returning true. + return true; + } +#endif + + default: + ASSERT_NOT_REACHED(); + } + + return false; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& wheelEvent) +{ + switch (m_eventModel) { + case NPEventModelCocoa: { + IntPoint eventPositionInPluginCoordinates; + if (!convertFromRootView(wheelEvent.position(), eventPositionInPluginCoordinates)) + return true; + + NPCocoaEvent event = initializeEvent(NPCocoaEventScrollWheel); + + event.data.mouse.modifierFlags = modifierFlags(wheelEvent); + event.data.mouse.pluginX = eventPositionInPluginCoordinates.x(); + event.data.mouse.pluginY = eventPositionInPluginCoordinates.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, IntPoint()); + 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, IntPoint()); + 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.capsLockKey()) + modifierFlags |= NSAlphaShiftKeyMask; + if (keyboardEvent.shiftKey()) + modifierFlags |= NSShiftKeyMask; + if (keyboardEvent.controlKey()) + modifierFlags |= NSControlKeyMask; + if (keyboardEvent.altKey()) + modifierFlags |= NSAlternateKeyMask; + if (keyboardEvent.metaKey()) + modifierFlags |= NSCommandKeyMask; + + return modifierFlags; +} + +static bool isFlagsChangedEvent(const WebKeyboardEvent& keyboardEvent) +{ + switch (keyboardEvent.nativeVirtualKeyCode()) { + case 54: // Right Command + case 55: // Left Command + + case 57: // Capslock + + case 56: // Left Shift + case 60: // Right Shift + + case 58: // Left Alt + case 61: // Right Alt + + case 59: // Left Ctrl + case 62: // Right Ctrl + return true; + } + + return false; +} + +static NPCocoaEvent initializeKeyboardEvent(const WebKeyboardEvent& keyboardEvent) +{ + NPCocoaEventType eventType; + + if (isFlagsChangedEvent(keyboardEvent)) + eventType = NPCocoaEventFlagsChanged; + else { + 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: { + if (keyboardEvent.type() == WebEvent::KeyDown) { + m_hasHandledAKeyDownEvent = true; + + if (!m_pluginWantsLegacyCocoaTextInput && m_isComplexTextInputEnabled && !keyboardEvent.isAutoRepeat()) { + // When complex text is enabled in the new model, the plug-in should never + // receive any key down or key up events until the composition is complete. + m_ignoreNextKeyUpEventCounter++; + return true; + } + } else if (keyboardEvent.type() == WebEvent::KeyUp && m_ignoreNextKeyUpEventCounter) { + m_ignoreNextKeyUpEventCounter--; + return true; + } + + NPCocoaEvent event = initializeKeyboardEvent(keyboardEvent); + int16_t returnValue = NPP_HandleEvent(&event); + handled = returnValue; + + if (!m_pluginWantsLegacyCocoaTextInput) { + if (event.type == NPCocoaEventKeyDown && returnValue == kNPEventStartIME) { + if (!keyboardEvent.isAutoRepeat()) + m_ignoreNextKeyUpEventCounter++; + setComplexTextInputEnabled(true); + } + } + + 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. + // However, for command-A (the shortcurt for 'Select All' we will always return true, since we don't + // want the entire page to be selected if the focus is in a plug-in text field (see <rdar://problem/9309903>). + if (keyboardEvent.metaKey()) { + if (keyboardEvent.text() == "a") + return true; + + return false; + } + + return handled; +} + +void NetscapePlugin::platformSetFocus(bool hasFocus) +{ + m_pluginHasFocus = hasFocus; + pluginFocusOrWindowFocusChanged(); + + 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(); + } +} + +bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() +{ + return true; +} + +void NetscapePlugin::windowFocusChanged(bool hasFocus) +{ + m_windowHasFocus = hasFocus; + pluginFocusOrWindowFocusChanged(); + + 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(); + } +} + +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: + updateFakeWindowBounds(); + break; +#endif + + default: + ASSERT_NOT_REACHED(); + } +} + +void NetscapePlugin::windowVisibilityChanged(bool) +{ + // FIXME: Implement. +} + +uint64_t NetscapePlugin::pluginComplexTextInputIdentifier() const +{ + // Just return a dummy value; this is only called for in-process plug-ins, which we don't support on Mac. + return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)); +} + + +#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) +{ + if (!m_pluginWantsLegacyCocoaTextInput) { + // In the updated Cocoa text input spec, text input is disabled when the text input string has been sent + // by the UI process. Since the UI process has also updated its state, we can just reset the variable here + // instead of calling setComplexTextInputEnabled. + m_isComplexTextInputEnabled = false; + + // The UI process can also disable text input by sending an empty input string. In this case, we don't want + // to send it to the plug-in. + if (textInput.isNull()) + return; + } + + 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(); + } +} + +void NetscapePlugin::pluginFocusOrWindowFocusChanged() +{ + bool pluginHasFocusAndWindowHasFocus = m_pluginHasFocus && m_windowHasFocus; + + controller()->pluginFocusOrWindowFocusChanged(pluginHasFocusAndWindowHasFocus); + + // In the updated Cocoa text input spec, the plug-in will enable complex text input + // by returning kNPEventStartIME from it's NPCocoaEventKeyDown handler. + if (!m_pluginWantsLegacyCocoaTextInput) + return; + + // In the old model, if the plug-in is focused, enable complex text input. + setComplexTextInputEnabled(pluginHasFocusAndWindowHasFocus); +} + +void NetscapePlugin::setComplexTextInputEnabled(bool complexTextInputEnabled) +{ + if (m_isComplexTextInputEnabled == complexTextInputEnabled) + return; + + m_isComplexTextInputEnabled = complexTextInputEnabled; + + PluginComplexTextInputState complexTextInputState = PluginComplexTextInputDisabled; + if (m_isComplexTextInputEnabled) + complexTextInputState = m_pluginWantsLegacyCocoaTextInput ? PluginComplexTextInputEnabledLegacy : PluginComplexTextInputEnabled; + + controller()->setComplexTextInputState(complexTextInputState); +} + +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 000000000..49385d9d9 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm @@ -0,0 +1,70 @@ +/* + * 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 "config.h" +#import "PluginProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#import "PluginController.h" +#import <WebKitSystemInterface.h> + +namespace WebKit { + +PlatformLayer* PluginProxy::pluginLayer() +{ + if (!m_pluginLayer && m_remoteLayerClientID) { + CALayer *renderLayer = WKMakeRenderLayer(m_remoteLayerClientID); + + // Create a layer with flipped geometry and add the real plug-in layer as a sublayer + // so the coordinate system will match the event coordinate system. + m_pluginLayer.adoptNS([[CALayer alloc] init]); + [m_pluginLayer.get() setGeometryFlipped:YES]; + + [renderLayer setAutoresizingMask:kCALayerWidthSizable | kCALayerHeightSizable]; + [m_pluginLayer.get() addSublayer:renderLayer]; + } + + return m_pluginLayer.get(); +} + +bool PluginProxy::needsBackingStore() const +{ + return !m_remoteLayerClientID; +} + +void PluginProxy::pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) +{ + controller()->pluginFocusOrWindowFocusChanged(pluginHasFocusAndWindowHasFocus); +} + +void PluginProxy::setComplexTextInputState(uint64_t complexTextInputState) +{ + controller()->setComplexTextInputState(static_cast<PluginComplexTextInputState>(complexTextInputState)); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/qt/PluginProxyQt.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/PluginProxyQt.cpp new file mode 100644 index 000000000..7af178429 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/PluginProxyQt.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Nokia Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +bool PluginProxy::needsBackingStore() const +{ + notImplemented(); + return true; +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) 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 000000000..b14f31d25 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "NetscapePlugin.h" + +#include "PluginController.h" +#include "WebEvent.h" +#include "WindowGeometry.h" +#include <WebCore/DefWndProcWindowClass.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/LocalWindowsContext.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/WebCoreInstanceHandle.h> + +using namespace WebCore; + +namespace WebKit { + +static NetscapePlugin* currentPlugin; + +class CurrentPluginSetter { + WTF_MAKE_NONCOPYABLE(CurrentPluginSetter); +public: + explicit CurrentPluginSetter(NetscapePlugin* plugin) + : m_plugin(plugin) + , m_formerCurrentPlugin(currentPlugin) + { + currentPlugin = m_plugin; + } + + ~CurrentPluginSetter() + { + ASSERT(currentPlugin == m_plugin); + currentPlugin = m_formerCurrentPlugin; + } + +private: + NetscapePlugin* m_plugin; + NetscapePlugin* m_formerCurrentPlugin; +}; + +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 = instanceHandle(); + windowClass.hCursor = ::LoadCursorW(0, IDC_ARROW); + windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1); + windowClass.lpszClassName = windowClassName; + + ::RegisterClassW(&windowClass); +} + +HWND NetscapePlugin::containingWindow() +{ + return controller()->nativeParentWindow(); +} + +bool NetscapePlugin::platformPostInitialize() +{ + if (!m_isWindowed) { + m_window = 0; + + // Windowless plugins need a little help showing context menus since our containingWindow() + // is in a different process. See <http://webkit.org/b/51063>. + m_pluginModule->module()->installIATHook("user32.dll", "TrackPopupMenu", hookedTrackPopupMenu); + m_contextMenuOwnerWindow = ::CreateWindowExW(0, defWndProcWindowClassName(), 0, WS_CHILD, 0, 0, 0, 0, containingWindow(), 0, instanceHandle(), 0); + + return true; + } + + registerPluginView(); + + // Start out with the window hidden. The UI process will take care of showing it once it's correctly positioned the window. + m_window = ::CreateWindowExW(0, windowClassName, 0, WS_CHILD, 0, 0, 0, 0, containingWindow(), 0, instanceHandle(), 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_contextMenuOwnerWindow); + ::DestroyWindow(m_contextMenuOwnerWindow); + 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; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + if (!m_isWindowed) + return; + + scheduleWindowedGeometryUpdate(); +} + +void NetscapePlugin::platformVisibilityDidChange() +{ + if (!m_isWindowed) + return; + + scheduleWindowedGeometryUpdate(); +} + +void NetscapePlugin::scheduleWindowedGeometryUpdate() +{ + // We only update the size here and let the UI process update our position and clip rect so + // that we can keep our position in sync when scrolling, etc. See <http://webkit.org/b/60210>. + ::SetWindowPos(m_window, 0, 0, 0, m_pluginSize.width(), m_pluginSize.height(), SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); + + WindowGeometry geometry; + geometry.window = m_window; + geometry.visible = controller()->isPluginVisible(); + geometry.frame = IntRect(convertToRootView(IntPoint()), m_pluginSize); + geometry.clipRect = m_clipRect; + + controller()->scheduleWindowedPluginGeometryUpdate(geometry); +} + +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool) +{ + CurrentPluginSetter setCurrentPlugin(this); + + // 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; + } + + controller()->willSendEventToPlugin(); + + LocalWindowsContext windowsContext(context, dirtyRect, m_isTransparent); + + m_npWindow.type = NPWindowTypeDrawable; + m_npWindow.window = windowsContext.hdc(); + + WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 }; + + IntPoint pluginLocationInRootViewCoordinates = convertToRootView(IntPoint()); + + windowpos.x = pluginLocationInRootViewCoordinates.x(); + windowpos.y = pluginLocationInRootViewCoordinates.y(); + windowpos.cx = m_pluginSize.width(); + windowpos.cy = m_pluginSize.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) +{ + CurrentPluginSetter setCurrentPlugin(this); + + if (m_isWindowed) + return false; + + controller()->willSendEventToPlugin(); + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) +{ + CurrentPluginSetter setCurrentPlugin(this); + + notImplemented(); + return false; +} + +void NetscapePlugin::platformSetFocus(bool hasFocus) +{ + CurrentPluginSetter setCurrentPlugin(this); + + if (m_isWindowed) + return; + + controller()->willSendEventToPlugin(); + + NPEvent npEvent; + npEvent.event = hasFocus ? WM_SETFOCUS : WM_KILLFOCUS; + npEvent.wParam = 0; + npEvent.lParam = 0; + + NPP_HandleEvent(&npEvent); +} + +bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() +{ + return false; +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + CurrentPluginSetter setCurrentPlugin(this); + + if (m_isWindowed) + return false; + + controller()->willSendEventToPlugin(); + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + CurrentPluginSetter setCurrentPlugin(this); + + if (m_isWindowed) + return false; + + controller()->willSendEventToPlugin(); + + NPEvent npEvent = toNP(event); + NPP_HandleEvent(&npEvent); + return true; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent&) +{ + CurrentPluginSetter setCurrentPlugin(this); + + notImplemented(); + return false; +} + +BOOL NetscapePlugin::hookedTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, const RECT* prcRect) +{ + // ::TrackPopupMenu fails when it is passed a window that is owned by another thread. If this + // happens, we substitute a dummy window that is owned by this thread. + + if (::GetWindowThreadProcessId(hWnd, 0) == ::GetCurrentThreadId()) + return ::TrackPopupMenu(hMenu, uFlags, x, y, nReserved, hWnd, prcRect); + + HWND originalFocusWindow = 0; + + ASSERT(currentPlugin); + if (currentPlugin) { + ASSERT(!currentPlugin->m_isWindowed); + ASSERT(currentPlugin->m_contextMenuOwnerWindow); + ASSERT(::GetWindowThreadProcessId(currentPlugin->m_contextMenuOwnerWindow, 0) == ::GetCurrentThreadId()); + hWnd = currentPlugin->m_contextMenuOwnerWindow; + + // If we don't focus the dummy window, the user will be able to scroll the page while the + // context menu is up, e.g. + originalFocusWindow = ::SetFocus(hWnd); + } + + BOOL result = ::TrackPopupMenu(hMenu, uFlags, x, y, nReserved, hWnd, prcRect); + + if (originalFocusWindow) + ::SetFocus(originalFocusWindow); + + return result; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp new file mode 100644 index 000000000..a1c2a31a2 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp @@ -0,0 +1,547 @@ +/* + * 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 "config.h" +#if PLUGIN_ARCHITECTURE(X11) + +#include "NetscapePlugin.h" + +#include "WebEvent.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/NotImplemented.h> + +#if PLATFORM(QT) +#include <WebCore/QtX11ImageConversion.h> +#elif PLATFORM(GTK) +#include "PlatformContextCairo.h" +#include "RefPtrCairo.h" +#include <cairo/cairo-xlib.h> +#include <gdk/gdkx.h> +#include <WebCore/GtkVersioning.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +static Display* getPluginDisplay() +{ +#if PLATFORM(QT) + // At the moment, we only support gdk based plugins (like Flash) that use a different X connection. + // The code below has the same effect as this one: + // Display *gdkDisplay = gdk_x11_display_get_xdisplay(gdk_display_get_default()); + + QLibrary library(QLatin1String("libgdk-x11-2.0"), 0); + if (!library.load()) + return 0; + + typedef void *(*gdk_init_check_ptr)(void*, void*); + gdk_init_check_ptr gdk_init_check = (gdk_init_check_ptr)library.resolve("gdk_init_check"); + if (!gdk_init_check) + return 0; + + typedef void *(*gdk_display_get_default_ptr)(); + gdk_display_get_default_ptr gdk_display_get_default = (gdk_display_get_default_ptr)library.resolve("gdk_display_get_default"); + if (!gdk_display_get_default) + return 0; + + typedef void *(*gdk_x11_display_get_xdisplay_ptr)(void *); + gdk_x11_display_get_xdisplay_ptr gdk_x11_display_get_xdisplay = (gdk_x11_display_get_xdisplay_ptr)library.resolve("gdk_x11_display_get_xdisplay"); + if (!gdk_x11_display_get_xdisplay) + return 0; + + gdk_init_check(0, 0); + return (Display*)gdk_x11_display_get_xdisplay(gdk_display_get_default()); +#elif PLATFORM(GTK) + // Since we're a gdk/gtk app, we'll (probably?) have the same X connection as any gdk-based + // plugins, so we can return that. We might want to add other implementations here later. + return GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); +#else + return 0; +#endif +} + +static inline int x11Screen() +{ +#if PLATFORM(QT) + return XDefaultScreen(NetscapePlugin::x11HostDisplay()); +#elif PLATFORM(GTK) + return gdk_screen_get_number(gdk_screen_get_default()); +#else + return 0; +#endif +} + +static inline int displayDepth() +{ +#if PLATFORM(QT) + return XDefaultDepth(NetscapePlugin::x11HostDisplay(), x11Screen()); +#elif PLATFORM(GTK) + return gdk_visual_get_depth(gdk_screen_get_system_visual(gdk_screen_get_default())); +#else + return 0; +#endif +} + +static inline unsigned long rootWindowID() +{ +#if PLATFORM(QT) + return XDefaultRootWindow(NetscapePlugin::x11HostDisplay()); +#elif PLATFORM(GTK) + return GDK_ROOT_WINDOW(); +#else + return 0; +#endif +} + +#if PLATFORM(GTK) +static bool moduleMixesGtkSymbols(Module* module) +{ +#ifdef GTK_API_VERSION_2 + return module->functionPointer<gpointer>("gtk_application_get_type"); +#else + return module->functionPointer<gpointer>("gtk_object_get_type"); +#endif +} +#endif + +Display* NetscapePlugin::x11HostDisplay() +{ +#if PLATFORM(QT) + static Display* dedicatedDisplay = 0; + if (!dedicatedDisplay) + dedicatedDisplay = XOpenDisplay(0); + + ASSERT(dedicatedDisplay); + return dedicatedDisplay; +#elif PLATFORM(GTK) + return GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); +#else + return 0; +#endif +} + +bool NetscapePlugin::platformPostInitialize() +{ +#if PLATFORM(GTK) + if (moduleMixesGtkSymbols(m_pluginModule->module())) + return false; +#endif + + if (m_isWindowed) + return false; + + if (!(m_pluginDisplay = getPluginDisplay())) + return false; + + NPSetWindowCallbackStruct* callbackStruct = new NPSetWindowCallbackStruct; + callbackStruct->type = 0; + Display* display = x11HostDisplay(); + int depth = displayDepth(); +#if PLATFORM(QT) + ASSERT(depth == 16 || depth == 24 || depth == 32); +#endif + callbackStruct->display = display; + callbackStruct->depth = depth; + + XVisualInfo visualTemplate; + visualTemplate.screen = x11Screen(); + visualTemplate.depth = depth; + visualTemplate.c_class = TrueColor; + int numMatching; + XVisualInfo* visualInfo = XGetVisualInfo(display, VisualScreenMask | VisualDepthMask | VisualClassMask, + &visualTemplate, &numMatching); + ASSERT(visualInfo); + Visual* visual = visualInfo[0].visual; + ASSERT(visual); + XFree(visualInfo); + + callbackStruct->visual = visual; + callbackStruct->colormap = XCreateColormap(display, rootWindowID(), visual, AllocNone); + + m_npWindow.type = NPWindowTypeDrawable; + m_npWindow.window = 0; + m_npWindow.ws_info = callbackStruct; + + callSetWindow(); + + return true; +} + +void NetscapePlugin::platformDestroy() +{ + NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); + Display* hostDisplay = x11HostDisplay(); + XFreeColormap(hostDisplay, callbackStruct->colormap); + delete callbackStruct; + + if (m_drawable) { + XFreePixmap(hostDisplay, m_drawable); + m_drawable = 0; + } +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + if (m_isWindowed) { + notImplemented(); + return; + } + + Display* display = x11HostDisplay(); + if (m_drawable) + XFreePixmap(display, m_drawable); + + if (m_pluginSize.isEmpty()) { + m_drawable = 0; + return; + } + + m_drawable = XCreatePixmap(display, rootWindowID(), m_pluginSize.width(), m_pluginSize.height(), displayDepth()); + + XSync(display, false); // Make sure that the server knows about the Drawable. +} + +void NetscapePlugin::platformVisibilityDidChange() +{ + notImplemented(); +} + +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool /*isSnapshot*/) +{ + if (m_isWindowed) { + notImplemented(); + return; + } + + if (!m_isStarted) { + // FIXME: we should paint a missing plugin icon. + return; + } + + if (context->paintingDisabled() || !m_drawable) + return; + + XEvent xevent; + memset(&xevent, 0, sizeof(XEvent)); + XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; + exposeEvent.type = GraphicsExpose; + exposeEvent.display = x11HostDisplay(); + exposeEvent.drawable = m_drawable; + + IntRect exposedRect(dirtyRect); + exposeEvent.x = exposedRect.x(); + exposeEvent.y = exposedRect.y(); + + // Note: in transparent mode Flash thinks width is the right and height is the bottom. + // We should take it into account if we want to support transparency. + exposeEvent.width = exposedRect.width(); + exposeEvent.height = exposedRect.height(); + + NPP_HandleEvent(&xevent); + + if (m_pluginDisplay != x11HostDisplay()) + XSync(m_pluginDisplay, false); + +#if PLATFORM(QT) + XImage* xImage = XGetImage(NetscapePlugin::x11HostDisplay(), m_drawable, exposedRect.x(), exposedRect.y(), + exposedRect.width(), exposedRect.height(), ULONG_MAX, ZPixmap); + QPainter* painter = context->platformContext(); + painter->drawImage(QPoint(exposedRect.x(), exposedRect.y()), qimageFromXImage(xImage), exposedRect); + + XDestroyImage(xImage); +#elif PLATFORM(GTK) + RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(m_pluginDisplay, + m_drawable, + static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info)->visual, + m_pluginSize.width(), + m_pluginSize.height())); + cairo_t* cr = context->platformContext()->cr(); + cairo_save(cr); + + cairo_set_source_surface(cr, drawableSurface.get(), 0, 0); + + cairo_rectangle(cr, exposedRect.x(), exposedRect.y(), exposedRect.width(), exposedRect.height()); + cairo_clip(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_paint(cr); + + cairo_restore(cr); +#else + notImplemented(); +#endif +} + +static inline void initializeXEvent(XEvent& event) +{ + memset(&event, 0, sizeof(XEvent)); + event.xany.serial = 0; + event.xany.send_event = false; + event.xany.display = NetscapePlugin::x11HostDisplay(); + event.xany.window = 0; +} + +static inline uint64_t xTimeStamp(double timestampInSeconds) +{ + return timestampInSeconds * 1000; +} + +static inline unsigned xKeyModifiers(const WebEvent& event) +{ + unsigned xModifiers = 0; + if (event.controlKey()) + xModifiers |= ControlMask; + if (event.shiftKey()) + xModifiers |= ShiftMask; + if (event.altKey()) + xModifiers |= Mod1Mask; + if (event.metaKey()) + xModifiers |= Mod4Mask; + + return xModifiers; +} + +template <typename XEventType, typename WebEventType> +static inline void setCommonMouseEventFields(XEventType& xEvent, const WebEventType& webEvent, const WebCore::IntPoint& pluginLocation) +{ + xEvent.root = rootWindowID(); + xEvent.subwindow = 0; + xEvent.time = xTimeStamp(webEvent.timestamp()); + xEvent.x = webEvent.position().x() - pluginLocation.x(); + xEvent.y = webEvent.position().y() - pluginLocation.y(); + xEvent.x_root = webEvent.globalPosition().x(); + xEvent.y_root = webEvent.globalPosition().y(); + xEvent.state = xKeyModifiers(webEvent); + xEvent.same_screen = true; +} + +static inline void setXMotionEventFields(XEvent& xEvent, const WebMouseEvent& webEvent, const WebCore::IntPoint& pluginLocation) +{ + XMotionEvent& xMotion = xEvent.xmotion; + setCommonMouseEventFields(xMotion, webEvent, pluginLocation); + xMotion.type = MotionNotify; +} + +static inline void setXButtonEventFields(XEvent& xEvent, const WebMouseEvent& webEvent, const WebCore::IntPoint& pluginLocation) +{ + XButtonEvent& xButton = xEvent.xbutton; + setCommonMouseEventFields(xButton, webEvent, pluginLocation); + + xButton.type = (webEvent.type() == WebEvent::MouseDown) ? ButtonPress : ButtonRelease; + switch (webEvent.button()) { + case WebMouseEvent::LeftButton: + xButton.button = Button1; + break; + case WebMouseEvent::MiddleButton: + xButton.button = Button2; + break; + case WebMouseEvent::RightButton: + xButton.button = Button3; + break; + default: + ASSERT_NOT_REACHED(); + break; + } +} + +static inline void setXButtonEventFieldsByWebWheelEvent(XEvent& xEvent, const WebWheelEvent& webEvent, const WebCore::IntPoint& pluginLocation) +{ + XButtonEvent& xButton = xEvent.xbutton; + setCommonMouseEventFields(xButton, webEvent, pluginLocation); + + xButton.type = ButtonPress; + FloatSize ticks = webEvent.wheelTicks(); + if (ticks.height()) { + if (ticks.height() > 0) + xButton.button = 4; // up + else + xButton.button = 5; // down + } else { + if (ticks.width() > 0) + xButton.button = 6; // left + else + xButton.button = 7; // right + } +} + +static inline void setXCrossingEventFields(XEvent& xEvent, const WebMouseEvent& webEvent, const WebCore::IntPoint& pluginLocation, int type) +{ + XCrossingEvent& xCrossing = xEvent.xcrossing; + setCommonMouseEventFields(xCrossing, webEvent, pluginLocation); + + xCrossing.type = type; + xCrossing.mode = NotifyNormal; + xCrossing.detail = NotifyDetailNone; + xCrossing.focus = false; +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + if ((event.type() == WebEvent::MouseDown || event.type() == WebEvent::MouseUp) + && event.button() == WebMouseEvent::RightButton + && quirks().contains(PluginQuirks::IgnoreRightClickInWindowlessMode)) + return false; + + XEvent xEvent; + initializeXEvent(xEvent); + + switch (event.type()) { + case WebEvent::MouseDown: + case WebEvent::MouseUp: + setXButtonEventFields(xEvent, event, convertToRootView(IntPoint())); + break; + case WebEvent::MouseMove: + setXMotionEventFields(xEvent, event, convertToRootView(IntPoint())); + break; + case WebEvent::NoType: + case WebEvent::Wheel: + case WebEvent::KeyDown: + case WebEvent::KeyUp: + case WebEvent::RawKeyDown: + case WebEvent::Char: +#if ENABLE(GESTURE_EVENTS) + case WebEvent::GestureScrollBegin: + case WebEvent::GestureScrollEnd: +#endif +#if ENABLE(TOUCH_EVENTS) + case WebEvent::TouchStart: + case WebEvent::TouchMove: + case WebEvent::TouchEnd: + case WebEvent::TouchCancel: +#endif + return false; + } + + return !NPP_HandleEvent(&xEvent); +} + +// We undefine these constants in npruntime_internal.h to avoid collision +// with WebKit and platform headers. Values are defined in X.h. +const int kKeyPressType = 2; +const int kKeyReleaseType = 3; +const int kFocusInType = 9; +const int kFocusOutType = 10; + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& event) +{ + if (m_isWindowed) + return false; + + XEvent xEvent; + initializeXEvent(xEvent); + setXButtonEventFieldsByWebWheelEvent(xEvent, event, convertToRootView(IntPoint())); + + return !NPP_HandleEvent(&xEvent); +} + +void NetscapePlugin::platformSetFocus(bool focusIn) +{ + if (m_isWindowed) + return; + + XEvent xEvent; + initializeXEvent(xEvent); + XFocusChangeEvent& focusEvent = xEvent.xfocus; + focusEvent.type = focusIn ? kFocusInType : kFocusOutType; + focusEvent.mode = NotifyNormal; + focusEvent.detail = NotifyDetailNone; + + NPP_HandleEvent(&xEvent); +} + +bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() +{ + return true; +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + XEvent xEvent; + initializeXEvent(xEvent); + setXCrossingEventFields(xEvent, event, convertToRootView(IntPoint()), EnterNotify); + + return !NPP_HandleEvent(&xEvent); +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + if (m_isWindowed) + return false; + + XEvent xEvent; + initializeXEvent(xEvent); + setXCrossingEventFields(xEvent, event, convertToRootView(IntPoint()), LeaveNotify); + + return !NPP_HandleEvent(&xEvent); +} + +static inline void setXKeyEventFields(XEvent& xEvent, const WebKeyboardEvent& webEvent) +{ + xEvent.xany.type = (webEvent.type() == WebEvent::KeyDown) ? kKeyPressType : kKeyReleaseType; + XKeyEvent& xKey = xEvent.xkey; + xKey.root = rootWindowID(); + xKey.subwindow = 0; + xKey.time = xTimeStamp(webEvent.timestamp()); + xKey.state = xKeyModifiers(webEvent); + xKey.keycode = webEvent.nativeVirtualKeyCode(); + + xKey.same_screen = true; + + // Key events propagated to the plugin does not need to have position. + // source: https://developer.mozilla.org/en/NPEvent + xKey.x = 0; + xKey.y = 0; + xKey.x_root = 0; + xKey.y_root = 0; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +{ + // We don't generate other types of keyboard events via WebEventFactory. + ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp); + + XEvent xEvent; + initializeXEvent(xEvent); + setXKeyEventFields(xEvent, event); + + return !NPP_HandleEvent(&xEvent); +} + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.cpp b/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.cpp new file mode 100644 index 000000000..13f97d96f --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.cpp @@ -0,0 +1,876 @@ +/* + * Copyright (C) 2009, 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 "config.h" +#include "BuiltInPDFView.h" + +#include "PluginView.h" +#include "ShareableBitmap.h" +#include "WebEvent.h" +#include "WebEventConversion.h" +#include <JavaScriptCore/JSContextRef.h> +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSStringRef.h> +#include <JavaScriptCore/JSStringRefCF.h> +#include <WebCore/ArchiveResource.h> +#include <WebCore/Chrome.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/HTTPHeaderMap.h> +#include <WebCore/LocalizedStrings.h> +#include <WebCore/Page.h> +#include <WebCore/PluginData.h> +#include <WebCore/RenderBoxModelObject.h> +#include <WebCore/ScrollAnimator.h> +#include <WebCore/ScrollbarTheme.h> + +using namespace WebCore; +using namespace std; + +static void appendValuesInPDFNameSubtreeToVector(CGPDFDictionaryRef subtree, Vector<CGPDFObjectRef>& values) +{ + CGPDFArrayRef names; + if (CGPDFDictionaryGetArray(subtree, "Names", &names)) { + size_t nameCount = CGPDFArrayGetCount(names) / 2; + for (size_t i = 0; i < nameCount; ++i) { + CGPDFObjectRef object; + CGPDFArrayGetObject(names, 2 * i + 1, &object); + values.append(object); + } + return; + } + + CGPDFArrayRef kids; + if (!CGPDFDictionaryGetArray(subtree, "Kids", &kids)) + return; + + size_t kidCount = CGPDFArrayGetCount(kids); + for (size_t i = 0; i < kidCount; ++i) { + CGPDFDictionaryRef kid; + if (!CGPDFArrayGetDictionary(kids, i, &kid)) + continue; + appendValuesInPDFNameSubtreeToVector(kid, values); + } +} + +static void getAllValuesInPDFNameTree(CGPDFDictionaryRef tree, Vector<CGPDFObjectRef>& allValues) +{ + appendValuesInPDFNameSubtreeToVector(tree, allValues); +} + +static void getAllScriptsInPDFDocument(CGPDFDocumentRef pdfDocument, Vector<RetainPtr<CFStringRef> >& scripts) +{ + if (!pdfDocument) + return; + + CGPDFDictionaryRef pdfCatalog = CGPDFDocumentGetCatalog(pdfDocument); + if (!pdfCatalog) + return; + + // Get the dictionary of all document-level name trees. + CGPDFDictionaryRef namesDictionary; + if (!CGPDFDictionaryGetDictionary(pdfCatalog, "Names", &namesDictionary)) + return; + + // Get the document-level "JavaScript" name tree. + CGPDFDictionaryRef javaScriptNameTree; + if (!CGPDFDictionaryGetDictionary(namesDictionary, "JavaScript", &javaScriptNameTree)) + return; + + // The names are arbitrary. We are only interested in the values. + Vector<CGPDFObjectRef> objects; + getAllValuesInPDFNameTree(javaScriptNameTree, objects); + size_t objectCount = objects.size(); + + for (size_t i = 0; i < objectCount; ++i) { + CGPDFDictionaryRef javaScriptAction; + if (!CGPDFObjectGetValue(reinterpret_cast<CGPDFObjectRef>(objects[i]), kCGPDFObjectTypeDictionary, &javaScriptAction)) + continue; + + // A JavaScript action must have an action type of "JavaScript". + const char* actionType; + if (!CGPDFDictionaryGetName(javaScriptAction, "S", &actionType) || strcmp(actionType, "JavaScript")) + continue; + + const UInt8* bytes = 0; + CFIndex length; + CGPDFStreamRef stream; + CGPDFStringRef string; + RetainPtr<CFDataRef> data; + if (CGPDFDictionaryGetStream(javaScriptAction, "JS", &stream)) { + CGPDFDataFormat format; + data.adoptCF(CGPDFStreamCopyData(stream, &format)); + if (!data) + continue; + bytes = CFDataGetBytePtr(data.get()); + length = CFDataGetLength(data.get()); + } else if (CGPDFDictionaryGetString(javaScriptAction, "JS", &string)) { + bytes = CGPDFStringGetBytePtr(string); + length = CGPDFStringGetLength(string); + } + if (!bytes) + continue; + + CFStringEncoding encoding = (length > 1 && bytes[0] == 0xFE && bytes[1] == 0xFF) ? kCFStringEncodingUnicode : kCFStringEncodingUTF8; + RetainPtr<CFStringRef> script(AdoptCF, CFStringCreateWithBytes(kCFAllocatorDefault, bytes, length, encoding, true)); + if (!script) + continue; + + scripts.append(script); + } +} + +namespace WebKit { + +const uint64_t pdfDocumentRequestID = 1; // PluginController supports loading multiple streams, but we only need one for PDF. + +const int gutterHeight = 10; +const int shadowOffsetX = 0; +const int shadowOffsetY = -2; +const int shadowSize = 7; + +PassRefPtr<BuiltInPDFView> BuiltInPDFView::create(WebFrame* frame) +{ + return adoptRef(new BuiltInPDFView(frame)); +} + +BuiltInPDFView::BuiltInPDFView(WebFrame* frame) + : m_frame(frame) +{ +} + +BuiltInPDFView::~BuiltInPDFView() +{ +} + +PluginInfo BuiltInPDFView::pluginInfo() +{ + PluginInfo info; + info.name = builtInPDFPluginName(); + + MimeClassInfo mimeClassInfo; + mimeClassInfo.type ="application/pdf"; + mimeClassInfo.desc = pdfDocumentTypeDescription(); + mimeClassInfo.extensions.append("pdf"); + + info.mimes.append(mimeClassInfo); + return info; +} + +PluginView* BuiltInPDFView::pluginView() +{ + return static_cast<PluginView*>(controller()); +} + +const PluginView* BuiltInPDFView::pluginView() const +{ + return static_cast<const PluginView*>(controller()); +} + +void BuiltInPDFView::updateScrollbars() +{ + if (m_horizontalScrollbar) { + if (m_pluginSize.width() >= m_pdfDocumentSize.width()) + destroyScrollbar(HorizontalScrollbar); + } else if (m_pluginSize.width() < m_pdfDocumentSize.width()) + m_horizontalScrollbar = createScrollbar(HorizontalScrollbar); + + if (m_verticalScrollbar) { + if (m_pluginSize.height() >= m_pdfDocumentSize.height()) + destroyScrollbar(VerticalScrollbar); + } else if (m_pluginSize.height() < m_pdfDocumentSize.height()) + m_verticalScrollbar = createScrollbar(VerticalScrollbar); + + int horizontalScrollbarHeight = (m_horizontalScrollbar && !m_horizontalScrollbar->isOverlayScrollbar()) ? m_horizontalScrollbar->height() : 0; + int verticalScrollbarWidth = (m_verticalScrollbar && !m_verticalScrollbar->isOverlayScrollbar()) ? m_verticalScrollbar->width() : 0; + + int pageStep = m_pageBoxes.isEmpty() ? 0 : m_pageBoxes[0].height(); + + if (m_horizontalScrollbar) { + m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep); + m_horizontalScrollbar->setProportion(m_pluginSize.width() - verticalScrollbarWidth, m_pdfDocumentSize.width()); + IntRect scrollbarRect(pluginView()->x(), pluginView()->y() + m_pluginSize.height() - m_horizontalScrollbar->height(), m_pluginSize.width(), m_horizontalScrollbar->height()); + if (m_verticalScrollbar) + scrollbarRect.contract(m_verticalScrollbar->width(), 0); + m_horizontalScrollbar->setFrameRect(scrollbarRect); + } + if (m_verticalScrollbar) { + m_verticalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep); + m_verticalScrollbar->setProportion(m_pluginSize.height() - horizontalScrollbarHeight, m_pdfDocumentSize.height()); + IntRect scrollbarRect(IntRect(pluginView()->x() + m_pluginSize.width() - m_verticalScrollbar->width(), pluginView()->y(), m_verticalScrollbar->width(), m_pluginSize.height())); + if (m_horizontalScrollbar) + scrollbarRect.contract(0, m_horizontalScrollbar->height()); + m_verticalScrollbar->setFrameRect(scrollbarRect); + } +} + +void BuiltInPDFView::didAddHorizontalScrollbar(Scrollbar* scrollbar) +{ + pluginView()->frame()->document()->didAddWheelEventHandler(); + ScrollableArea::didAddHorizontalScrollbar(scrollbar); +} + +void BuiltInPDFView::willRemoveHorizontalScrollbar(Scrollbar* scrollbar) +{ + ScrollableArea::willRemoveHorizontalScrollbar(scrollbar); + // FIXME: Maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback? + if (PluginView* pluginView = this->pluginView()) + pluginView->frame()->document()->didRemoveWheelEventHandler(); +} + +void BuiltInPDFView::didAddVerticalScrollbar(Scrollbar* scrollbar) +{ + pluginView()->frame()->document()->didAddWheelEventHandler(); + ScrollableArea::didAddVerticalScrollbar(scrollbar); +} + +void BuiltInPDFView::willRemoveVerticalScrollbar(Scrollbar* scrollbar) +{ + ScrollableArea::willRemoveVerticalScrollbar(scrollbar); + // FIXME: Maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback? + if (PluginView* pluginView = this->pluginView()) + pluginView->frame()->document()->didRemoveWheelEventHandler(); +} + +PassRefPtr<Scrollbar> BuiltInPDFView::createScrollbar(ScrollbarOrientation orientation) +{ + RefPtr<Scrollbar> widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar); + if (orientation == HorizontalScrollbar) + didAddHorizontalScrollbar(widget.get()); + else + didAddVerticalScrollbar(widget.get()); + pluginView()->frame()->view()->addChild(widget.get()); + return widget.release(); +} + +void BuiltInPDFView::destroyScrollbar(ScrollbarOrientation orientation) +{ + RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_horizontalScrollbar : m_verticalScrollbar; + if (!scrollbar) + return; + + if (orientation == HorizontalScrollbar) + willRemoveHorizontalScrollbar(scrollbar.get()); + else + willRemoveVerticalScrollbar(scrollbar.get()); + + scrollbar->removeFromParent(); + scrollbar->disconnectFromScrollableArea(); + scrollbar = 0; +} + +void BuiltInPDFView::addArchiveResource() +{ + // FIXME: It's a hack to force add a resource to DocumentLoader. PDF documents should just be fetched as CachedResources. + + // Add just enough data for context menu handling and web archives to work. + ResourceResponse synthesizedResponse; + synthesizedResponse.setSuggestedFilename(m_suggestedFilename); + synthesizedResponse.setURL(m_sourceURL); // Needs to match the HitTestResult::absolutePDFURL. + synthesizedResponse.setMimeType("application/pdf"); + + RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::wrapCFData(m_dataBuffer.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse); + pluginView()->frame()->document()->loader()->addArchiveResource(resource.release()); +} + +void BuiltInPDFView::pdfDocumentDidLoad() +{ + addArchiveResource(); + + RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_dataBuffer.get())); + m_pdfDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get())); + + calculateSizes(); + updateScrollbars(); + + controller()->invalidate(IntRect(0, 0, m_pluginSize.width(), m_pluginSize.height())); + + Vector<RetainPtr<CFStringRef> > scripts; + getAllScriptsInPDFDocument(m_pdfDocument.get(), scripts); + + size_t scriptCount = scripts.size(); + if (!scriptCount) + return; + + JSGlobalContextRef ctx = JSGlobalContextCreate(0); + JSObjectRef jsPDFDoc = makeJSPDFDoc(ctx); + + for (size_t i = 0; i < scriptCount; ++i) { + JSStringRef script = JSStringCreateWithCFString(scripts[i].get()); + JSEvaluateScript(ctx, script, jsPDFDoc, 0, 0, 0); + JSStringRelease(script); + } + + JSGlobalContextRelease(ctx); +} + +void BuiltInPDFView::calculateSizes() +{ + size_t pageCount = CGPDFDocumentGetNumberOfPages(m_pdfDocument.get()); + for (size_t i = 0; i < pageCount; ++i) { + CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), i + 1); + ASSERT(pdfPage); + + CGRect box = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox); + if (CGRectIsEmpty(box)) + box = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox); + m_pageBoxes.append(IntRect(box)); + m_pdfDocumentSize.setWidth(max(m_pdfDocumentSize.width(), static_cast<int>(box.size.width))); + m_pdfDocumentSize.expand(0, box.size.height); + } + m_pdfDocumentSize.expand(0, gutterHeight * (m_pageBoxes.size() - 1)); +} + +bool BuiltInPDFView::initialize(const Parameters& parameters) +{ + m_frame->coreFrame()->page()->addScrollableArea(this); + + // Load the src URL if needed. + m_sourceURL = parameters.url; + if (!parameters.loadManually && !parameters.url.isEmpty()) + controller()->loadURL(pdfDocumentRequestID, "GET", parameters.url.string(), String(), HTTPHeaderMap(), Vector<uint8_t>(), false); + + return true; +} + +void BuiltInPDFView::destroy() +{ + if (m_frame) { + if (Page* page = m_frame->coreFrame()->page()) + page->removeScrollableArea(this); + } + + destroyScrollbar(HorizontalScrollbar); + destroyScrollbar(VerticalScrollbar); +} + +void BuiltInPDFView::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRect) +{ + contentAreaWillPaint(); + + paintBackground(graphicsContext, dirtyRect); + + if (!m_pdfDocument) // FIXME: Draw loading progress. + return; + + paintContent(graphicsContext, dirtyRect); + paintControls(graphicsContext, dirtyRect); +} + +void BuiltInPDFView::paintBackground(GraphicsContext* graphicsContext, const IntRect& dirtyRect) +{ + GraphicsContextStateSaver stateSaver(*graphicsContext); + graphicsContext->setFillColor(Color::gray, ColorSpaceDeviceRGB); + graphicsContext->fillRect(dirtyRect); +} + +void BuiltInPDFView::paintContent(GraphicsContext* graphicsContext, const IntRect& dirtyRect) +{ + GraphicsContextStateSaver stateSaver(*graphicsContext); + CGContextRef context = graphicsContext->platformContext(); + + graphicsContext->setImageInterpolationQuality(InterpolationHigh); + graphicsContext->setShouldAntialias(true); + graphicsContext->setShouldSmoothFonts(true); + graphicsContext->setFillColor(Color::white, ColorSpaceDeviceRGB); + + graphicsContext->clip(dirtyRect); + IntRect contentRect(dirtyRect); + contentRect.moveBy(IntPoint(m_scrollOffset)); + graphicsContext->translate(-m_scrollOffset.width(), -m_scrollOffset.height()); + + CGContextScaleCTM(context, 1, -1); + + int pageTop = 0; + for (size_t i = 0; i < m_pageBoxes.size(); ++i) { + IntRect pageBox = m_pageBoxes[i]; + float extraOffsetForCenteringX = max(roundf((m_pluginSize.width() - pageBox.width()) / 2.0f), 0.0f); + float extraOffsetForCenteringY = (m_pageBoxes.size() == 1) ? max(roundf((m_pluginSize.height() - pageBox.height() + shadowOffsetY) / 2.0f), 0.0f) : 0; + + if (pageTop > contentRect.maxY()) + break; + if (pageTop + pageBox.height() + extraOffsetForCenteringY + gutterHeight >= contentRect.y()) { + CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), i + 1); + + graphicsContext->save(); + graphicsContext->translate(extraOffsetForCenteringX - pageBox.x(), -extraOffsetForCenteringY - pageBox.y() - pageBox.height()); + + graphicsContext->setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowSize, Color::black, ColorSpaceDeviceRGB); + graphicsContext->fillRect(pageBox); + graphicsContext->clearShadow(); + + graphicsContext->clip(pageBox); + + CGContextDrawPDFPage(context, pdfPage); + graphicsContext->restore(); + } + pageTop += pageBox.height() + gutterHeight; + CGContextTranslateCTM(context, 0, -pageBox.height() - gutterHeight); + } +} + +void BuiltInPDFView::paintControls(GraphicsContext* graphicsContext, const IntRect& dirtyRect) +{ + { + GraphicsContextStateSaver stateSaver(*graphicsContext); + IntRect scrollbarDirtyRect = dirtyRect; + scrollbarDirtyRect.moveBy(pluginView()->frameRect().location()); + graphicsContext->translate(-pluginView()->frameRect().x(), -pluginView()->frameRect().y()); + + if (m_horizontalScrollbar) + m_horizontalScrollbar->paint(graphicsContext, scrollbarDirtyRect); + + if (m_verticalScrollbar) + m_verticalScrollbar->paint(graphicsContext, scrollbarDirtyRect); + } + + IntRect dirtyCornerRect = intersection(scrollCornerRect(), dirtyRect); + ScrollbarTheme::theme()->paintScrollCorner(0, graphicsContext, dirtyCornerRect); +} + +void BuiltInPDFView::updateControlTints(GraphicsContext* graphicsContext) +{ + ASSERT(graphicsContext->updatingControlTints()); + + if (m_horizontalScrollbar) + m_horizontalScrollbar->invalidate(); + if (m_verticalScrollbar) + m_verticalScrollbar->invalidate(); + invalidateScrollCorner(scrollCornerRect()); +} + +PassRefPtr<ShareableBitmap> BuiltInPDFView::snapshot() +{ + return 0; +} + +#if PLATFORM(MAC) +PlatformLayer* BuiltInPDFView::pluginLayer() +{ + return 0; +} +#endif + + +bool BuiltInPDFView::isTransparent() +{ + // This should never be called from the web process. + ASSERT_NOT_REACHED(); + return false; +} + +void BuiltInPDFView::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform) +{ + if (m_pluginSize == pluginSize) { + // Nothing to do. + return; + } + + m_pluginSize = pluginSize; + updateScrollbars(); +} + +void BuiltInPDFView::visibilityDidChange() +{ +} + +void BuiltInPDFView::frameDidFinishLoading(uint64_t) +{ + ASSERT_NOT_REACHED(); +} + +void BuiltInPDFView::frameDidFail(uint64_t, bool) +{ + ASSERT_NOT_REACHED(); +} + +void BuiltInPDFView::didEvaluateJavaScript(uint64_t, const WTF::String&) +{ + ASSERT_NOT_REACHED(); +} + +void BuiltInPDFView::streamDidReceiveResponse(uint64_t streamID, const KURL&, uint32_t, uint32_t, const String&, const String&, const String& suggestedFilename) +{ + ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID); + + m_suggestedFilename = suggestedFilename; +} + +void BuiltInPDFView::streamDidReceiveData(uint64_t streamID, const char* bytes, int length) +{ + ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID); + + if (!m_dataBuffer) + m_dataBuffer.adoptCF(CFDataCreateMutable(0, 0)); + + CFDataAppendBytes(m_dataBuffer.get(), reinterpret_cast<const UInt8*>(bytes), length); +} + +void BuiltInPDFView::streamDidFinishLoading(uint64_t streamID) +{ + ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID); + + pdfDocumentDidLoad(); +} + +void BuiltInPDFView::streamDidFail(uint64_t streamID, bool wasCancelled) +{ + ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID); + + m_dataBuffer.clear(); +} + +void BuiltInPDFView::manualStreamDidReceiveResponse(const KURL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFilename) +{ + m_suggestedFilename = suggestedFilename; +} + +void BuiltInPDFView::manualStreamDidReceiveData(const char* bytes, int length) +{ + if (!m_dataBuffer) + m_dataBuffer.adoptCF(CFDataCreateMutable(0, 0)); + + CFDataAppendBytes(m_dataBuffer.get(), reinterpret_cast<const UInt8*>(bytes), length); +} + +void BuiltInPDFView::manualStreamDidFinishLoading() +{ + pdfDocumentDidLoad(); +} + +void BuiltInPDFView::manualStreamDidFail(bool) +{ + m_dataBuffer.clear(); +} + +bool BuiltInPDFView::handleMouseEvent(const WebMouseEvent& event) +{ + switch (event.type()) { + case WebEvent::MouseMove: + mouseMovedInContentArea(); + // FIXME: Should also notify scrollbar to show hover effect. Should also send mouseExited to hide it. + break; + case WebEvent::MouseDown: { + // Returning false as will make EventHandler unfocus the plug-in, which is appropriate when clicking scrollbars. + // Ideally, we wouldn't change focus at all, but PluginView already did that for us. + // When support for PDF forms is added, we'll need to actually focus the plug-in when clicking in a form. + break; + } + case WebEvent::MouseUp: { + PlatformMouseEvent platformEvent = platform(event); + if (m_horizontalScrollbar) + m_horizontalScrollbar->mouseUp(platformEvent); + if (m_verticalScrollbar) + m_verticalScrollbar->mouseUp(platformEvent); + break; + } + default: + break; + } + + return false; +} + +bool BuiltInPDFView::handleWheelEvent(const WebWheelEvent& event) +{ + PlatformWheelEvent platformEvent = platform(event); + return ScrollableArea::handleWheelEvent(platformEvent); +} + +bool BuiltInPDFView::handleMouseEnterEvent(const WebMouseEvent&) +{ + mouseEnteredContentArea(); + return false; +} + +bool BuiltInPDFView::handleMouseLeaveEvent(const WebMouseEvent&) +{ + mouseExitedContentArea(); + return false; +} + +bool BuiltInPDFView::handleContextMenuEvent(const WebMouseEvent&) +{ + // Use default WebKit context menu. + return false; +} + +bool BuiltInPDFView::handleKeyboardEvent(const WebKeyboardEvent&) +{ + return false; +} + +void BuiltInPDFView::setFocus(bool hasFocus) +{ +} + +NPObject* BuiltInPDFView::pluginScriptableNPObject() +{ + return 0; +} + +#if PLATFORM(MAC) + +void BuiltInPDFView::windowFocusChanged(bool) +{ +} + +void BuiltInPDFView::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) +{ +} + +void BuiltInPDFView::windowVisibilityChanged(bool) +{ +} + +void BuiltInPDFView::contentsScaleFactorChanged(float) +{ +} + +uint64_t BuiltInPDFView::pluginComplexTextInputIdentifier() const +{ + return 0; +} + +void BuiltInPDFView::sendComplexTextInput(const String&) +{ +} + +#endif + +void BuiltInPDFView::privateBrowsingStateChanged(bool) +{ +} + +bool BuiltInPDFView::getFormValue(String&) +{ + return false; +} + +bool BuiltInPDFView::handleScroll(ScrollDirection direction, ScrollGranularity granularity) +{ + return scroll(direction, granularity); +} + +Scrollbar* BuiltInPDFView::horizontalScrollbar() +{ + return m_horizontalScrollbar.get(); +} + +Scrollbar* BuiltInPDFView::verticalScrollbar() +{ + return m_verticalScrollbar.get(); +} + +IntRect BuiltInPDFView::scrollCornerRect() const +{ + if (!m_horizontalScrollbar || !m_verticalScrollbar) + return IntRect(); + if (m_horizontalScrollbar->isOverlayScrollbar()) { + ASSERT(m_verticalScrollbar->isOverlayScrollbar()); + return IntRect(); + } + return IntRect(pluginView()->width() - m_verticalScrollbar->width(), pluginView()->height() - m_horizontalScrollbar->height(), m_verticalScrollbar->width(), m_horizontalScrollbar->height()); +} + +ScrollableArea* BuiltInPDFView::enclosingScrollableArea() const +{ + // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer. + return 0; +} + +void BuiltInPDFView::setScrollOffset(const IntPoint& offset) +{ + m_scrollOffset = IntSize(offset.x(), offset.y()); + // FIXME: It would be better for performance to blit parts that remain visible. + controller()->invalidate(IntRect(0, 0, m_pluginSize.width(), m_pluginSize.height())); +} + +int BuiltInPDFView::scrollSize(ScrollbarOrientation orientation) const +{ + Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalScrollbar : m_verticalScrollbar).get(); + return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0; +} + +bool BuiltInPDFView::isActive() const +{ + if (Frame* coreFrame = m_frame->coreFrame()) { + if (Page* page = coreFrame->page()) + return page->focusController()->isActive(); + } + + return false; +} + +void BuiltInPDFView::invalidateScrollbarRect(Scrollbar* scrollbar, const LayoutRect& rect) +{ + IntRect dirtyRect = rect; + dirtyRect.moveBy(scrollbar->location()); + dirtyRect.moveBy(-pluginView()->location()); + controller()->invalidate(dirtyRect); +} + +void BuiltInPDFView::invalidateScrollCornerRect(const IntRect& rect) +{ + controller()->invalidate(rect); +} + +bool BuiltInPDFView::isScrollCornerVisible() const +{ + return false; +} + +int BuiltInPDFView::scrollPosition(Scrollbar* scrollbar) const +{ + if (scrollbar->orientation() == HorizontalScrollbar) + return m_scrollOffset.width(); + if (scrollbar->orientation() == VerticalScrollbar) + return m_scrollOffset.height(); + ASSERT_NOT_REACHED(); + return 0; +} + +IntPoint BuiltInPDFView::scrollPosition() const +{ + return IntPoint(m_scrollOffset.width(), m_scrollOffset.height()); +} + +IntPoint BuiltInPDFView::minimumScrollPosition() const +{ + return IntPoint(0, 0); +} + +IntPoint BuiltInPDFView::maximumScrollPosition() const +{ + int horizontalScrollbarHeight = (m_horizontalScrollbar && !m_horizontalScrollbar->isOverlayScrollbar()) ? m_horizontalScrollbar->height() : 0; + int verticalScrollbarWidth = (m_verticalScrollbar && !m_verticalScrollbar->isOverlayScrollbar()) ? m_verticalScrollbar->width() : 0; + + IntPoint maximumOffset(m_pdfDocumentSize.width() - m_pluginSize.width() + verticalScrollbarWidth, m_pdfDocumentSize.height() - m_pluginSize.height() + horizontalScrollbarHeight); + maximumOffset.clampNegativeToZero(); + return maximumOffset; +} + +int BuiltInPDFView::visibleHeight() const +{ + return m_pluginSize.height(); +} + +int BuiltInPDFView::visibleWidth() const +{ + return m_pluginSize.width(); +} + +IntSize BuiltInPDFView::contentsSize() const +{ + return m_pdfDocumentSize; +} + +bool BuiltInPDFView::isOnActivePage() const +{ + return !pluginView()->frame()->document()->inPageCache(); +} + +void BuiltInPDFView::scrollbarStyleChanged(int, bool forceUpdate) +{ + if (!forceUpdate) + return; + + // If the PDF was scrolled all the way to bottom right and scrollbars change to overlay style, we don't want to display white rectangles where scrollbars were. + IntPoint newScrollOffset = IntPoint(m_scrollOffset).shrunkTo(maximumScrollPosition()); + setScrollOffset(newScrollOffset); + + // As size of the content area changes, scrollbars may need to appear or to disappear. + updateScrollbars(); + + ScrollableArea::contentsResized(); +} + +IntPoint BuiltInPDFView::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const +{ + IntPoint point = pluginView()->frame()->view()->convertToRenderer(pluginView()->renderer(), parentPoint); + point.move(pluginView()->location() - scrollbar->location()); + + return point; +} + +static void jsPDFDocInitialize(JSContextRef ctx, JSObjectRef object) +{ + BuiltInPDFView* pdfView = static_cast<BuiltInPDFView*>(JSObjectGetPrivate(object)); + pdfView->ref(); +} + +static void jsPDFDocFinalize(JSObjectRef object) +{ + BuiltInPDFView* pdfView = static_cast<BuiltInPDFView*>(JSObjectGetPrivate(object)); + pdfView->deref(); +} + +JSValueRef BuiltInPDFView::jsPDFDocPrint(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + BuiltInPDFView* pdfView = static_cast<BuiltInPDFView*>(JSObjectGetPrivate(thisObject)); + + WebFrame* frame = pdfView->m_frame; + if (!frame) + return JSValueMakeUndefined(ctx); + + Frame* coreFrame = frame->coreFrame(); + if (!coreFrame) + return JSValueMakeUndefined(ctx); + + Page* page = coreFrame->page(); + if (!page) + return JSValueMakeUndefined(ctx); + + page->chrome()->print(coreFrame); + + return JSValueMakeUndefined(ctx); +} + +JSObjectRef BuiltInPDFView::makeJSPDFDoc(JSContextRef ctx) +{ + static JSStaticFunction jsPDFDocStaticFunctions[] = { + { "print", jsPDFDocPrint, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 }, + }; + + static JSClassDefinition jsPDFDocClassDefinition = { + 0, + kJSClassAttributeNone, + "Doc", + 0, + 0, + jsPDFDocStaticFunctions, + jsPDFDocInitialize, jsPDFDocFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + static JSClassRef jsPDFDocClass = JSClassCreate(&jsPDFDocClassDefinition); + + return JSObjectMake(ctx, jsPDFDocClass, this); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h b/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h new file mode 100644 index 000000000..6ee4bf3c5 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h @@ -0,0 +1,173 @@ +/* + * 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 BuiltInPDFView_h +#define BuiltInPDFView_h + +#include "Plugin.h" +#include <WebCore/ScrollableArea.h> +#include <wtf/RetainPtr.h> + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; +typedef const struct OpaqueJSValue* JSValueRef; + +namespace WebCore { + struct PluginInfo; +} + +namespace WebKit { + +class PluginView; +class WebFrame; + +class BuiltInPDFView : public Plugin, private WebCore::ScrollableArea { +public: + static PassRefPtr<BuiltInPDFView> create(WebFrame*); + ~BuiltInPDFView(); + + static WebCore::PluginInfo pluginInfo(); + +private: + explicit BuiltInPDFView(WebFrame*); + + // Regular plug-ins don't need access to view, but we add scrollbars to embedding FrameView for proper event handling. + PluginView* pluginView(); + const PluginView* pluginView() const; + + void updateScrollbars(); + void didAddHorizontalScrollbar(WebCore::Scrollbar*); + void willRemoveHorizontalScrollbar(WebCore::Scrollbar*); + void didAddVerticalScrollbar(WebCore::Scrollbar*); + void willRemoveVerticalScrollbar(WebCore::Scrollbar*); + PassRefPtr<WebCore::Scrollbar> createScrollbar(WebCore::ScrollbarOrientation); + void destroyScrollbar(WebCore::ScrollbarOrientation); + void addArchiveResource(); + void pdfDocumentDidLoad(); + void calculateSizes(); + void paintBackground(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + void paintContent(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + void paintControls(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + + // Plug-in methods + virtual bool initialize(const Parameters&); + virtual void destroy(); + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRectInWindowCoordinates); + virtual void updateControlTints(WebCore::GraphicsContext*); + virtual PassRefPtr<ShareableBitmap> snapshot(); +#if PLATFORM(MAC) + virtual PlatformLayer* pluginLayer(); +#endif + virtual bool isTransparent(); + virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform); + virtual void visibilityDidChange(); + virtual void frameDidFinishLoading(uint64_t requestID); + virtual void frameDidFail(uint64_t requestID, bool wasCancelled); + virtual void didEvaluateJavaScript(uint64_t requestID, 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, const String& suggestedFileName); + 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, const String& suggestedFileName); + 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 handleContextMenuEvent(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 void contentsScaleFactorChanged(float); + virtual uint64_t pluginComplexTextInputIdentifier() const; + virtual void sendComplexTextInput(const String& textInput); +#endif + + virtual void privateBrowsingStateChanged(bool); + virtual bool getFormValue(String& formValue); + virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); + virtual WebCore::Scrollbar* horizontalScrollbar(); + virtual WebCore::Scrollbar* verticalScrollbar(); + + virtual RetainPtr<CGPDFDocumentRef> pdfDocumentForPrinting() const OVERRIDE { return m_pdfDocument; } + + // ScrollableArea methods. + virtual WebCore::IntRect scrollCornerRect() const; + virtual WebCore::ScrollableArea* enclosingScrollableArea() const; + virtual void setScrollOffset(const WebCore::IntPoint&); + virtual int scrollSize(WebCore::ScrollbarOrientation) const; + virtual bool isActive() const; + virtual void invalidateScrollbarRect(WebCore::Scrollbar*, const WebCore::IntRect&); + virtual void invalidateScrollCornerRect(const WebCore::IntRect&); + virtual bool isScrollCornerVisible() const; + virtual int scrollPosition(WebCore::Scrollbar*) const; + virtual WebCore::IntPoint scrollPosition() const; + virtual WebCore::IntPoint minimumScrollPosition() const; + virtual WebCore::IntPoint maximumScrollPosition() const; + virtual int visibleHeight() const; + virtual int visibleWidth() const; + virtual WebCore::IntSize contentsSize() const; + virtual WebCore::Scrollbar* horizontalScrollbar() const { return m_horizontalScrollbar.get(); } + virtual WebCore::Scrollbar* verticalScrollbar() const { return m_verticalScrollbar.get(); } + virtual bool isOnActivePage() const; + virtual void disconnectFromPage() { m_frame = 0; } + virtual bool shouldSuspendScrollAnimations() const { return false; } // If we return true, ScrollAnimatorMac will keep cycling a timer forever, waiting for a good time to animate. + virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate); + virtual void zoomAnimatorTransformChanged(float, float, float, ZoomAnimationState) { } + + // FIXME: Implement the other conversion functions; this one is enough to get scrollbar hit testing working. + virtual WebCore::IntPoint convertFromContainingViewToScrollbar(const WebCore::Scrollbar*, const WebCore::IntPoint& parentPoint) const; + + JSObjectRef makeJSPDFDoc(JSContextRef); + static JSValueRef jsPDFDocPrint(JSContextRef, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + + WebCore::IntSize m_pluginSize; + + WebCore::KURL m_sourceURL; + + String m_suggestedFilename; + RetainPtr<CFMutableDataRef> m_dataBuffer; + + RetainPtr<CGPDFDocumentRef> m_pdfDocument; + Vector<WebCore::IntRect> m_pageBoxes; + WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps. + + RefPtr<WebCore::Scrollbar> m_horizontalScrollbar; + RefPtr<WebCore::Scrollbar> m_verticalScrollbar; + + WebFrame* m_frame; + + WebCore::IntSize m_scrollOffset; +}; + +} // namespace WebKit + +#endif // BuiltInPDFView_h diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.cpp b/Source/WebKit2/WebProcess/Plugins/Plugin.cpp new file mode 100644 index 000000000..87c9940a5 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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); + encoder->encode(documentURL); + encoder->encode(toplevelDocumentURL); +} + +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 (!decoder->decode(parameters.documentURL)) + return false; + if (!decoder->decode(parameters.toplevelDocumentURL)) + return false; + + if (parameters.names.size() != parameters.values.size()) { + decoder->markInvalid(); + return false; + } + + return true; +} + +Plugin::Plugin() + : m_pluginController(0) +{ +} + +Plugin::~Plugin() +{ +} + +bool Plugin::initialize(PluginController* pluginController, const Parameters& parameters) +{ + ASSERT(!m_pluginController); + ASSERT(pluginController); + + m_pluginController = pluginController; + + return initialize(parameters); +} + +void Plugin::destroyPlugin() +{ + destroy(); + + m_pluginController = 0; +} + +void Plugin::updateControlTints(GraphicsContext*) +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.h b/Source/WebKit2/WebProcess/Plugins/Plugin.h new file mode 100644 index 000000000..4c656a3a7 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.h @@ -0,0 +1,235 @@ +/* + * 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 <WebCore/ScrollTypes.h> +#include <wtf/RefCounted.h> +#include <wtf/RetainPtr.h> +#include <wtf/Vector.h> + +struct NPObject; + +namespace CoreIPC { + class ArgumentEncoder; + class ArgumentDecoder; +} + +namespace WebCore { + class AffineTransform; + class GraphicsContext; + class IntRect; + class IntSize; + class Scrollbar; +} + +namespace WebKit { + +class ShareableBitmap; +class WebKeyboardEvent; +class WebMouseEvent; +class WebWheelEvent; + +class PluginController; + +class Plugin : public ThreadSafeRefCounted<Plugin> { +public: + struct Parameters { + WebCore::KURL url; + Vector<String> names; + Vector<String> values; + String mimeType; + bool loadManually; + + // The URL of the document that the plug-in is in. + String documentURL; + + // The URL of the document in the main frame. Will be null if the document the plug-in + // doesn't have access to the main frame document. + String toplevelDocumentURL; + + void encode(CoreIPC::ArgumentEncoder*) const; + static bool decode(CoreIPC::ArgumentDecoder*, Parameters&); + }; + + // Sets the active plug-in controller and initializes the plug-in. + bool initialize(PluginController*, const Parameters&); + + // Destroys the plug-in. + void destroyPlugin(); + + // Returns the plug-in controller for this plug-in. + PluginController* controller() { return m_pluginController; } + const PluginController* controller() const { return m_pluginController; } + + virtual ~Plugin(); + +private: + + // Initializes the plug-in. If the plug-in fails to initialize this should return false. + // This is only called by the other initialize overload so it can be made private. + virtual bool initialize(const Parameters&) = 0; + + // Destroys the plug-in. + virtual void destroy() = 0; + +public: + + // 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; + + // Invalidate native tintable controls. The passed-in context is in window coordinates. + virtual void updateControlTints(WebCore::GraphicsContext*); + + // Tells the plug-in to draw itself into a bitmap, and return that. + virtual PassRefPtr<ShareableBitmap> snapshot() = 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 + + // Returns whether the plug-in is transparent or not. + virtual bool isTransparent() = 0; + + // Tells the plug-in that its geometry has changed. The clip rect is in plug-in coordinates, and the affine transform can be used + // to convert from root view coordinates to plug-in coordinates. + virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) = 0; + + // Tells the plug-in that it has been explicitly hidden or shown. (Note that this is not called when the plug-in becomes obscured from view on screen.) + virtual void visibilityDidChange() = 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& 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, const String& suggestedFileName) = 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, const String& suggestedFileName) = 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 context menu event. The plug-in should return true if it processed the event. + virtual bool handleContextMenuEvent(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 + + // Tells the plug-in about scale factor changes. + virtual void contentsScaleFactorChanged(float) = 0; + + // Called when the private browsing state for this plug-in changes. + virtual void privateBrowsingStateChanged(bool) = 0; + + // Gets the form value representation for the plug-in, letting plug-ins participate in form submission. + virtual bool getFormValue(String& formValue) = 0; + + // Tells the plug-in that it should scroll. The plug-in should return true if it did scroll. + virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) = 0; + + // A plug-in can use WebCore scroll bars. Make them known, so that hit testing can find them. + // FIXME: This code should be in PluginView or its base class, not in individual plug-ins. + virtual WebCore::Scrollbar* horizontalScrollbar() = 0; + virtual WebCore::Scrollbar* verticalScrollbar() = 0; + +#if USE(CG) + virtual RetainPtr<CGPDFDocumentRef> pdfDocumentForPrinting() const { return 0; } +#endif + +protected: + Plugin(); + +private: + PluginController* m_pluginController; +}; + +} // 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 000000000..da48eb6e1 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginController.h @@ -0,0 +1,173 @@ +/* + * 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> + +#if PLATFORM(MAC) +#include "PluginComplexTextInputState.h" +#endif + +struct NPObject; +typedef struct _NPVariant NPVariant; +typedef void* NPIdentifier; + +namespace WebCore { + class HTTPHeaderMap; + class IntRect; + class KURL; + class ProtectionSpace; +} + +namespace WebKit { + +#if PLATFORM(WIN) +struct WindowGeometry; +#endif + +class PluginController { +public: + // Returns false if the plugin has explicitly been hidden. Returns true otherwise (even if the plugin is currently obscured from view on screen.) + virtual bool isPluginVisible() = 0; + + // 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; + + // Tries to short circuit the NPN_Invoke call with the given parameters. Returns true on success. + virtual bool tryToShortCircuitInvoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result) = 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; + + // Tells the controller that we're about to dispatch an event to the plug-in. + virtual void willSendEventToPlugin() = 0; + +#if PLATFORM(WIN) + // The window to use as the parent of the plugin's window. + virtual HWND nativeParentWindow() = 0; + + // Tells the controller that the given HWND needs to be positioned and clipped to the given + // coordinates sometime soon. The controller will decide exactly when this will happen. + virtual void scheduleWindowedPluginGeometryUpdate(const WindowGeometry&) = 0; +#endif + +#if PLATFORM(MAC) + // Tells the controller that the plug-in focus or window focus did change. + virtual void pluginFocusOrWindowFocusChanged(bool) = 0; + + // Tells the controller that complex text input be enabled or disabled for the plug-in. + virtual void setComplexTextInputState(PluginComplexTextInputState) = 0; + + // Returns the mach port of the compositing render server. + virtual mach_port_t compositingRenderServerPort() = 0; +#endif + + // Returns the contents scale factor. + virtual float contentsScaleFactor() = 0; + + // 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; + + // Get authentication credentials for the given protection space. + virtual bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password) = 0; + + // Returns whether private browsing is enabled. + virtual bool isPrivateBrowsingEnabled() = 0; + + // Increments a counter that prevents the plug-in from being destroyed. + virtual void protectPluginFromDestruction() = 0; + + // Decrements a counter that, when it reaches 0, stops preventing the plug-in from being destroyed. + virtual void unprotectPluginFromDestruction() = 0; + + // Helper class for delaying destruction of a plug-in. + class PluginDestructionProtector { + public: + explicit PluginDestructionProtector(PluginController* pluginController) + : m_pluginController(pluginController) + { + m_pluginController->protectPluginFromDestruction(); + } + + ~PluginDestructionProtector() + { + m_pluginController->unprotectPluginFromDestruction(); + } + + private: + PluginController* m_pluginController; + }; + +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 000000000..b2152713b --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp @@ -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 "config.h" +#include "PluginProcessConnection.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "NPRemoteObjectMap.h" +#include "NPRuntimeObjectMap.h" +#include "PluginProcessConnectionManager.h" +#include "PluginProxy.h" +#include "WebProcess.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/FileSystem.h> + +using namespace WebCore; + +namespace WebKit { + +// The timeout, in seconds, when sending sync messages to the plug-in. +static const double syncMessageTimeout = 45; + +static double defaultSyncMessageTimeout(const String& pluginPath) +{ + // FIXME: We should key this off something other than the path. + + // We don't want a message timeout for the AppleConnect plug-in. + if (pathGetFileName(pluginPath) == "AppleConnect.plugin") + return CoreIPC::Connection::NoTimeout; + + // We don't want a message timeout for the Microsoft SharePoint plug-in + // since it can spin a nested run loop in response to an NPN_Invoke, making it seem like + // the plug-in process is hung. See <rdar://problem/9536303>. + // FIXME: Instead of changing the default sync message timeout, CoreIPC could send an + // asynchronous message which the other process would have to reply to on the main thread. + // This way we could check if the plug-in process is actually hung or not. + if (pathGetFileName(pluginPath) == "SharePointBrowserPlugin.plugin") + return CoreIPC::Connection::NoTimeout; + + // We don't want a message timeout for the BankID plug-in since it can spin a nested + // run loop when it's waiting for a reply to an AppleEvent. + if (pathGetFileName(pluginPath) == "PersonalPlugin.bundle") + return CoreIPC::Connection::NoTimeout; + + if (WebProcess::shared().disablePluginProcessMessageTimeout()) + return CoreIPC::Connection::NoTimeout; + + return syncMessageTimeout; +} + +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_connection->setDefaultSyncMessageTimeout(defaultSyncMessageTimeout(m_pluginPath)); + 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()); + + // Invalidate all objects related to this plug-in. + m_npRemoteObjectMap->pluginDestroyed(plugin); + + if (!m_plugins.isEmpty()) + return; + + m_npRemoteObjectMap = nullptr; + + // 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) +{ + ASSERT(arguments->destinationID()); + + PluginProxy* pluginProxy = m_plugins.get(arguments->destinationID()); + if (!pluginProxy) + return; + + pluginProxy->didReceivePluginProxyMessage(connection, messageID, arguments); +} + +void PluginProcessConnection::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply) +{ + if (messageID.is<CoreIPC::MessageClassNPObjectMessageReceiver>()) { + m_npRemoteObjectMap->didReceiveSyncMessage(connection, messageID, arguments, reply); + return; + } + + uint64_t destinationID = arguments->destinationID(); + + if (!destinationID) { + didReceiveSyncPluginProcessConnectionMessage(connection, messageID, arguments, reply); + return; + } + + PluginProxy* pluginProxy = m_plugins.get(destinationID); + if (!pluginProxy) + return; + + pluginProxy->didReceiveSyncPluginProxyMessage(connection, messageID, arguments, reply); +} + +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) +{ +} + +void PluginProcessConnection::syncMessageSendTimedOut(CoreIPC::Connection*) +{ + WebProcess::shared().connection()->send(Messages::WebProcessProxy::PluginSyncMessageSendTimedOut(m_pluginPath), 0); +} + +void PluginProcessConnection::setException(const String& exceptionString) +{ + NPRuntimeObjectMap::setGlobalException(exceptionString); +} + +} // 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 000000000..61c4ac2a5 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h @@ -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. + */ + +#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 void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); + + // Message handlers. + void didReceiveSyncPluginProcessConnectionMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + void setException(const String&); + + 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/PluginProcessConnection.messages.in b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.messages.in new file mode 100644 index 000000000..5573f3bda --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.messages.in @@ -0,0 +1,30 @@ +# 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. + +#if ENABLE(PLUGIN_PROCESS) + +messages -> PluginProcessConnection { + # Set a global JavaScript exception. + SetException(WTF::String exceptionString) -> () +} + +#endif diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp new file mode 100644 index 000000000..fd1906d7a --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProcessConnectionManager.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "ArgumentDecoder.h" +#include "ArgumentEncoder.h" +#include "PluginProcessConnection.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcess.h" +#include "WebProcessProxyMessages.h" + +#if PLATFORM(MAC) +#include "MachPort.h" +#endif + +namespace WebKit { + +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::Attachment encodedConnectionIdentifier; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::GetPluginProcessConnection(pluginPath), + Messages::WebProcessProxy::GetPluginProcessConnection::Reply(encodedConnectionIdentifier), 0)) + return 0; + +#if PLATFORM(MAC) + CoreIPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.port(); + if (!connectionIdentifier) + return 0; +#elif USE(UNIX_DOMAIN_SOCKETS) + CoreIPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.fileDescriptor(); + if (connectionIdentifier == -1) + return 0; +#endif + + RefPtr<PluginProcessConnection> pluginProcessConnection = PluginProcessConnection::create(this, pluginPath, connectionIdentifier); + m_pluginProcessConnections.append(pluginProcessConnection); + + { + MutexLocker locker(m_pathsAndConnectionsMutex); + ASSERT(!m_pathsAndConnections.contains(pluginProcessConnection->pluginPath())); + + m_pathsAndConnections.set(pluginPath, pluginProcessConnection->connection()); + } + + return pluginProcessConnection.get(); +} + +void PluginProcessConnectionManager::removePluginProcessConnection(PluginProcessConnection* pluginProcessConnection) +{ + size_t vectorIndex = m_pluginProcessConnections.find(pluginProcessConnection); + ASSERT(vectorIndex != notFound); + + { + MutexLocker locker(m_pathsAndConnectionsMutex); + ASSERT(m_pathsAndConnections.contains(pluginProcessConnection->pluginPath())); + + m_pathsAndConnections.remove(pluginProcessConnection->pluginPath()); + } + + m_pluginProcessConnections.remove(vectorIndex); +} + +void PluginProcessConnectionManager::pluginProcessCrashed(const String& pluginPath) +{ + MutexLocker locker(m_pathsAndConnectionsMutex); + CoreIPC::Connection* connection = m_pathsAndConnections.get(pluginPath).get(); + + // It's OK for connection to be null here; it will happen if this web process doesn't know + // anything about the plug-in process. + if (!connection) + return; + + connection->postConnectionDidCloseOnConnectionWorkQueue(); +} + +} // 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 000000000..45515cdf1 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.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 PluginProcessConnectionManager_h +#define PluginProcessConnectionManager_h + +#if ENABLE(PLUGIN_PROCESS) + +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/Threading.h> +#include <wtf/Vector.h> +#include <wtf/text/StringHash.h> + +// Manages plug-in process connections for the given web process. + +namespace CoreIPC { + class Connection; +} + +namespace WebKit { + +class PluginProcessConnection; + +class PluginProcessConnectionManager { + WTF_MAKE_NONCOPYABLE(PluginProcessConnectionManager); +public: + PluginProcessConnectionManager(); + ~PluginProcessConnectionManager(); + + PluginProcessConnection* getPluginProcessConnection(const String& pluginPath); + void removePluginProcessConnection(PluginProcessConnection*); + + // Called on the web process connection work queue. + void pluginProcessCrashed(const String& pluginPath); + +private: + Vector<RefPtr<PluginProcessConnection> > m_pluginProcessConnections; + + Mutex m_pathsAndConnectionsMutex; + HashMap<String, RefPtr<CoreIPC::Connection> > m_pathsAndConnections; +}; + +} + +#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 000000000..638250e8e --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "DataReference.h" +#include "NPRemoteObjectMap.h" +#include "NPRuntimeUtilities.h" +#include "NPVariantData.h" +#include "PluginController.h" +#include "PluginControllerProxyMessages.h" +#include "PluginCreationParameters.h" +#include "PluginProcessConnection.h" +#include "PluginProcessConnectionManager.h" +#include "ShareableBitmap.h" +#include "WebCoreArgumentCoders.h" +#include "WebEvent.h" +#include "WebProcess.h" +#include "WebProcessConnectionMessages.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/NotImplemented.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_pluginBackingStoreContainsValidData(false) + , m_isStarted(false) + , m_waitingForPaintInResponseToUpdate(false) + , m_remoteLayerClientID(0) +{ +} + +PluginProxy::~PluginProxy() +{ +} + +void PluginProxy::pluginProcessCrashed() +{ + controller()->pluginProcessCrashed(); +} + +bool PluginProxy::initialize(const Parameters& parameters) +{ + ASSERT(!m_connection); + m_connection = WebProcess::shared().pluginProcessConnectionManager().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. + PluginCreationParameters creationParameters; + creationParameters.pluginInstanceID = m_pluginInstanceID; + creationParameters.windowNPObjectID = windowNPObjectID(); + creationParameters.parameters = parameters; + creationParameters.userAgent = controller()->userAgent(); + creationParameters.contentsScaleFactor = contentsScaleFactor(); + creationParameters.isPrivateBrowsingEnabled = controller()->isPrivateBrowsingEnabled(); +#if USE(ACCELERATED_COMPOSITING) + creationParameters.isAcceleratedCompositingEnabled = controller()->isAcceleratedCompositingEnabled(); +#endif + + bool result = false; + uint32_t remoteLayerClientID = 0; + + if (!m_connection->connection()->sendSync(Messages::WebProcessConnection::CreatePlugin(creationParameters), 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(); + graphicsContext->applyDeviceScaleFactor(contentsScaleFactor()); + graphicsContext->setCompositeOperation(CompositeCopy); + + m_pluginBackingStore->paint(*graphicsContext, contentsScaleFactor(), IntPoint(), pluginBounds()); + + m_pluginBackingStoreContainsValidData = true; + } + + m_backingStore->paint(*graphicsContext, contentsScaleFactor(), dirtyRect.location(), dirtyRect); + + if (m_waitingForPaintInResponseToUpdate) { + m_waitingForPaintInResponseToUpdate = false; + m_connection->connection()->send(Messages::PluginControllerProxy::DidUpdate(), m_pluginInstanceID); + return; + } +} + +PassRefPtr<ShareableBitmap> PluginProxy::snapshot() +{ + ShareableBitmap::Handle snapshotStoreHandle; + m_connection->connection()->sendSync(Messages::PluginControllerProxy::Snapshot(), Messages::PluginControllerProxy::Snapshot::Reply(snapshotStoreHandle), m_pluginInstanceID); + + RefPtr<ShareableBitmap> snapshotBuffer = ShareableBitmap::create(snapshotStoreHandle); + return snapshotBuffer.release(); +} + +bool PluginProxy::isTransparent() +{ + // This should never be called from the web process. + ASSERT_NOT_REACHED(); + return false; +} + +void PluginProxy::geometryDidChange() +{ + ASSERT(m_isStarted); + + ShareableBitmap::Handle pluginBackingStoreHandle; + + if (updateBackingStore()) { + // Create a new plug-in backing store. + m_pluginBackingStore = ShareableBitmap::createShareable(m_backingStore->size(), ShareableBitmap::SupportsAlpha); + 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 = nullptr; + return; + } + + m_pluginBackingStoreContainsValidData = false; + } + + m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_pluginSize, m_clipRect, m_pluginToRootViewTransform, contentsScaleFactor(), pluginBackingStoreHandle), m_pluginInstanceID, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply); +} + +void PluginProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform) +{ + if (pluginSize == m_pluginSize && m_clipRect == clipRect && m_pluginToRootViewTransform == pluginToRootViewTransform) { + // Nothing to do. + return; + } + + m_pluginSize = pluginSize; + m_clipRect = clipRect; + m_pluginToRootViewTransform = pluginToRootViewTransform; + + geometryDidChange(); +} + +void PluginProxy::visibilityDidChange() +{ + ASSERT(m_isStarted); + notImplemented(); +} + +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& result) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::DidEvaluateJavaScript(requestID, 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, const String& /* suggestedFileName */) +{ + 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, const String& /* suggestedFileName */) +{ + 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::handleContextMenuEvent(const WebMouseEvent&) +{ + // We don't know if the plug-in has handled mousedown event by displaying a context menu, so we never want WebKit to show a default one. + return true; +} + +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() +{ + // Sending the synchronous Messages::PluginControllerProxy::GetPluginScriptableNPObject message can cause us to dispatch an + // incoming synchronous message that ends up destroying the PluginProxy object. + PluginController::PluginDestructionProtector protector(controller()); + + 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, this); +} + +#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::contentsScaleFactorChanged(float scaleFactor) +{ + geometryDidChange(); +} + +void PluginProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled) +{ + m_connection->connection()->send(Messages::PluginControllerProxy::PrivateBrowsingStateChanged(isPrivateBrowsingEnabled), m_pluginInstanceID); +} + +bool PluginProxy::getFormValue(String& formValue) +{ + bool returnValue; + if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::GetFormValue(), Messages::PluginControllerProxy::GetFormValue::Reply(returnValue, formValue), m_pluginInstanceID)) + return false; + + return returnValue; +} + +bool PluginProxy::handleScroll(ScrollDirection, ScrollGranularity) +{ + return false; +} + +Scrollbar* PluginProxy::horizontalScrollbar() +{ + return 0; +} + +Scrollbar* PluginProxy::verticalScrollbar() +{ + return 0; +} + +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) +{ + controller()->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups); +} + +void PluginProxy::proxiesForURL(const String& urlString, String& proxyString) +{ + proxyString = controller()->proxiesForURL(urlString); +} + +void PluginProxy::cookiesForURL(const String& urlString, String& cookieString) +{ + cookieString = controller()->cookiesForURL(urlString); +} + +void PluginProxy::setCookiesForURL(const String& urlString, const String& cookieString) +{ + controller()->setCookiesForURL(urlString, cookieString); +} + +void PluginProxy::getAuthenticationInfo(const ProtectionSpace& protectionSpace, bool& returnValue, String& username, String& password) +{ + returnValue = controller()->getAuthenticationInfo(protectionSpace, username, password); +} + +float PluginProxy::contentsScaleFactor() +{ + return controller()->contentsScaleFactor(); +} + +bool PluginProxy::updateBackingStore() +{ + if (m_pluginSize.isEmpty() || !needsBackingStore()) + return false; + + IntSize backingStoreSize = m_pluginSize; + backingStoreSize.scale(contentsScaleFactor()); + + if (!m_backingStore) { + m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha); + return true; + } + + if (backingStoreSize != m_backingStore->size()) { + // The backing store already exists, just resize it. + return m_backingStore->resize(backingStoreSize); + } + + return false; +} + +uint64_t PluginProxy::windowNPObjectID() +{ + NPObject* windowScriptNPObject = controller()->windowScriptNPObject(); + if (!windowScriptNPObject) + return 0; + + uint64_t windowNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(windowScriptNPObject, this); + releaseNPObject(windowScriptNPObject); + + return windowNPObjectID; +} + +IntRect PluginProxy::pluginBounds() +{ + return IntRect(IntPoint(), m_pluginSize); +} + +void PluginProxy::getPluginElementNPObject(uint64_t& pluginElementNPObjectID) +{ + NPObject* pluginElementNPObject = controller()->pluginElementNPObject(); + if (!pluginElementNPObject) { + pluginElementNPObjectID = 0; + return; + } + + pluginElementNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginElementNPObject, this); + releaseNPObject(pluginElementNPObject); +} + +void PluginProxy::evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, bool& returnValue, NPVariantData& resultData) +{ + PluginController::PluginDestructionProtector protector(controller()); + + NPVariant npObjectAsVariant = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(npObjectAsVariantData, this); + if (!NPVARIANT_IS_OBJECT(npObjectAsVariant) || !(NPVARIANT_TO_OBJECT(npObjectAsVariant))) { + returnValue = false; + return; + } + + NPVariant result; + returnValue = controller()->evaluate(NPVARIANT_TO_OBJECT(npObjectAsVariant), scriptString, &result, allowPopups); + if (!returnValue) + return; + + // Convert the NPVariant to an NPVariantData. + resultData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(result, this); + + // And release the result. + releaseNPVariantValue(&result); + + releaseNPVariantValue(&npObjectAsVariant); +} + +void PluginProxy::cancelStreamLoad(uint64_t streamID) +{ + controller()->cancelStreamLoad(streamID); +} + +void PluginProxy::cancelManualStreamLoad() +{ + controller()->cancelManualStreamLoad(); +} + +void PluginProxy::setStatusbarText(const String& statusbarText) +{ + controller()->setStatusbarText(statusbarText); +} + +void PluginProxy::update(const IntRect& paintedRect) +{ + if (paintedRect == pluginBounds()) + m_pluginBackingStoreContainsValidData = true; + + if (m_backingStore) { + // Blit the plug-in backing store into our own backing store. + OwnPtr<GraphicsContext> graphicsContext = m_backingStore->createGraphicsContext(); + graphicsContext->applyDeviceScaleFactor(contentsScaleFactor()); + graphicsContext->setCompositeOperation(CompositeCopy); + m_pluginBackingStore->paint(*graphicsContext, contentsScaleFactor(), paintedRect.location(), paintedRect); + } + + // Ask the controller to invalidate the rect for us. + m_waitingForPaintInResponseToUpdate = true; + controller()->invalidate(paintedRect); +} + +} // 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 000000000..d2a538777 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h @@ -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. + */ + +#ifndef PluginProxy_h +#define PluginProxy_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "Connection.h" +#include "Plugin.h" +#include <WebCore/AffineTransform.h> +#include <WebCore/IntRect.h> + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +OBJC_CLASS CALayer; +#endif + +namespace WebCore { + class HTTPHeaderMap; + class ProtectionSpace; +} + +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); + void didReceiveSyncPluginProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + +private: + explicit PluginProxy(const String& pluginPath); + + // Plugin + virtual bool initialize(const Parameters&); + virtual void destroy(); + virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + virtual PassRefPtr<ShareableBitmap> snapshot(); +#if PLATFORM(MAC) + virtual PlatformLayer* pluginLayer(); +#endif + virtual bool isTransparent(); + virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform); + virtual void visibilityDidChange(); + virtual void frameDidFinishLoading(uint64_t requestID); + virtual void frameDidFail(uint64_t requestID, bool wasCancelled); + virtual void didEvaluateJavaScript(uint64_t requestID, 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, const String& suggestedFileName); + 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, const String& suggestedFileName); + 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 handleContextMenuEvent(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 contentsScaleFactorChanged(float); + virtual void privateBrowsingStateChanged(bool); + virtual bool getFormValue(String& formValue); + virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); + virtual WebCore::Scrollbar* horizontalScrollbar(); + virtual WebCore::Scrollbar* verticalScrollbar(); + + float contentsScaleFactor(); + bool needsBackingStore() const; + bool updateBackingStore(); + uint64_t windowNPObjectID(); + WebCore::IntRect pluginBounds(); + + void geometryDidChange(); + + // 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 getAuthenticationInfo(const WebCore::ProtectionSpace&, bool& returnValue, String& username, String& password); + 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 pluginFocusOrWindowFocusChanged(bool); + void setComplexTextInputState(uint64_t); +#endif + + String m_pluginPath; + + RefPtr<PluginProcessConnection> m_connection; + uint64_t m_pluginInstanceID; + + WebCore::IntSize m_pluginSize; + + // The clip rect in plug-in coordinates. + WebCore::IntRect m_clipRect; + + // A transform that can be used to convert from root view coordinates to plug-in coordinates. + WebCore::AffineTransform m_pluginToRootViewTransform; + + // 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 000000000..ce756169a --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in @@ -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. + +#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. The painted rect is in plug-in coordinates. + 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 the authentication info for the given protection space. + GetAuthenticationInfo(WebCore::ProtectionSpace protectionSpace) -> (bool returnValue, WTF::String username, WTF::String password) + + # 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) + # Called when the plug-in's focus or its containing window focus changes. + PluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) + + # Change whether complext text input is enabled for this plug-in. + SetComplexTextInputState(uint64_t complexTextInputState) +#endif +} + +#endif diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp new file mode 100644 index 000000000..5b915dc40 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp @@ -0,0 +1,1244 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginView.h" + +#include "NPRuntimeUtilities.h" +#include "Plugin.h" +#include "ShareableBitmap.h" +#include "WebEvent.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/Chrome.h> +#include <WebCore/CookieJar.h> +#include <WebCore/Credential.h> +#include <WebCore/CredentialStorage.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/MouseEvent.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.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/Page.h> +#include <WebCore/ProtectionSpace.h> +#include <WebCore/ProxyServer.h> +#include <WebCore/RenderEmbeddedObject.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/ResourceLoadScheduler.h> +#include <WebCore/ScriptValue.h> +#include <WebCore/ScrollView.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityPolicy.h> +#include <WebCore/Settings.h> +#include <WebCore/UserGestureIndicator.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, response.suggestedFilename()); +} + +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. + 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->destroyPlugin(); + m_isBeingDestroyed = false; +#if PLATFORM(MAC) + setComplexTextInputState(PluginComplexTextInputDisabled); +#endif + } + + // Invalidate the object map. + m_npRuntimeObjectMap.invalidate(); + + cancelAllStreams(); + + // Null out the plug-in element explicitly so we'll crash earlier if we try to use + // the plug-in view after it's been destroyed. + m_pluginElement = nullptr; +} + +Frame* PluginView::frame() const +{ + 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, response.suggestedFilename()); +} + +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()); +} + +RenderBoxModelObject* PluginView::renderer() const +{ + return toRenderBoxModelObject(m_pluginElement->renderer()); +} + +#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::setDeviceScaleFactor(float scaleFactor) +{ + if (!m_isInitialized || !m_plugin) + return; + + m_plugin->contentsScaleFactorChanged(scaleFactor); +} + +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; + + m_webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(m_parameters.mimeType)); + return; + } + + m_isInitialized = true; + +#if PLATFORM(MAC) + windowAndViewFramesChanged(m_webPage->windowFrameInScreenCoordinates(), m_webPage->viewFrameInWindowCoordinates()); +#endif + + viewGeometryDidChange(); + + redeliverManualStream(); + +#if PLATFORM(MAC) + if (m_plugin->pluginLayer()) { + if (frame()) { + frame()->view()->enterCompositingMode(); + m_pluginElement->setNeedsStyleRecalc(SyntheticStyleChange); + } + } + + 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); +} + +bool PluginView::getFormValue(String& formValue) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return false; + + return m_plugin->getFormValue(formValue); +} + +bool PluginView::scroll(ScrollDirection direction, ScrollGranularity granularity) +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return false; + + return m_plugin->handleScroll(direction, granularity); +} + +Scrollbar* PluginView::horizontalScrollbar() +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return 0; + + return m_plugin->horizontalScrollbar(); +} + +Scrollbar* PluginView::verticalScrollbar() +{ + // The plug-in can be null here if it failed to initialize. + if (!m_isInitialized || !m_plugin) + return 0; + + return m_plugin->verticalScrollbar(); +} + +void PluginView::setFrameRect(const WebCore::IntRect& rect) +{ + Widget::setFrameRect(rect); + viewGeometryDidChange(); +} + +void PluginView::paint(GraphicsContext* context, const IntRect& dirtyRect) +{ + if (!m_plugin || !m_isInitialized) + return; + + if (context->paintingDisabled()) { + if (context->updatingControlTints()) + m_plugin->updateControlTints(context); + return; + } + + // FIXME: We should try to intersect the dirty rect with the plug-in's clip rect here. + IntRect paintRect = IntRect(IntPoint(), frameRect().size()); + + if (paintRect.isEmpty()) + return; + + if (m_snapshot) { + m_snapshot->paint(*context, contentsScaleFactor(), frameRect().location(), m_snapshot->bounds()); + return; + } + + GraphicsContextStateSaver stateSaver(*context); + + // Translate the coordinate system so that the origin is in the top-left corner of the plug-in. + context->translate(frameRect().location().x(), frameRect().location().y()); + + m_plugin->paint(context, paintRect); +} + +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. + + // FIXME: Clicking in a scroll bar should not change focus. + 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().contextmenuEvent && currentEvent->type() == WebEvent::MouseDown) { + // We have a context menu event. + didHandleEvent = m_plugin->handleContextMenuEvent(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::notifyWidget(WidgetNotification notification) +{ + switch (notification) { + case WillPaintFlattened: + if (m_plugin && m_isInitialized) + m_snapshot = m_plugin->snapshot(); + break; + case DidPaintFlattened: + m_snapshot = nullptr; + break; + } +} + +void PluginView::show() +{ + bool wasVisible = isVisible(); + + setSelfVisible(true); + + if (!wasVisible) + viewVisibilityDidChange(); + + Widget::show(); +} + +void PluginView::hide() +{ + bool wasVisible = isVisible(); + + setSelfVisible(false); + + if (wasVisible) + viewVisibilityDidChange(); + + Widget::hide(); +} + +bool PluginView::transformsAffectFrameRect() +{ + return false; +} + +void PluginView::viewGeometryDidChange() +{ + if (!m_isInitialized || !m_plugin || !parent()) + return; + + ASSERT(frame()); + float frameScaleFactor = frame()->frameScaleFactor(); + + IntPoint scaledFrameRectLocation(frameRect().location().x() * frameScaleFactor, frameRect().location().y() * frameScaleFactor); + IntPoint scaledLocationInRootViewCoordinates(parent()->contentsToRootView(scaledFrameRectLocation)); + + // FIXME: We still don't get the right coordinates for transformed plugins. + AffineTransform transform; + transform.translate(scaledLocationInRootViewCoordinates.x(), scaledLocationInRootViewCoordinates.y()); + transform.scale(frameScaleFactor); + + // FIXME: The clip rect isn't correct. + IntRect clipRect = boundsRect(); + m_plugin->geometryDidChange(size(), clipRect, transform); +} + +void PluginView::viewVisibilityDidChange() +{ + if (!m_isInitialized || !m_plugin || !parent()) + return; + + m_plugin->visibilityDidChange(); +} + +IntRect PluginView::clipRectInWindowCoordinates() const +{ + // Get the frame rect in window coordinates. + IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); + + Frame* frame = this->frame(); + + // Get the window clip rect for the enclosing layer (in window coordinates). + RenderLayer* layer = m_pluginElement->renderer()->enclosingLayer(); + IntRect windowClipRect = frame->view()->windowClipRectForLayer(layer, true); + + // Intersect the two rects to get the view clip rect in window coordinates. + frameRectInWindowCoordinates.intersect(windowClipRect); + + return frameRectInWindowCoordinates; +} + +void PluginView::focusPluginElement() +{ + ASSERT(frame()); + + if (Page* page = frame()->page()) + page->focusController()->setFocusedNode(m_pluginElement.get(), frame()); + else + 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; + ScriptValue result = frame->script()->executeScript(jsString, request->allowPopups()); + + // Check if evaluating the JavaScript destroyed the plug-in. + if (!plugin->controller()) + return; + + // Don't notify the plug-in at all about targeted javascript: requests. This matches Mozilla and WebKit1. + if (!request->target().isNull()) + return; + + ScriptState* scriptState = frame->script()->globalObject(pluginWorld())->globalExec(); + String resultString; + result.getString(scriptState, resultString); + + // Send the result back to the plug-in. + plugin->didEvaluateJavaScript(request->requestID(), 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; + +#if PLATFORM(MAC) + if (m_plugin->pluginLayer()) + return; +#endif + + RenderBoxModelObject* renderer = toRenderBoxModelObject(m_pluginElement->renderer()); + if (!renderer) + return; + + IntRect contentRect(dirtyRect); + contentRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop()); + renderer->repaintRectangle(contentRect); +} + +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(); +} + +bool PluginView::isPluginVisible() +{ + return isVisible(); +} + +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); + + String referrer = SecurityPolicy::generateReferrerHeader(frame()->document()->referrerPolicy(), frameLoadRequest.resourceRequest().url(), frame()->loader()->outgoingReferrer()); + if (!referrer.isEmpty()) + frameLoadRequest.resourceRequest().setHTTPReferrer(referrer); + + 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(*pluginWorld()->globalData(), 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(*pluginWorld()->globalData(), object); +} + +bool PluginView::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups) +{ + // FIXME: Is this check necessary? + if (!m_pluginElement->document()->frame()) + return false; + + // Calling evaluate will run JavaScript that can potentially remove the plug-in element, so we need to + // protect the plug-in view from destruction. + NPRuntimeObjectMap::PluginProtector pluginProtector(&m_npRuntimeObjectMap); + + UserGestureIndicator gestureIndicator(allowPopups ? DefinitelyProcessingUserGesture : PossiblyProcessingUserGesture); + return m_npRuntimeObjectMap.evaluate(npObject, scriptString, result); +} + +bool PluginView::tryToShortCircuitInvoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result) +{ + // Never try to short-circuit invoke in the web process. + return false; +} + +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(); + + Widget::invalidate(); +} + +void PluginView::willSendEventToPlugin() +{ + // If we're sending an event to a plug-in, we can't control how long the plug-in + // takes to process it (e.g. it may display a context menu), so we tell the UI process + // to stop the responsiveness timer in this case. + m_webPage->send(Messages::WebPageProxy::StopResponsivenessTimer()); +} + +#if PLATFORM(WIN) +HWND PluginView::nativeParentWindow() +{ + return m_webPage->nativeWindow(); +} + +void PluginView::scheduleWindowedPluginGeometryUpdate(const WindowGeometry& geometry) +{ + m_webPage->drawingArea()->scheduleChildWindowGeometryUpdate(geometry); +} +#endif + +#if PLATFORM(MAC) +void PluginView::pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) +{ + m_webPage->send(Messages::WebPageProxy::PluginFocusOrWindowFocusChanged(m_plugin->pluginComplexTextInputIdentifier(), pluginHasFocusAndWindowHasFocus)); +} + +void PluginView::setComplexTextInputState(PluginComplexTextInputState pluginComplexTextInputState) +{ + m_webPage->send(Messages::WebPageProxy::SetPluginComplexTextInputState(m_plugin->pluginComplexTextInputIdentifier(), pluginComplexTextInputState)); +} + +mach_port_t PluginView::compositingRenderServerPort() +{ + return WebProcess::shared().compositingRenderServerPort(); +} +#endif + +float PluginView::contentsScaleFactor() +{ + if (Page* page = frame() ? frame()->page() : 0) + return page->deviceScaleFactor(); + + return 1; +} + +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::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password) +{ + Credential credential = CredentialStorage::get(protectionSpace); + if (credential.isEmpty()) + credential = CredentialStorage::getFromPersistentStorage(protectionSpace); + + if (!credential.hasPassword()) + return false; + + username = credential.user(); + password = credential.password(); + + return true; +} + +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::protectPluginFromDestruction() +{ + if (!m_isBeingDestroyed) + ref(); +} + +static void derefPluginView(PluginView* pluginView) +{ + pluginView->deref(); +} + +void PluginView::unprotectPluginFromDestruction() +{ + if (m_isBeingDestroyed) + return; + + // A plug-in may ask us to evaluate JavaScript that removes the plug-in from the + // page, but expect the object to still be alive when the call completes. Flash, + // for example, may crash if the plug-in is destroyed and we return to code for + // the destroyed object higher on the stack. To prevent this, if the plug-in has + // only one remaining reference, call deref() asynchronously. + if (hasOneRef()) + RunLoop::main()->dispatch(bind(derefPluginView, this)); + else + deref(); +} + +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 000000000..9624ac954 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.h @@ -0,0 +1,214 @@ +/* + * 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, public PluginController, private WebCore::MediaCanStartListener, private WebFrame::LoadListener { +public: + static PassRefPtr<PluginView> create(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters&); + + WebCore::Frame* frame() const; + + 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 setDeviceScaleFactor(float); + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); + bool sendComplexTextInput(uint64_t pluginComplexTextInputIdentifier, const String& textInput); +#endif + +#if USE(CG) + RetainPtr<CGPDFDocumentRef> pdfDocumentForPrinting() const { return m_plugin->pdfDocumentForPrinting(); } +#endif + + // FIXME: Remove this; nobody should have to know about the plug-in view's renderer except the plug-in view itself. + WebCore::RenderBoxModelObject* renderer() const; + +private: + PluginView(PassRefPtr<WebCore::HTMLPlugInElement>, PassRefPtr<Plugin>, const Plugin::Parameters& parameters); + virtual ~PluginView(); + + void initializePlugin(); + void destroyPlugin(); + + void viewGeometryDidChange(); + void viewVisibilityDidChange(); + 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); + virtual bool getFormValue(String&); + virtual bool scroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); + virtual WebCore::Scrollbar* horizontalScrollbar(); + virtual WebCore::Scrollbar* verticalScrollbar(); + + // 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*); + virtual void notifyWidget(WebCore::WidgetNotification); + virtual void show(); + virtual void hide(); + virtual bool transformsAffectFrameRect(); + + // WebCore::MediaCanStartListener + virtual void mediaCanStart(); + + // PluginController + virtual bool isPluginVisible(); + 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 bool tryToShortCircuitInvoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result); + virtual void setStatusbarText(const String&); + virtual bool isAcceleratedCompositingEnabled(); + virtual void pluginProcessCrashed(); + virtual void willSendEventToPlugin(); +#if PLATFORM(WIN) + virtual HWND nativeParentWindow(); + virtual void scheduleWindowedPluginGeometryUpdate(const WindowGeometry&); +#endif +#if PLATFORM(MAC) + virtual void pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus); + virtual void setComplexTextInputState(PluginComplexTextInputState); + virtual mach_port_t compositingRenderServerPort(); +#endif + virtual float contentsScaleFactor(); + virtual String proxiesForURL(const String&); + virtual String cookiesForURL(const String&); + virtual void setCookiesForURL(const String& urlString, const String& cookieString); + virtual bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); + virtual bool isPrivateBrowsingEnabled(); + virtual void protectPluginFromDestruction(); + virtual void unprotectPluginFromDestruction(); + + // 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; + + RefPtr<ShareableBitmap> m_snapshot; +}; + +} // namespace WebKit + +#endif // PluginView_h diff --git a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp new file mode 100644 index 000000000..e88696371 --- /dev/null +++ b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp @@ -0,0 +1,138 @@ +/* + * 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 "config.h" +#include "WebResourceCacheManager.h" + +#include "Connection.h" +#include "MessageID.h" +#include "ResourceCachesToClear.h" +#include "SecurityOriginData.h" +#include "WebCoreArgumentCoders.h" +#include "WebResourceCacheManagerProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/MemoryCache.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityOriginHash.h> +#include <wtf/UnusedParam.h> + +using namespace WebCore; + +namespace WebKit { + +WebResourceCacheManager& WebResourceCacheManager::shared() +{ + static WebResourceCacheManager& shared = *new WebResourceCacheManager; + return shared; +} + +WebResourceCacheManager::WebResourceCacheManager() +{ +} + +WebResourceCacheManager::~WebResourceCacheManager() +{ +} + +void WebResourceCacheManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceiveWebResourceCacheManagerMessage(connection, messageID, arguments); +} + + +void WebResourceCacheManager::getCacheOrigins(uint64_t callbackID) const +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + MemoryCache::SecurityOriginSet origins; + memoryCache()->getOriginsWithCache(origins); + +#if USE(CFURLCACHE) + RetainPtr<CFArrayRef> cfURLHosts = cfURLCacheHostNames(); + CFIndex size = cfURLHosts ? CFArrayGetCount(cfURLHosts.get()) : 0; + + String httpString("http"); + for (CFIndex i = 0; i < size; ++i) { + CFStringRef host = static_cast<CFStringRef>(CFArrayGetValueAtIndex(cfURLHosts.get(), i)); + origins.add(SecurityOrigin::create(httpString, host, 0)); + } +#endif + + // Create a list with the origins in both of the caches. + Vector<SecurityOriginData> identifiers; + identifiers.reserveCapacity(origins.size()); + + MemoryCache::SecurityOriginSet::iterator end = origins.end(); + for (MemoryCache::SecurityOriginSet::iterator it = origins.begin(); it != end; ++it) { + RefPtr<SecurityOrigin> origin = *it; + + SecurityOriginData originData; + originData.protocol = origin->protocol(); + originData.host = origin->host(); + originData.port = origin->port(); + + identifiers.uncheckedAppend(originData); + } + + WebProcess::shared().connection()->send(Messages::WebResourceCacheManagerProxy::DidGetCacheOrigins(identifiers, callbackID), 0); +} + +void WebResourceCacheManager::clearCacheForOrigin(SecurityOriginData originData, uint32_t cachesToClear) const +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + +#if USE(CFURLCACHE) + ResourceCachesToClear resourceCachesToClear = static_cast<ResourceCachesToClear>(cachesToClear); +#else + UNUSED_PARAM(cachesToClear); +#endif + + RefPtr<SecurityOrigin> origin = SecurityOrigin::create(originData.protocol, originData.host, originData.port); + if (!origin) + return; + + memoryCache()->removeResourcesWithOrigin(origin.get()); + +#if USE(CFURLCACHE) + if (resourceCachesToClear != InMemoryResourceCachesOnly) { + RetainPtr<CFMutableArrayRef> hostArray(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); + RetainPtr<CFStringRef> host(AdoptCF, origin->host().createCFString()); + CFArrayAppendValue(hostArray.get(), host.get()); + + clearCFURLCacheForHostNames(hostArray.get()); + } +#endif +} + +void WebResourceCacheManager::clearCacheForAllOrigins(uint32_t cachesToClear) const +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + ResourceCachesToClear resourceCachesToClear = static_cast<ResourceCachesToClear>(cachesToClear); + + WebProcess::shared().clearResourceCaches(resourceCachesToClear); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h new file mode 100644 index 000000000..01723894c --- /dev/null +++ b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h @@ -0,0 +1,71 @@ +/* + * 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 WebResourceCacheManager_h +#define WebResourceCacheManager_h + +#include "Arguments.h" +#include "ResourceCachesToClear.h" +#include <wtf/Noncopyable.h> +#include <wtf/RetainPtr.h> +#include <wtf/text/WTFString.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +class MessageID; +} + +namespace WebKit { + +struct SecurityOriginData; + +class WebResourceCacheManager { + WTF_MAKE_NONCOPYABLE(WebResourceCacheManager); +public: + static WebResourceCacheManager& shared(); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + +private: + WebResourceCacheManager(); + virtual ~WebResourceCacheManager(); + + // Implemented in generated WebResourceCacheManagerMessageReceiver.cpp + void didReceiveWebResourceCacheManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + void getCacheOrigins(uint64_t callbackID) const; + void clearCacheForOrigin(SecurityOriginData, uint32_t cachesToClear) const; + void clearCacheForAllOrigins(uint32_t cachesToClear) const; + +#if USE(CFURLCACHE) + static RetainPtr<CFArrayRef> cfURLCacheHostNames(); + static void clearCFURLCacheForHostNames(CFArrayRef); +#endif +}; + +} // namespace WebKit + +#endif // WebResourceCacheManager_h diff --git a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in new file mode 100644 index 000000000..336b25301 --- /dev/null +++ b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in @@ -0,0 +1,27 @@ +# 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 -> WebResourceCacheManager { + void GetCacheOrigins(uint64_t callbackID) + void ClearCacheForOrigin(WebKit::SecurityOriginData originIdentifier, uint32_t cachesToClear) + void ClearCacheForAllOrigins(uint32_t cachesToClear) +} diff --git a/Source/WebKit2/WebProcess/ResourceCache/cf/WebResourceCacheManagerCFNet.cpp b/Source/WebKit2/WebProcess/ResourceCache/cf/WebResourceCacheManagerCFNet.cpp new file mode 100644 index 000000000..86372cf9e --- /dev/null +++ b/Source/WebKit2/WebProcess/ResourceCache/cf/WebResourceCacheManagerCFNet.cpp @@ -0,0 +1,58 @@ +/* + * 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 "config.h" +#include "WebResourceCacheManager.h" + +#if USE(CFURLCACHE) + +#if PLATFORM(WIN) +#include <WebKitSystemInterface/WebKitSystemInterface.h> +#elif PLATFORM(MAC) +#include "WebKitSystemInterface.h" +#endif + + +namespace WebKit { + +#if PLATFORM(WIN) +// The Windows version of WKSI defines these functions as capitalized, while the Mac version defines them as lower case. +static inline CFArrayRef WKCFURLCacheCopyAllHostNamesInPersistentStore() { return wkCFURLCacheCopyAllHostNamesInPersistentStore(); } +static inline void WKCFURLCacheDeleteHostNamesInPersistentStore(CFArrayRef hostNames) { return wkCFURLCacheDeleteHostNamesInPersistentStore(hostNames); } +#endif + +RetainPtr<CFArrayRef> WebResourceCacheManager::cfURLCacheHostNames() +{ + return RetainPtr<CFArrayRef>(AdoptCF, WKCFURLCacheCopyAllHostNamesInPersistentStore()); +} + +void WebResourceCacheManager::clearCFURLCacheForHostNames(CFArrayRef hostNames) +{ + WKCFURLCacheDeleteHostNamesInPersistentStore(hostNames); +} + +} // namespace WebKit + +#endif // USE(CFURLCACHE) diff --git a/Source/WebKit2/WebProcess/WebConnectionToUIProcess.cpp b/Source/WebKit2/WebProcess/WebConnectionToUIProcess.cpp new file mode 100644 index 000000000..9a64add1c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebConnectionToUIProcess.cpp @@ -0,0 +1,115 @@ +/* + * 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 "config.h" +#include "WebConnectionToUIProcess.h" + +#include "InjectedBundleUserMessageCoders.h" +#include "WebConnectionMessageKinds.h" +#include "WebProcess.h" + +namespace WebKit { + +PassRefPtr<WebConnectionToUIProcess> WebConnectionToUIProcess::create(WebProcess* process, CoreIPC::Connection::Identifier connectionIdentifier, RunLoop* runLoop) +{ + return adoptRef(new WebConnectionToUIProcess(process, connectionIdentifier, runLoop)); +} + +WebConnectionToUIProcess::WebConnectionToUIProcess(WebProcess* process, CoreIPC::Connection::Identifier connectionIdentifier, RunLoop* runLoop) + : m_process(process) + , m_connection(CoreIPC::Connection::createClientConnection(connectionIdentifier, this, runLoop)) +{ + m_connection->setDidCloseOnConnectionWorkQueueCallback(ChildProcess::didCloseOnConnectionWorkQueue); + m_connection->setShouldExitOnSyncMessageSendFailure(true); +} + +void WebConnectionToUIProcess::invalidate() +{ + m_connection->invalidate(); + m_connection = nullptr; + m_process = 0; +} + +// WebConnection + +void WebConnectionToUIProcess::postMessage(const String& messageName, APIObject* messageBody) +{ + if (!m_process) + return; + + m_connection->deprecatedSend(WebConnectionLegacyMessage::PostMessage, 0, CoreIPC::In(messageName, InjectedBundleUserMessageEncoder(messageBody))); +} + +// CoreIPC::Connection::Client + +void WebConnectionToUIProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (messageID.is<CoreIPC::MessageClassWebConnectionLegacy>()) { + switch (messageID.get<WebConnectionLegacyMessage::Kind>()) { + case WebConnectionLegacyMessage::PostMessage: { + String messageName; + RefPtr<APIObject> messageBody; + InjectedBundleUserMessageDecoder messageDecoder(messageBody); + if (!arguments->decode(CoreIPC::Out(messageName, messageDecoder))) + return; + + forwardDidReceiveMessageToClient(messageName, messageBody.get()); + return; + } + } + return; + } + + m_process->didReceiveMessage(connection, messageID, arguments); +} + +void WebConnectionToUIProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply) +{ + m_process->didReceiveSyncMessage(connection, messageID, arguments, reply); +} + +void WebConnectionToUIProcess::didClose(CoreIPC::Connection* connection) +{ + m_process->didClose(connection); +} + +void WebConnectionToUIProcess::didReceiveInvalidMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID) +{ + m_process->didReceiveInvalidMessage(connection, messageID); +} + +void WebConnectionToUIProcess::syncMessageSendTimedOut(CoreIPC::Connection* connection) +{ + m_process->syncMessageSendTimedOut(connection); +} + +#if PLATFORM(WIN) +Vector<HWND> WebConnectionToUIProcess::windowsToReceiveSentMessagesWhileWaitingForSyncReply() +{ + return m_process->windowsToReceiveSentMessagesWhileWaitingForSyncReply(); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebConnectionToUIProcess.h b/Source/WebKit2/WebProcess/WebConnectionToUIProcess.h new file mode 100644 index 000000000..1d9c96c80 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebConnectionToUIProcess.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 WebConnectionToUIProcess_h +#define WebConnectionToUIProcess_h + +#include "Connection.h" +#include "WebConnection.h" + +namespace WebKit { + +class WebProcess; + +class WebConnectionToUIProcess : public WebConnection, CoreIPC::Connection::Client { +public: + static PassRefPtr<WebConnectionToUIProcess> create(WebProcess*, CoreIPC::Connection::Identifier, RunLoop*); + + CoreIPC::Connection* connection() { return m_connection.get(); } + + void invalidate(); + +private: + WebConnectionToUIProcess(WebProcess*, CoreIPC::Connection::Identifier, RunLoop*); + + // WebConnection + virtual void postMessage(const String&, APIObject*); + + // CoreIPC::Connection::Client + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); +#if PLATFORM(WIN) + virtual Vector<HWND> windowsToReceiveSentMessagesWhileWaitingForSyncReply(); +#endif + + WebProcess* m_process; + RefPtr<CoreIPC::Connection> m_connection; +}; + +} // namespace WebKit + +#endif // WebConnectionToUIProcess_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp new file mode 100644 index 000000000..44c0c002d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp @@ -0,0 +1,786 @@ +/* + * Copyright (C) 2010, 2011 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 "config.h" +#include "WebChromeClient.h" + +#include "DrawingArea.h" +#include "InjectedBundleNavigationAction.h" +#include "InjectedBundleUserMessageCoders.h" +#include "WebContextMenu.h" +#include "WebCoreArgumentCoders.h" +#include "WebFrame.h" +#include "WebFrameLoaderClient.h" +#include "WebFullScreenManager.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 "WebSearchPopupMenu.h" +#include <WebCore/AXObjectCache.h> +#include <WebCore/DatabaseTracker.h> +#include <WebCore/FileChooser.h> +#include <WebCore/FileIconLoader.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoadRequest.h> +#include <WebCore/FrameLoader.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLPlugInImageElement.h> +#include <WebCore/Icon.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/Page.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/Settings.h> + +using namespace WebCore; +using namespace HTMLNames; + +namespace WebKit { + +static double area(WebFrame* frame) +{ + IntSize size = frame->visibleContentBoundsExcludingScrollbars().size(); + return static_cast<double>(size.height()) * size.width(); +} + + +static WebFrame* findLargestFrameInFrameSet(WebPage* page) +{ + // Approximate what a user could consider a default target frame for application menu operations. + + WebFrame* mainFrame = page->mainWebFrame(); + 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()); +} + +void WebChromeClient::focus() +{ + m_page->send(Messages::WebPageProxy::SetFocus(true)); +} + +void WebChromeClient::unfocus() +{ + m_page->send(Messages::WebPageProxy::SetFocus(false)); +} + +#if PLATFORM(MAC) +void WebChromeClient::makeFirstResponder() +{ + m_page->send(Messages::WebPageProxy::MakeFirstResponder()); +} +#endif + +bool WebChromeClient::canTakeFocus(FocusDirection) +{ + notImplemented(); + return true; +} + +void WebChromeClient::takeFocus(FocusDirection direction) +{ + m_page->send(Messages::WebPageProxy::TakeFocus(direction)); +} + +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& request, const WindowFeatures& windowFeatures, const NavigationAction& navigationAction) +{ + uint32_t modifiers = static_cast<uint32_t>(InjectedBundleNavigationAction::modifiersForNavigationAction(navigationAction)); + int32_t mouseButton = static_cast<int32_t>(InjectedBundleNavigationAction::mouseButtonForNavigationAction(navigationAction)); + + uint64_t newPageID = 0; + WebPageCreationParameters parameters; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::CreateNewPage(request.resourceRequest(), 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() +{ + return m_page->canRunModal(); +} + +void WebChromeClient::runModal() +{ + m_page->runModal(); +} + +void WebChromeClient::setToolbarsVisible(bool toolbarsAreVisible) +{ + m_page->send(Messages::WebPageProxy::SetToolbarsAreVisible(toolbarsAreVisible)); +} + +bool WebChromeClient::toolbarsVisible() +{ + WKBundlePageUIElementVisibility toolbarsVisibility = m_page->injectedBundleUIClient().toolbarsAreVisible(m_page); + if (toolbarsVisibility != WKBundlePageUIElementVisibilityUnknown) + return toolbarsVisibility == WKBundlePageUIElementVisible; + + 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() +{ + WKBundlePageUIElementVisibility statusbarVisibility = m_page->injectedBundleUIClient().statusBarIsVisible(m_page); + if (statusbarVisibility != WKBundlePageUIElementVisibilityUnknown) + return statusbarVisibility == WKBundlePageUIElementVisible; + + 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() +{ + WKBundlePageUIElementVisibility menubarVisibility = m_page->injectedBundleUIClient().menuBarIsVisible(m_page); + if (menubarVisibility != WKBundlePageUIElementVisibilityUnknown) + return menubarVisibility == WKBundlePageUIElementVisible; + + 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() +{ + return m_page->canRunBeforeUnloadConfirmPanel(); +} + +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->mainWebFrame()) { + 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); + + unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? CoreIPC::SpinRunLoopWhileWaitingForReply : 0; + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptAlert(webFrame->frameID(), alertText), Messages::WebPageProxy::RunJavaScriptAlert::Reply(), m_page->pageID(), CoreIPC::Connection::DefaultTimeout, syncSendFlags); +} + +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); + + unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? CoreIPC::SpinRunLoopWhileWaitingForReply : 0; + bool result = false; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptConfirm(webFrame->frameID(), message), Messages::WebPageProxy::RunJavaScriptConfirm::Reply(result), m_page->pageID(), CoreIPC::Connection::DefaultTimeout, syncSendFlags)) + 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); + + unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? CoreIPC::SpinRunLoopWhileWaitingForReply : 0; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::RunJavaScriptPrompt(webFrame->frameID(), message, defaultValue), Messages::WebPageProxy::RunJavaScriptPrompt::Reply(result), m_page->pageID(), CoreIPC::Connection::DefaultTimeout, syncSendFlags)) + 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() +{ + bool shouldInterrupt = false; + if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::ShouldInterruptJavaScript(), Messages::WebPageProxy::ShouldInterruptJavaScript::Reply(shouldInterrupt), m_page->pageID())) + return false; + + return shouldInterrupt; +} + +KeyboardUIMode WebChromeClient::keyboardUIMode() +{ + return m_page->keyboardUIMode(); +} + +IntRect WebChromeClient::windowResizerRect() const +{ + return m_page->windowResizerRect(); +} + +void WebChromeClient::invalidateRootView(const IntRect&, bool) +{ + // Do nothing here, there's no concept of invalidating the window in the web process. +} + +void WebChromeClient::invalidateContentsAndRootView(const IntRect& rect, bool) +{ + if (Document* document = m_page->corePage()->mainFrame()->document()) { + if (document->printing()) + return; + } + + m_page->drawingArea()->setNeedsDisplay(rect); +} + +void WebChromeClient::invalidateContentsForSlowScroll(const IntRect& rect, bool) +{ + if (Document* document = m_page->corePage()->mainFrame()->document()) { + if (document->printing()) + return; + } + + m_page->pageDidScroll(); + m_page->drawingArea()->setNeedsDisplay(rect); +} + +void WebChromeClient::scroll(const IntSize& scrollOffset, const IntRect& scrollRect, const IntRect& clipRect) +{ + m_page->pageDidScroll(); + m_page->drawingArea()->scroll(intersection(scrollRect, clipRect), scrollOffset); +} + +#if USE(TILED_BACKING_STORE) +void WebChromeClient::delegatedScrollRequested(const IntPoint& scrollOffset) +{ + m_page->pageDidRequestScroll(scrollOffset); +} +#endif + +IntPoint WebChromeClient::screenToRootView(const IntPoint& point) const +{ + return m_page->screenToWindow(point); +} + +IntRect WebChromeClient::rootViewToScreen(const IntRect& rect) const +{ + return m_page->windowToScreen(rect); +} + +PlatformPageClient WebChromeClient::platformPageClient() const +{ + notImplemented(); + return 0; +} + +void WebChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) const +{ + if (!m_page->corePage()->settings()->frameFlatteningEnabled()) { + WebFrame* largestFrame = findLargestFrameInFrameSet(m_page); + if (largestFrame != m_cachedFrameSetLargestFrame.get()) { + m_cachedFrameSetLargestFrame = largestFrame; + m_page->send(Messages::WebPageProxy::FrameSetLargestFrameChanged(largestFrame ? largestFrame->frameID() : 0)); + } + } + + if (frame->page()->mainFrame() != frame) + return; + +#if PLATFORM(QT) + m_page->send(Messages::WebPageProxy::DidChangeContentsSize(size)); + + if (m_page->useFixedLayout()) + m_page->resizeToContentsIfNeeded(); +#endif + + FrameView* frameView = frame->view(); + if (frameView && !frameView->delegatesScrolling()) { + bool hasHorizontalScrollbar = frameView->horizontalScrollbar(); + bool hasVerticalScrollbar = frameView->verticalScrollbar(); + + if (hasHorizontalScrollbar != m_cachedMainFrameHasHorizontalScrollbar || hasVerticalScrollbar != m_cachedMainFrameHasVerticalScrollbar) { + m_page->send(Messages::WebPageProxy::DidChangeScrollbarsForMainFrame(hasHorizontalScrollbar, hasVerticalScrollbar)); + + m_cachedMainFrameHasHorizontalScrollbar = hasHorizontalScrollbar; + m_cachedMainFrameHasVerticalScrollbar = hasVerticalScrollbar; + } + } +} + +void WebChromeClient::scrollRectIntoView(const IntRect&) 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(), pluginElement->getAttribute(pluginspageAttr))); +} + +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); + + WebHitTestResult::Data webHitTestResultData; + webHitTestResultData.absoluteImageURL = hitTestResult.absoluteImageURL().string(); + webHitTestResultData.absolutePDFURL = hitTestResult.absolutePDFURL().string(); + webHitTestResultData.absoluteLinkURL = hitTestResult.absoluteLinkURL().string(); + webHitTestResultData.absoluteMediaURL = hitTestResult.absoluteMediaURL().string(); + webHitTestResultData.linkLabel = hitTestResult.textContent(); + webHitTestResultData.linkTitle = hitTestResult.titleDisplayString(); + + // Notify the UIProcess. + m_page->send(Messages::WebPageProxy::MouseDidMoveOverElement(webHitTestResultData, 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* frame) +{ + WebFrame* webFrame = static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame(); + m_page->sendSync(Messages::WebPageProxy::PrintFrame(webFrame->frameID()), Messages::WebPageProxy::PrintFrame::Reply()); +} + +#if ENABLE(SQL_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 currentOriginUsage = DatabaseTracker::tracker().usageForOrigin(origin); + uint64_t newQuota = 0; + WebProcess::shared().connection()->sendSync( + Messages::WebPageProxy::ExceededDatabaseQuota(webFrame->frameID(), origin->databaseIdentifier(), databaseName, details.displayName(), currentQuota, currentOriginUsage, details.currentUsage(), details.expectedUsage()), + Messages::WebPageProxy::ExceededDatabaseQuota::Reply(newQuota), m_page->pageID()); + + DatabaseTracker::tracker().setQuota(origin, newQuota); +} +#endif + + +void WebChromeClient::reachedMaxAppCacheSize(int64_t) +{ + notImplemented(); +} + +void WebChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin*, int64_t) +{ + notImplemented(); +} + +#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) +{ + generatedFilename = m_page->injectedBundleUIClient().shouldGenerateFileForUpload(m_page, path); + return !generatedFilename.isNull(); +} + +String WebChromeClient::generateReplacementFile(const String& path) +{ + return m_page->injectedBundleUIClient().generateFileForUpload(m_page, path); +} + +bool WebChromeClient::paintCustomOverhangArea(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect) +{ + if (!m_page->injectedBundleUIClient().shouldPaintCustomOverhangArea()) + return false; + + m_page->injectedBundleUIClient().paintCustomOverhangArea(m_page, context, horizontalOverhangArea, verticalOverhangArea, dirtyRect); + return true; +} + +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())); + m_page->send(Messages::WebPageProxy::RunOpenPanel(static_cast<WebFrameLoaderClient*>(frame->loader()->client())->webFrame()->frameID(), fileChooser->settings())); +} + +void WebChromeClient::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader) +{ + loader->notifyFinished(Icon::createIconForFiles(filenames)); +} + +void WebChromeClient::setCursor(const WebCore::Cursor& cursor) +{ +#if USE(LAZY_NATIVE_CURSOR) + m_page->send(Messages::WebPageProxy::SetCursor(cursor)); +#endif +} + +void WebChromeClient::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) +{ + m_page->send(Messages::WebPageProxy::SetCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves)); +} + +void WebChromeClient::formStateDidChange(const Node*) +{ + notImplemented(); +} + +bool WebChromeClient::selectItemWritingDirectionIsNatural() +{ +#if PLATFORM(WIN) + return true; +#else + return false; +#endif +} + +bool WebChromeClient::selectItemAlignmentFollowsMenuWritingDirection() +{ +#if PLATFORM(WIN) + return false; +#else + return true; +#endif +} + +bool WebChromeClient::hasOpenedPopup() const +{ + notImplemented(); + return false; +} + +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 + +#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(TOUCH_EVENTS) +void WebChromeClient::needTouchEvents(bool needTouchEvents) +{ + m_page->send(Messages::WebPageProxy::NeedTouchEvents(needTouchEvents)); +} +#endif + +#if PLATFORM(WIN) +void WebChromeClient::setLastSetCursorToCurrentCursor() +{ +} +#endif + +#if ENABLE(FULLSCREEN_API) +bool WebChromeClient::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard) +{ + return m_page->fullScreenManager()->supportsFullScreen(withKeyboard); +} + +void WebChromeClient::enterFullScreenForElement(WebCore::Element* element) +{ + m_page->fullScreenManager()->enterFullScreenForElement(element); +} + +void WebChromeClient::exitFullScreenForElement(WebCore::Element* element) +{ + m_page->fullScreenManager()->exitFullScreenForElement(element); +} + +void WebChromeClient::setRootFullScreenLayer(GraphicsLayer* layer) +{ + m_page->fullScreenManager()->setRootFullScreenLayer(layer); +} + +#endif + +void WebChromeClient::dispatchViewportPropertiesDidChange(const ViewportArguments& args) const +{ + m_page->send(Messages::WebPageProxy::DidChangeViewportProperties(args)); + +#if USE(TILED_BACKING_STORE) + // When viewport properties change, recalculate and set the new recommended layout size in case of fixed layout rendering. + // Viewport properties have no impact on zero sized fixed viewports. + if (m_page->useFixedLayout() && !m_page->viewportSize().isEmpty()) { + Settings* settings = m_page->corePage()->settings(); + + int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), m_page->viewportSize().width()); + + IntSize targetLayoutSize = computeViewportAttributes(m_page->corePage()->viewportArguments(), + minimumLayoutFallbackWidth, settings->deviceWidth(), settings->deviceHeight(), + settings->deviceDPI(), m_page->viewportSize()).layoutSize; + m_page->setResizesToContentsUsingLayoutSize(targetLayoutSize); + } +#endif +} + +void WebChromeClient::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb) +{ + m_page->send(Messages::WebPageProxy::NotifyScrollerThumbIsVisibleInRect(scrollerThumb)); +} + +void WebChromeClient::recommendedScrollbarStyleDidChange(int32_t newStyle) +{ + m_page->send(Messages::WebPageProxy::RecommendedScrollbarStyleDidChange(newStyle)); +} + +bool WebChromeClient::shouldRubberBandInDirection(WebCore::ScrollDirection direction) const +{ + ASSERT(direction != WebCore::ScrollUp && direction != WebCore::ScrollDown); + + if (direction == WebCore::ScrollLeft) + return m_page->injectedBundleUIClient().shouldRubberBandInDirection(m_page, WKScrollDirectionLeft); + if (direction == WebCore::ScrollRight) + return m_page->injectedBundleUIClient().shouldRubberBandInDirection(m_page, WKScrollDirectionRight); + + ASSERT_NOT_REACHED(); + return true; +} + +void WebChromeClient::numWheelEventHandlersChanged(unsigned count) +{ + m_page->send(Messages::WebPageProxy::NumWheelEventHandlersChanged(count)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h new file mode 100644 index 000000000..fa364cd72 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h @@ -0,0 +1,224 @@ +/* + * 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_cachedMainFrameHasHorizontalScrollbar(false) + , m_cachedMainFrameHasVerticalScrollbar(false) + , m_page(page) + { + } + + WebPage* page() const { return m_page; } + + virtual void* webView() const { return 0; } + +private: + virtual void chromeDestroyed() OVERRIDE; + + virtual void setWindowRect(const WebCore::FloatRect&) OVERRIDE; + virtual WebCore::FloatRect windowRect() OVERRIDE; + + virtual WebCore::FloatRect pageRect() OVERRIDE; + + virtual void focus() OVERRIDE; + virtual void unfocus() OVERRIDE; + + virtual bool canTakeFocus(WebCore::FocusDirection) OVERRIDE; + virtual void takeFocus(WebCore::FocusDirection) OVERRIDE; + + virtual void focusedNodeChanged(WebCore::Node*) OVERRIDE; + virtual void focusedFrameChanged(WebCore::Frame*) OVERRIDE; + + // 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&) OVERRIDE; + virtual void show() OVERRIDE; + + virtual bool canRunModal() OVERRIDE; + virtual void runModal() OVERRIDE; + + virtual void setToolbarsVisible(bool) OVERRIDE; + virtual bool toolbarsVisible() OVERRIDE; + + virtual void setStatusbarVisible(bool) OVERRIDE; + virtual bool statusbarVisible() OVERRIDE; + + virtual void setScrollbarsVisible(bool) OVERRIDE; + virtual bool scrollbarsVisible() OVERRIDE; + + virtual void setMenubarVisible(bool) OVERRIDE; + virtual bool menubarVisible() OVERRIDE; + + virtual void setResizable(bool) OVERRIDE; + + virtual void addMessageToConsole(WebCore::MessageSource, WebCore::MessageType, WebCore::MessageLevel, const String& message, unsigned int lineNumber, const String& sourceID) OVERRIDE; + + virtual bool canRunBeforeUnloadConfirmPanel() OVERRIDE; + virtual bool runBeforeUnloadConfirmPanel(const String& message, WebCore::Frame*) OVERRIDE; + + virtual void closeWindowSoon() OVERRIDE; + + virtual void runJavaScriptAlert(WebCore::Frame*, const String&) OVERRIDE; + virtual bool runJavaScriptConfirm(WebCore::Frame*, const String&) OVERRIDE; + virtual bool runJavaScriptPrompt(WebCore::Frame*, const String& message, const String& defaultValue, String& result) OVERRIDE; + virtual void setStatusbarText(const String&) OVERRIDE; + virtual bool shouldInterruptJavaScript() OVERRIDE; + + virtual WebCore::KeyboardUIMode keyboardUIMode() OVERRIDE; + + virtual WebCore::IntRect windowResizerRect() const OVERRIDE; + + // HostWindow member function overrides. + virtual void invalidateRootView(const WebCore::IntRect&, bool) OVERRIDE; + virtual void invalidateContentsAndRootView(const WebCore::IntRect&, bool) OVERRIDE; + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool) OVERRIDE; + virtual void scroll(const WebCore::IntSize& scrollOffset, const WebCore::IntRect& scrollRect, const WebCore::IntRect& clipRect) OVERRIDE; +#if USE(TILED_BACKING_STORE) + virtual void delegatedScrollRequested(const WebCore::IntPoint& scrollOffset) OVERRIDE; +#endif + virtual WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) const OVERRIDE; + virtual WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) const OVERRIDE; + virtual PlatformPageClient platformPageClient() const OVERRIDE; + virtual void contentsSizeChanged(WebCore::Frame*, const WebCore::IntSize&) const OVERRIDE; + virtual void scrollRectIntoView(const WebCore::IntRect&) const OVERRIDE; // Currently only Mac has a non empty implementation. + + virtual bool shouldMissingPluginMessageBeButton() const OVERRIDE; + virtual void missingPluginButtonClicked(WebCore::Element*) const OVERRIDE; + + virtual void scrollbarsModeDidChange() const OVERRIDE; + virtual void mouseDidMoveOverElement(const WebCore::HitTestResult&, unsigned modifierFlags) OVERRIDE; + + virtual void setToolTip(const String&, WebCore::TextDirection) OVERRIDE; + + virtual void print(WebCore::Frame*) OVERRIDE; + +#if ENABLE(SQL_DATABASE) + virtual void exceededDatabaseQuota(WebCore::Frame*, const String& databaseName) OVERRIDE; +#endif + + virtual void reachedMaxAppCacheSize(int64_t spaceNeeded) OVERRIDE; + virtual void reachedApplicationCacheOriginQuota(WebCore::SecurityOrigin*, int64_t spaceNeeded) OVERRIDE; + +#if ENABLE(DASHBOARD_SUPPORT) + virtual void dashboardRegionsChanged() OVERRIDE; +#endif + + virtual void populateVisitedLinks() OVERRIDE; + + virtual WebCore::FloatRect customHighlightRect(WebCore::Node*, const WTF::AtomicString& type, const WebCore::FloatRect& lineRect) OVERRIDE; + virtual void paintCustomHighlight(WebCore::Node*, const AtomicString& type, const WebCore::FloatRect& boxRect, const WebCore::FloatRect& lineRect, + bool behindText, bool entireLine) OVERRIDE; + + virtual bool shouldReplaceWithGeneratedFileForUpload(const String& path, String& generatedFilename) OVERRIDE; + virtual String generateReplacementFile(const String& path) OVERRIDE; + + virtual bool paintCustomOverhangArea(WebCore::GraphicsContext*, const WebCore::IntRect&, const WebCore::IntRect&, const WebCore::IntRect&) OVERRIDE; + + // 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*) OVERRIDE; + virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*) OVERRIDE; + + virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>) OVERRIDE; + virtual void loadIconForFiles(const Vector<String>&, WebCore::FileIconLoader*) OVERRIDE; + + virtual void setCursor(const WebCore::Cursor&) OVERRIDE; + virtual void setCursorHiddenUntilMouseMoves(bool) OVERRIDE; + + // 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*) OVERRIDE; + + virtual bool selectItemWritingDirectionIsNatural() OVERRIDE; + virtual bool selectItemAlignmentFollowsMenuWritingDirection() OVERRIDE; + virtual bool hasOpenedPopup() const OVERRIDE; + virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const OVERRIDE; + virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const OVERRIDE; + +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() OVERRIDE; +#endif + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*) OVERRIDE; + virtual void setNeedsOneShotDrawingSynchronization() OVERRIDE; + virtual void scheduleCompositingLayerSync() OVERRIDE; +#endif + +#if ENABLE(TOUCH_EVENTS) + virtual void needTouchEvents(bool) OVERRIDE; +#endif + +#if PLATFORM(WIN) + virtual void setLastSetCursorToCurrentCursor() OVERRIDE; +#endif + +#if ENABLE(FULLSCREEN_API) + virtual bool supportsFullScreenForElement(const WebCore::Element*, bool withKeyboard) OVERRIDE; + virtual void enterFullScreenForElement(WebCore::Element*) OVERRIDE; + virtual void exitFullScreenForElement(WebCore::Element*) OVERRIDE; + virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*) OVERRIDE; +#endif + +#if PLATFORM(MAC) + virtual void makeFirstResponder() OVERRIDE; +#endif + + virtual void dispatchViewportPropertiesDidChange(const WebCore::ViewportArguments&) const OVERRIDE; + + virtual void notifyScrollerThumbIsVisibleInRect(const WebCore::IntRect&) OVERRIDE; + virtual void recommendedScrollbarStyleDidChange(int32_t newStyle) OVERRIDE; + virtual bool shouldRubberBandInDirection(WebCore::ScrollDirection) const OVERRIDE; + + virtual void numWheelEventHandlersChanged(unsigned) OVERRIDE; + + String m_cachedToolTip; + mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame; + mutable bool m_cachedMainFrameHasHorizontalScrollbar; + mutable bool m_cachedMainFrameHasVerticalScrollbar; + + 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 000000000..b2cdbcc31 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebContextMenuClient.h" + +#include "WebContextMenuItemData.h" +#include "WebPage.h" +#include <WebCore/ContextMenu.h> +#include <WebCore/Frame.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/Page.h> +#include <WebCore/UserGestureIndicator.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) +{ + // FIXME: this should use NSPerformService on Mac to support the system default search provider. + + 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, MaybeSendReferrer); + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebContextMenuClient.h new file mode 100644 index 000000000..b437245c0 --- /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>) OVERRIDE; +#else + virtual WebCore::PlatformMenuDescription getCustomMenuFromDefaultItems(WebCore::ContextMenu*) OVERRIDE; +#endif + virtual void contextMenuItemSelected(WebCore::ContextMenuItem*, const WebCore::ContextMenu*) OVERRIDE; + + virtual void downloadURL(const WebCore::KURL&) OVERRIDE; + virtual void searchWithGoogle(const WebCore::Frame*) OVERRIDE; + virtual void lookUpInDictionary(WebCore::Frame*) OVERRIDE; + virtual bool isSpeaking() OVERRIDE; + virtual void speak(const String&) OVERRIDE; + virtual void stopSpeaking() OVERRIDE; + +#if PLATFORM(MAC) + virtual void searchWithSpotlight() OVERRIDE; +#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 000000000..6104a50eb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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; +} + +void WebDatabaseManager::initialize(const String& databaseDirectory) +{ + DatabaseTracker::initializeTracker(databaseDirectory); +} + +WebDatabaseManager::WebDatabaseManager() +{ + 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 +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + // 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 +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + 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 +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); + if (!origin) + return; + + DatabaseTracker::tracker().deleteDatabase(origin.get(), databaseIdentifier); +} + +void WebDatabaseManager::deleteDatabasesForOrigin(const String& originIdentifier) const +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); + if (!origin) + return; + + DatabaseTracker::tracker().deleteOrigin(origin.get()); +} + +void WebDatabaseManager::deleteAllDatabases() const +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + DatabaseTracker::tracker().deleteAllDatabases(); +} + +void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const +{ + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + // 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 000000000..18fc8f936 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.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 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(); + static void initialize(const String& databaseDirectory); + + void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + void setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const; + +public: + void deleteAllDatabases() const; + +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; + + // WebCore::DatabaseTrackerClient + virtual void dispatchDidModifyOrigin(WebCore::SecurityOrigin*) OVERRIDE; + virtual void dispatchDidModifyDatabase(WebCore::SecurityOrigin*, const String& databaseIdentifier) OVERRIDE; +}; + +} // 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 000000000..e928ef654 --- /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 000000000..736de2177 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp @@ -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. + */ + +#include "config.h" +#include "WebDragClient.h" + +#include "WebPage.h" + +using namespace WebCore; + +namespace WebKit { + +void WebDragClient::willPerformDragDestinationAction(DragDestinationAction action, DragData*) +{ + if (action == DragDestinationActionLoad) + m_page->willPerformLoadDragDestinationAction(); +} + +void WebDragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) +{ +} + +DragDestinationAction WebDragClient::actionMaskForDrag(DragData*) +{ + return DragDestinationActionAny; +} + +DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint& windowPoint) +{ + return DragSourceActionAny; +} + +#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(QT) && !PLATFORM(GTK) +void WebDragClient::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) +{ +} +#endif + +#if !PLATFORM(MAC) +void WebDragClient::dragEnded() +{ +} +#endif + +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 000000000..f0109fddb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.h @@ -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. + */ + +#ifndef WebDragClient_h +#define WebDragClient_h + +#include <WebCore/DragClient.h> + +#if PLATFORM(MAC) +#ifdef __OBJC__ +@class WKPasteboardFilePromiseOwner; +@class WKPasteboardOwner; +#else +class WKPasteboardFilePromiseOwner; +class WKPasteboardOwner; +#endif +#endif + +namespace WebKit { + +class WebPage; + +class WebDragClient : public WebCore::DragClient { +public: + WebDragClient(WebPage* page) + : m_page(page) + { + } + +private: + virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*) OVERRIDE; + virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*) OVERRIDE; + virtual WebCore::DragDestinationAction actionMaskForDrag(WebCore::DragData*) OVERRIDE; + virtual WebCore::DragSourceAction dragSourceActionMaskForPoint(const WebCore::IntPoint& windowPoint) OVERRIDE; + + virtual void startDrag(WebCore::DragImageRef, const WebCore::IntPoint& dragImageOrigin, const WebCore::IntPoint& eventPos, WebCore::Clipboard*, WebCore::Frame*, bool linkDrag = false) OVERRIDE; + +#if PLATFORM(MAC) + virtual void declareAndWriteDragImage(NSPasteboard*, DOMElement*, NSURL*, NSString*, WebCore::Frame*) OVERRIDE; +#endif + + virtual void dragEnded() OVERRIDE; + + virtual void dragControllerDestroyed() OVERRIDE; + + WebPage* m_page; + +#if PLATFORM(MAC) + RetainPtr<WKPasteboardFilePromiseOwner> m_filePromiseOwner; + RetainPtr<WKPasteboardOwner> m_pasteboardOwner; +#endif +}; + +} // 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 000000000..1e3986475 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.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. + */ + +#include "config.h" +#include "WebEditorClient.h" + +#include "EditorState.h" +#include "WebCoreArgumentCoders.h" +#include "WebFrameLoaderClient.h" +#include "WebPage.h" +#include "WebPageProxy.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/ArchiveResource.h> +#include <WebCore/DocumentFragment.h> +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLInputElement.h> +#include <WebCore/HTMLNames.h> +#include <WebCore/HTMLTextAreaElement.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/Page.h> +#include <WebCore/TextIterator.h> +#include <WebCore/UndoStep.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::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? + DEFINE_STATIC_LOCAL(String, WebViewDidBeginEditingNotification, ("WebViewDidBeginEditingNotification")); + m_page->injectedBundleEditorClient().didBeginEditing(m_page, WebViewDidBeginEditingNotification.impl()); + notImplemented(); +} + +void WebEditorClient::respondToChangedContents() +{ + DEFINE_STATIC_LOCAL(String, WebViewDidChangeNotification, ("WebViewDidChangeNotification")); + m_page->injectedBundleEditorClient().didChange(m_page, WebViewDidChangeNotification.impl()); + notImplemented(); +} + +void WebEditorClient::respondToChangedSelection(Frame* frame) +{ + DEFINE_STATIC_LOCAL(String, WebViewDidChangeSelectionNotification, ("WebViewDidChangeSelectionNotification")); + m_page->injectedBundleEditorClient().didChangeSelection(m_page, WebViewDidChangeSelectionNotification.impl()); + if (!frame) + return; + + EditorState state = m_page->editorState(); + +#if PLATFORM(QT) + if (Element* scope = frame->selection()->rootEditableElement()) + m_page->send(Messages::WebPageProxy::FocusEditableArea(state.microFocus, scope->getRect())); +#endif + + m_page->send(Messages::WebPageProxy::EditorStateChanged(state)); + +#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() +{ + DEFINE_STATIC_LOCAL(String, WebViewDidEndEditingNotification, ("WebViewDidEndEditingNotification")); + m_page->injectedBundleEditorClient().didEndEditing(m_page, WebViewDidEndEditingNotification.impl()); + notImplemented(); +} + +void WebEditorClient::didWriteSelectionToPasteboard() +{ + notImplemented(); +} + +void WebEditorClient::didSetSelectionTypesForPasteboard() +{ + notImplemented(); +} + +void WebEditorClient::registerUndoStep(PassRefPtr<UndoStep> step) +{ + // FIXME: Add assertion that the command being reapplied is the same command that is + // being passed to us. + if (m_page->isInRedo()) + return; + + RefPtr<WebUndoStep> webStep = WebUndoStep::create(step); + m_page->addWebUndoStep(webStep->stepID(), webStep.get()); + uint32_t editAction = static_cast<uint32_t>(webStep->step()->editingAction()); + + m_page->send(Messages::WebPageProxy::RegisterEditCommandForUndo(webStep->stepID(), editAction)); +} + +void WebEditorClient::registerRedoStep(PassRefPtr<UndoStep>) +{ +} + +void WebEditorClient::clearUndoRedoOperations() +{ + m_page->send(Messages::WebPageProxy::ClearAllEditCommands()); +} + +bool WebEditorClient::canCopyCut(Frame*, bool defaultValue) const +{ + return defaultValue; +} + +bool WebEditorClient::canPaste(Frame*, bool defaultValue) const +{ + return defaultValue; +} + +bool WebEditorClient::canUndo() const +{ + bool result = false; + m_page->sendSync(Messages::WebPageProxy::CanUndoRedo(static_cast<uint32_t>(WebPageProxy::Undo)), Messages::WebPageProxy::CanUndoRedo::Reply(result)); + return result; +} + +bool WebEditorClient::canRedo() const +{ + bool result = false; + m_page->sendSync(Messages::WebPageProxy::CanUndoRedo(static_cast<uint32_t>(WebPageProxy::Redo)), Messages::WebPageProxy::CanUndoRedo::Reply(result)); + return result; +} + +void WebEditorClient::undo() +{ + bool result = false; + m_page->sendSync(Messages::WebPageProxy::ExecuteUndoRedo(static_cast<uint32_t>(WebPageProxy::Undo)), Messages::WebPageProxy::ExecuteUndoRedo::Reply(result)); +} + +void WebEditorClient::redo() +{ + bool result = false; + m_page->sendSync(Messages::WebPageProxy::ExecuteUndoRedo(static_cast<uint32_t>(WebPageProxy::Redo)), Messages::WebPageProxy::ExecuteUndoRedo::Reply(result)); +} + +#if !PLATFORM(GTK) && !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* text, int length, int* misspellingLocation, int* misspellingLength) +{ + int32_t resultLocation = -1; + int32_t resultLength = 0; + // FIXME: It would be nice if we wouldn't have to copy the text here. + m_page->sendSync(Messages::WebPageProxy::CheckSpellingOfString(String(text, length)), + Messages::WebPageProxy::CheckSpellingOfString::Reply(resultLocation, resultLength)); + *misspellingLocation = resultLocation; + *misspellingLength = resultLength; +} + +String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&) +{ + notImplemented(); + return String(); +} + +void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<WebCore::GrammarDetail>& grammarDetails, int* badGrammarLocation, int* badGrammarLength) +{ + int32_t resultLocation = -1; + int32_t resultLength = 0; + // FIXME: It would be nice if we wouldn't have to copy the text here. + m_page->sendSync(Messages::WebPageProxy::CheckGrammarOfString(String(text, length)), + Messages::WebPageProxy::CheckGrammarOfString::Reply(grammarDetails, resultLocation, resultLength)); + *badGrammarLocation = resultLocation; + *badGrammarLength = resultLength; +} + +void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail) +{ + m_page->send(Messages::WebPageProxy::UpdateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail)); +} + +void WebEditorClient::updateSpellingUIWithMisspelledWord(const String& misspelledWord) +{ + m_page->send(Messages::WebPageProxy::UpdateSpellingUIWithMisspelledWord(misspelledWord)); +} + +void WebEditorClient::showSpellingUI(bool) +{ + notImplemented(); +} + +bool WebEditorClient::spellingUIIsShowing() +{ + bool isShowing = false; + m_page->sendSync(Messages::WebPageProxy::SpellingUIIsShowing(), Messages::WebPageProxy::SpellingUIIsShowing::Reply(isShowing)); + return isShowing; +} + +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, WebCore::TextCheckingTypeMask, 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 000000000..666427598 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h @@ -0,0 +1,155 @@ +/* + * 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> +#include <WebCore/TextCheckerClient.h> + +namespace WebKit { + +class WebPage; + +class WebEditorClient : public WebCore::EditorClient, public WebCore::TextCheckerClient { +public: + WebEditorClient(WebPage* page) + : m_page(page) + { + } + +private: + virtual void pageDestroyed() OVERRIDE; + + virtual bool shouldDeleteRange(WebCore::Range*) OVERRIDE; + virtual bool shouldShowDeleteInterface(WebCore::HTMLElement*) OVERRIDE; + virtual bool smartInsertDeleteEnabled() OVERRIDE; + virtual bool isSelectTrailingWhitespaceEnabled() OVERRIDE; + virtual bool isContinuousSpellCheckingEnabled() OVERRIDE; + virtual void toggleContinuousSpellChecking() OVERRIDE; + virtual bool isGrammarCheckingEnabled() OVERRIDE; + virtual void toggleGrammarChecking() OVERRIDE; + virtual int spellCheckerDocumentTag() OVERRIDE; + + virtual bool shouldBeginEditing(WebCore::Range*) OVERRIDE; + virtual bool shouldEndEditing(WebCore::Range*) OVERRIDE; + virtual bool shouldInsertNode(WebCore::Node*, WebCore::Range*, WebCore::EditorInsertAction) OVERRIDE; + virtual bool shouldInsertText(const String&, WebCore::Range*, WebCore::EditorInsertAction) OVERRIDE; + virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity, bool stillSelecting) OVERRIDE; + + virtual bool shouldApplyStyle(WebCore::CSSStyleDeclaration*, WebCore::Range*) OVERRIDE; + virtual bool shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*) OVERRIDE; + + virtual void didBeginEditing() OVERRIDE; + virtual void respondToChangedContents() OVERRIDE; + virtual void respondToChangedSelection(WebCore::Frame*) OVERRIDE; + virtual void didEndEditing() OVERRIDE; + virtual void didWriteSelectionToPasteboard() OVERRIDE; + virtual void didSetSelectionTypesForPasteboard() OVERRIDE; + + virtual void registerUndoStep(PassRefPtr<WebCore::UndoStep>) OVERRIDE; + virtual void registerRedoStep(PassRefPtr<WebCore::UndoStep>) OVERRIDE; + virtual void clearUndoRedoOperations() OVERRIDE; + + virtual bool canCopyCut(WebCore::Frame*, bool defaultValue) const OVERRIDE; + virtual bool canPaste(WebCore::Frame*, bool defaultValue) const OVERRIDE; + virtual bool canUndo() const OVERRIDE; + virtual bool canRedo() const OVERRIDE; + + virtual void undo() OVERRIDE; + virtual void redo() OVERRIDE; + + virtual void handleKeyboardEvent(WebCore::KeyboardEvent*) OVERRIDE; + virtual void handleInputMethodKeydown(WebCore::KeyboardEvent*) OVERRIDE; + + virtual void textFieldDidBeginEditing(WebCore::Element*) OVERRIDE; + virtual void textFieldDidEndEditing(WebCore::Element*) OVERRIDE; + virtual void textDidChangeInTextField(WebCore::Element*) OVERRIDE; + virtual bool doTextFieldCommandFromEvent(WebCore::Element*, WebCore::KeyboardEvent*) OVERRIDE; + virtual void textWillBeDeletedInTextField(WebCore::Element*) OVERRIDE; + virtual void textDidChangeInTextArea(WebCore::Element*) OVERRIDE; + +#if PLATFORM(MAC) + virtual NSString *userVisibleString(NSURL *) OVERRIDE; + virtual WebCore::DocumentFragment* documentFragmentFromAttributedString(NSAttributedString *, Vector< RefPtr<WebCore::ArchiveResource> >&) OVERRIDE; + virtual void setInsertionPasteboard(NSPasteboard *) OVERRIDE; + virtual NSURL* canonicalizeURL(NSURL*) OVERRIDE; + virtual NSURL* canonicalizeURLString(NSString*) OVERRIDE; +#endif + +#if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) + virtual void uppercaseWord() OVERRIDE; + virtual void lowercaseWord() OVERRIDE; + virtual void capitalizeWord() OVERRIDE; + virtual void showSubstitutionsPanel(bool show) OVERRIDE; + virtual bool substitutionsPanelIsShowing() OVERRIDE; + virtual void toggleSmartInsertDelete() OVERRIDE; + virtual bool isAutomaticQuoteSubstitutionEnabled() OVERRIDE; + virtual void toggleAutomaticQuoteSubstitution() OVERRIDE; + virtual bool isAutomaticLinkDetectionEnabled() OVERRIDE; + virtual void toggleAutomaticLinkDetection() OVERRIDE; + virtual bool isAutomaticDashSubstitutionEnabled() OVERRIDE; + virtual void toggleAutomaticDashSubstitution() OVERRIDE; + virtual bool isAutomaticTextReplacementEnabled() OVERRIDE; + virtual void toggleAutomaticTextReplacement() OVERRIDE; + virtual bool isAutomaticSpellingCorrectionEnabled() OVERRIDE; + virtual void toggleAutomaticSpellingCorrection() OVERRIDE; +#endif + +#if PLATFORM(GTK) + bool executePendingEditorCommands(WebCore::Frame*, Vector<WTF::String>, bool) OVERRIDE; + void getEditorCommandsForKeyEvent(const WebCore::KeyboardEvent*, Vector<WTF::String>&) OVERRIDE; +#endif + + TextCheckerClient* textChecker() OVERRIDE { return this; } + + virtual void ignoreWordInSpellDocument(const String&) OVERRIDE; + virtual void learnWord(const String&) OVERRIDE; + virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) OVERRIDE; + virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) OVERRIDE; + virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) OVERRIDE; +#if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD) + virtual void checkTextOfParagraph(const UChar* text, int length, WebCore::TextCheckingTypeMask checkingTypes, Vector<WebCore::TextCheckingResult>& results) OVERRIDE; +#endif + virtual void updateSpellingUIWithGrammarString(const String&, const WebCore::GrammarDetail&) OVERRIDE; + virtual void updateSpellingUIWithMisspelledWord(const String&) OVERRIDE; + virtual void showSpellingUI(bool show) OVERRIDE; + virtual bool spellingUIIsShowing() OVERRIDE; + virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) OVERRIDE; + virtual void willSetInputMethodState() OVERRIDE; + virtual void setInputMethodState(bool enabled) OVERRIDE; + virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) OVERRIDE; +#if PLATFORM(MAC) && !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) OVERRIDE; + virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel) OVERRIDE; + virtual String dismissCorrectionPanelSoon(WebCore::ReasonForDismissingCorrectionPanel) OVERRIDE; + virtual void recordAutocorrectionResponse(AutocorrectionResponseType, const String& replacedString, const String& replacementString) OVERRIDE; +#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 000000000..b53866258 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebErrors.h @@ -0,0 +1,47 @@ +/* + * 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 WebErrors_h +#define WebErrors_h + +namespace WebCore { + class ResourceError; + class ResourceRequest; + class ResourceResponse; +} + +namespace WebKit { + +WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&); +WebCore::ResourceError blockedError(const WebCore::ResourceRequest&); +WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&); +WebCore::ResourceError interruptedForPolicyChangeError(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 000000000..3d0e22205 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp @@ -0,0 +1,1451 @@ +/* + * 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 "config.h" +#include "WebFrameLoaderClient.h" + +#include "AuthenticationManager.h" +#include "DataReference.h" +#include "InjectedBundleNavigationAction.h" +#include "InjectedBundleUserMessageCoders.h" +#include "PlatformCertificateInfo.h" +#include "PluginView.h" +#include "StringPairVector.h" +#include "WebBackForwardListProxy.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 "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/HistoryItem.h> +#include <WebCore/MIMETypeRegistry.h> +#include <WebCore/MouseEvent.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/Page.h> +#include <WebCore/PluginData.h> +#include <WebCore/ProgressTracker.h> +#include <WebCore/ResourceError.h> +#include <WebCore/Settings.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* loader, const ResourceRequest& request) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + bool pageIsProvisionallyLoading = false; + if (FrameLoader* frameLoader = loader->frameLoader()) + pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader; + + webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading); + webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request, pageIsProvisionallyLoading)); +} + +void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse); + + if (request.isNull()) { + // 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->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response); + webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response)); +} + +void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength); + webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength)); +} + +void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier); + 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->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error); + 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::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()->document()->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()->document()->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()->document()->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()->document()->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(); + webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame); + + 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); + + String unreachableURL = provisionalLoader->unreachableURL().string(); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + // FIXME: use direction of title. + webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType) +{ + 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()))); + + // Only restore the scale factor for standard frame loads (of the main frame). + if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) { + Page* page = m_frame->coreFrame()->page(); + if (page && page->pageScaleFactor() != 1) + webPage->scalePage(1, IntPoint()); + } +} + +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()))); + + if (m_frame == m_frame->page()->mainWebFrame() && !webPage->corePage()->settings()->suppressIncrementalRendering()) + webPage->drawingArea()->setLayerTreeStateIsFrozen(false); +} + +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()))); +} + +void WebFrameLoaderClient::dispatchDidLayout() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + // Notify the bundle client. + webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame); + + // NOTE: Unlike the other layout notifications, this does not notify the + // the UIProcess for every call. + + if (m_frame == m_frame->page()->mainWebFrame()) { + // FIXME: Remove at the soonest possible time. + webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize())); + webPage->mainFrameDidLayout(); + } +} + +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(); +} + +void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (!request.url().string()) { + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); + return; + } + + RefPtr<APIObject> userData; + + // Notify the bundle client. + WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData); + if (policy == WKBundlePagePolicyActionUse) { + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); + return; + } + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + bool receivedPolicyAction; + uint64_t policyAction; + uint64_t downloadID; + + // Notify the UIProcess. + if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), response, request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponse::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> formState, const String& frameName) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState); + + // Notify the bundle client. + WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData); + if (policy == WKBundlePagePolicyActionUse) { + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); + return; + } + + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get()))); +} + +void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + // Always ignore requests with empty URLs. + if (request.isEmpty()) { + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore); + return; + } + + RefPtr<APIObject> userData; + + RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState); + + // Notify the bundle client. + WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData); + if (policy == WKBundlePagePolicyActionUse) { + (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse); + return; + } + + uint64_t listenerID = m_frame->setUpPolicyListener(function); + bool receivedPolicyAction; + uint64_t policyAction; + uint64_t downloadID; + + // Notify the UIProcess. + if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, policyAction, downloadID))) + return; + + // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply. + if (receivedPolicyAction) + m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID); +} + +void WebFrameLoaderClient::cancelPolicyCheck() +{ + m_frame->invalidatePolicyListener(); +} + +void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + // Notify the bundle client. + webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData); + + // Notify the UIProcess. + webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get()))); +} + +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()) { + if (m_frame->isMainFrame()) + webPage->send(Messages::WebPageProxy::DidStartProgress()); + } +} + +void WebFrameLoaderClient::postProgressEstimateChangedNotification() +{ + if (WebPage* webPage = m_frame->page()) { + if (m_frame->isMainFrame()) { + double progress = webPage->corePage()->progress()->estimatedProgress(); + webPage->send(Messages::WebPageProxy::DidChangeProgress(progress)); + } + } +} + +void WebFrameLoaderClient::postProgressFinishedNotification() +{ + if (WebPage* webPage = m_frame->page()) { + if (m_frame->isMainFrame()) + webPage->send(Messages::WebPageProxy::DidFinishProgress()); + } +} + +void WebFrameLoaderClient::setMainFrameDocumentReady(bool) +{ + notImplemented(); +} + +void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */) +{ + 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(loader->response().suggestedFilename(), dataReference)); + } + + return; + } + + m_pluginView->manualLoadDidFinishLoading(); + m_pluginView = 0; + m_hasSentResponseToPluginView = false; +} + +void WebFrameLoaderClient::updateGlobalHistory() +{ + WebPage* webPage = m_frame->page(); + if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) + return; + + DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); + + WebNavigationDataStore data; + data.url = loader->urlForHistory().string(); + // FIXME: use direction of title. + data.title = loader->title().string(); + data.originalRequest = loader->originalRequestCopy(); + + WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0); +} + +void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() +{ + WebPage* webPage = m_frame->page(); + if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) + 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* item) const +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return false; + + uint64_t itemID = WebBackForwardListProxy::idForItem(item); + if (!itemID) { + // We should never be considering navigating to an item that is not actually in the back/forward list. + ASSERT_NOT_REACHED(); + return false; + } + + bool shouldGoToBackForwardListItem; + if (!webPage->sendSync(Messages::WebPageProxy::ShouldGoToBackForwardListItem(itemID), Messages::WebPageProxy::ShouldGoToBackForwardListItem::Reply(shouldGoToBackForwardListItem))) + return false; + + return shouldGoToBackForwardListItem; +} + +bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const +{ + return true; +} + +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*, const KURL&) +{ + 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()))); +} + +void WebFrameLoaderClient::didDetectXSS(const KURL&, bool) +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + RefPtr<APIObject> userData; + + webPage->injectedBundleLoaderClient().didDetectXSSForFrame(webPage, m_frame, userData); + + webPage->send(Messages::WebPageProxy::DidDetectXSSForFrame(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::interruptedForPolicyChangeError(const ResourceRequest& request) +{ + return WebKit::interruptedForPolicyChangeError(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; + +#if PLATFORM(QT) + DEFINE_STATIC_LOCAL(const ResourceError, errorInterruptedForPolicyChange, (this->interruptedForPolicyChangeError(ResourceRequest()))); + + if (error.errorCode() == errorInterruptedForPolicyChange.errorCode() && error.domain() == errorInterruptedForPolicyChange.domain()) + return false; +#endif + + 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() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (m_frame == m_frame->page()->mainWebFrame()) + webPage->drawingArea()->setLayerTreeStateIsFrozen(false); +} + +void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*) +{ + notImplemented(); +} + +void WebFrameLoaderClient::restoreViewState() +{ + // Inform the UI process of the scale factor. + double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor(); + m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor)); + + // FIXME: This should not be necessary. WebCore should be correctly invalidating + // the view on restores from the back/forward cache. + if (m_frame == m_frame->page()->mainWebFrame()) + m_frame->page()->drawingArea()->setNeedsDisplay(m_frame->page()->bounds()); +} + +void WebFrameLoaderClient::provisionalLoadStarted() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (m_frame == m_frame->page()->mainWebFrame()) + webPage->drawingArea()->setLayerTreeStateIsFrozen(true); +} + +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 StringWithDirection& title, const KURL& url) +{ + WebPage* webPage = m_frame->page(); + if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) + return; + + // FIXME: use direction of title. + WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(), + title.string(), 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*) +{ + WebPage* webPage = m_frame->page(); + bool isMainFrame = webPage->mainWebFrame() == m_frame; + + const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response(); + m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForResponse(response); +} + +void WebFrameLoaderClient::transitionToCommittedForNewPage() +{ + WebPage* webPage = m_frame->page(); + + Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white; + bool isMainFrame = webPage->mainWebFrame() == m_frame; + bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout(); + +#if !USE(TILED_BACKING_STORE) + const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response(); + m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForResponse(response); +#endif + + m_frame->coreFrame()->createView(webPage->size(), backgroundColor, /* transparent */ false, IntSize(), shouldUseFixedLayout); + 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 ResourceResponse& response) +{ + m_frame->convertHandleToDownload(handle, request, 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(); + if (!coreSubframe) + return 0; + + // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. + if (!coreSubframe->page()) + return 0; + + 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(ResourceLoader*, 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; + parameters.documentURL = m_frame->coreFrame()->document()->url().string(); + + Frame* mainFrame = webPage->mainWebFrame()->coreFrame(); + if (m_frame->coreFrame() == mainFrame) + parameters.toplevelDocumentURL = parameters.documentURL; + else if (m_frame->coreFrame()->document()->securityOrigin()->canAccess(mainFrame->document()->securityOrigin())) { + // We only want to set the toplevel document URL if the plug-in has access to it. + parameters.toplevelDocumentURL = mainFrame->document()->url().string(); + } + +#if PLUGIN_ARCHITECTURE(X11) + // FIXME: This should really be X11-specific plug-in quirks. + if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) { + // Currently we don't support transparency and windowed mode. + // Inject wmode=opaque to make Flash work in these conditions. + size_t wmodeIndex = parameters.names.find("wmode"); + if (wmodeIndex == notFound) { + parameters.names.append("wmode"); + parameters.values.append("opaque"); + } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window")) + parameters.values[wmodeIndex] = "opaque"; + } else if (equalIgnoringCase(mimeType, "application/x-webkit-test-netscape")) { + parameters.names.append("windowedPlugin"); + parameters.values.append("false"); + } +#endif + + RefPtr<Plugin> plugin = webPage->createPlugin(m_frame, 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) +{ + const String mimeType = "application/x-java-applet"; + RefPtr<Widget> plugin = createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, mimeType, false); + if (!plugin) { + if (WebPage* webPage = m_frame->page()) + webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(mimeType)); + } + return plugin.release(); +} + +static bool pluginSupportsExtension(PluginData* pluginData, const String& extension) +{ + ASSERT(extension.lower() == extension); + + for (size_t i = 0; i < pluginData->mimes().size(); ++i) { + const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i]; + + if (mimeClassInfo.extensions.contains(extension)) + return true; + } + return false; +} + +ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages) +{ + // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code + // is consolidated. + + String mimeType = mimeTypeIn; + if (mimeType.isEmpty()) { + String extension = url.path().substring(url.path().reverseFind('.') + 1).lower(); + + // Try to guess the MIME type from the extension. + mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); + + if (mimeType.isEmpty()) { + // Check if there's a plug-in around that can handle the extension. + if (WebPage* webPage = m_frame->page()) { + if (PluginData* pluginData = webPage->corePage()->pluginData()) { + if (pluginSupportsExtension(pluginData, extension)) + return ObjectContentNetscapePlugin; + } + } + } + } + + if (mimeType.isEmpty()) + return ObjectContentFrame; + + bool plugInSupportsMIMEType = false; + if (WebPage* webPage = m_frame->page()) { + if (PluginData* pluginData = webPage->corePage()->pluginData()) { + if (pluginData->supportsMimeType(mimeType)) + plugInSupportsMIMEType = true; + } + } + + if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) + return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage; + + if (plugInSupportsMIMEType) + 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 PLATFORM(WIN) && 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; +} + +void WebFrameLoaderClient::didChangeScrollOffset() +{ + WebPage* webPage = m_frame->page(); + if (!webPage) + return; + + if (!m_frame->isMainFrame()) + return; + + // If this is called when tearing down a FrameView, the WebCore::Frame's + // current FrameView will be null. + if (!m_frame->coreFrame()->view()) + return; + + webPage->didChangeScrollOffsetForMainFrame(); +} + +PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext() +{ + RefPtr<WebFrameNetworkingContext> context = WebFrameNetworkingContext::create(m_frame); +#if PLATFORM(QT) + // We encapsulate the WebPage pointer as a property of the originating QObject. + QObject* originatingObject = context->originatingObject(); + ASSERT(originatingObject); + originatingObject->setProperty("PagePointer", QVariant::fromValue(static_cast<void*>(m_frame->page()))); +#endif + return context.release(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h new file mode 100644 index 000000000..fb783535e --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h @@ -0,0 +1,230 @@ +/* + * 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 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() OVERRIDE; + + virtual bool hasHTMLView() const OVERRIDE; + virtual bool hasWebView() const OVERRIDE; + + virtual void makeRepresentation(WebCore::DocumentLoader*) OVERRIDE; + virtual void forceLayout() OVERRIDE; + virtual void forceLayoutForNonHTML() OVERRIDE; + + virtual void setCopiesOnScroll() OVERRIDE; + + virtual void detachedFromParent2() OVERRIDE; + virtual void detachedFromParent3() OVERRIDE; + + virtual void assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest&) OVERRIDE; + + virtual void dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) OVERRIDE; + virtual bool shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long identifier) OVERRIDE; + virtual void dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&) OVERRIDE; + virtual void dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::AuthenticationChallenge&) OVERRIDE; +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + virtual bool canAuthenticateAgainstProtectionSpace(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ProtectionSpace&) OVERRIDE; +#endif + virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&) OVERRIDE; + virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int dataLength) OVERRIDE; + virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier) OVERRIDE; + virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&) OVERRIDE; + virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length) OVERRIDE; + + virtual void dispatchDidHandleOnloadEvents() OVERRIDE; + virtual void dispatchDidReceiveServerRedirectForProvisionalLoad() OVERRIDE; + virtual void dispatchDidCancelClientRedirect() OVERRIDE; + virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate) OVERRIDE; + virtual void dispatchDidChangeLocationWithinPage() OVERRIDE; + virtual void dispatchDidPushStateWithinPage() OVERRIDE; + virtual void dispatchDidReplaceStateWithinPage() OVERRIDE; + virtual void dispatchDidPopStateWithinPage() OVERRIDE; + virtual void dispatchWillClose() OVERRIDE; + virtual void dispatchDidReceiveIcon() OVERRIDE; + virtual void dispatchDidStartProvisionalLoad() OVERRIDE; + virtual void dispatchDidReceiveTitle(const WebCore::StringWithDirection&) OVERRIDE; + virtual void dispatchDidChangeIcons(WebCore::IconType) OVERRIDE; + virtual void dispatchDidCommitLoad() OVERRIDE; + virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&) OVERRIDE; + virtual void dispatchDidFailLoad(const WebCore::ResourceError&) OVERRIDE; + virtual void dispatchDidFinishDocumentLoad() OVERRIDE; + virtual void dispatchDidFinishLoad() OVERRIDE; + + virtual void dispatchDidFirstLayout() OVERRIDE; + virtual void dispatchDidFirstVisuallyNonEmptyLayout() OVERRIDE; + virtual void dispatchDidLayout() OVERRIDE; + + virtual WebCore::Frame* dispatchCreatePage(const WebCore::NavigationAction&) OVERRIDE; + virtual void dispatchShow() OVERRIDE; + + virtual void dispatchDecidePolicyForResponse(WebCore::FramePolicyFunction, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&) OVERRIDE; + virtual void dispatchDecidePolicyForNewWindowAction(WebCore::FramePolicyFunction, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<WebCore::FormState>, const String& frameName) OVERRIDE; + virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, PassRefPtr<WebCore::FormState>) OVERRIDE; + virtual void cancelPolicyCheck() OVERRIDE; + + virtual void dispatchUnableToImplementPolicy(const WebCore::ResourceError&) OVERRIDE; + + virtual void dispatchWillSendSubmitEvent(WebCore::HTMLFormElement*) OVERRIDE { } + virtual void dispatchWillSubmitForm(WebCore::FramePolicyFunction, PassRefPtr<WebCore::FormState>) OVERRIDE; + + virtual void dispatchDidLoadMainResource(WebCore::DocumentLoader*) OVERRIDE; + virtual void revertToProvisionalState(WebCore::DocumentLoader*) OVERRIDE; + virtual void setMainDocumentError(WebCore::DocumentLoader*, const WebCore::ResourceError&) OVERRIDE; + + // Maybe these should go into a ProgressTrackerClient some day + virtual void willChangeEstimatedProgress() OVERRIDE; + virtual void didChangeEstimatedProgress() OVERRIDE; + virtual void postProgressStartedNotification() OVERRIDE; + virtual void postProgressEstimateChangedNotification() OVERRIDE; + virtual void postProgressFinishedNotification() OVERRIDE; + + virtual void setMainFrameDocumentReady(bool) OVERRIDE; + + virtual void startDownload(const WebCore::ResourceRequest&, const String& suggestedName = String()) OVERRIDE; + + virtual void willChangeTitle(WebCore::DocumentLoader*) OVERRIDE; + virtual void didChangeTitle(WebCore::DocumentLoader*) OVERRIDE; + + virtual void committedLoad(WebCore::DocumentLoader*, const char*, int) OVERRIDE; + virtual void finishedLoading(WebCore::DocumentLoader*) OVERRIDE; + + virtual void updateGlobalHistory() OVERRIDE; + virtual void updateGlobalHistoryRedirectLinks() OVERRIDE; + + virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const OVERRIDE; + virtual bool shouldStopLoadingForHistoryItem(WebCore::HistoryItem*) const OVERRIDE; + + virtual void didDisplayInsecureContent() OVERRIDE; + virtual void didRunInsecureContent(WebCore::SecurityOrigin*, const WebCore::KURL&) OVERRIDE; + virtual void didDetectXSS(const WebCore::KURL&, bool didBlockEntirePage) OVERRIDE; + + virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&) OVERRIDE; + virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&) OVERRIDE; + virtual WebCore::ResourceError cannotShowURLError(const WebCore::ResourceRequest&) OVERRIDE; + virtual WebCore::ResourceError interruptedForPolicyChangeError(const WebCore::ResourceRequest&) OVERRIDE; + + virtual WebCore::ResourceError cannotShowMIMETypeError(const WebCore::ResourceResponse&) OVERRIDE; + virtual WebCore::ResourceError fileDoesNotExistError(const WebCore::ResourceResponse&) OVERRIDE; + virtual WebCore::ResourceError pluginWillHandleLoadError(const WebCore::ResourceResponse&) OVERRIDE; + + virtual bool shouldFallBack(const WebCore::ResourceError&) OVERRIDE; + + virtual bool canHandleRequest(const WebCore::ResourceRequest&) const OVERRIDE; + virtual bool canShowMIMEType(const String& MIMEType) const OVERRIDE; + virtual bool canShowMIMETypeAsHTML(const String& MIMEType) const OVERRIDE; + virtual bool representationExistsForURLScheme(const String& URLScheme) const OVERRIDE; + virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const OVERRIDE; + + virtual void frameLoadCompleted() OVERRIDE; + virtual void saveViewStateToItem(WebCore::HistoryItem*) OVERRIDE; + virtual void restoreViewState() OVERRIDE; + virtual void provisionalLoadStarted() OVERRIDE; + virtual void didFinishLoad() OVERRIDE; + virtual void prepareForDataSourceReplacement() OVERRIDE; + + virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); + virtual void setTitle(const WebCore::StringWithDirection&, const WebCore::KURL&) OVERRIDE; + + virtual String userAgent(const WebCore::KURL&) OVERRIDE; + + virtual void savePlatformDataToCachedFrame(WebCore::CachedFrame*) OVERRIDE; + virtual void transitionToCommittedFromCachedFrame(WebCore::CachedFrame*) OVERRIDE; + virtual void transitionToCommittedForNewPage() OVERRIDE; + + virtual void didSaveToPageCache() OVERRIDE; + virtual void didRestoreFromPageCache() OVERRIDE; + + virtual void dispatchDidBecomeFrameset(bool) OVERRIDE; + + virtual bool canCachePage() const OVERRIDE; + virtual void download(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&) OVERRIDE; + + virtual PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL& url, const String& name, WebCore::HTMLFrameOwnerElement* ownerElement, + const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) OVERRIDE; + virtual void didTransferChildFrameToNewDocument(WebCore::Page*) OVERRIDE; + virtual void transferLoadingResourceFromPage(WebCore::ResourceLoader*, const WebCore::ResourceRequest&, WebCore::Page*) OVERRIDE; + + virtual PassRefPtr<WebCore::Widget> createPlugin(const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually) OVERRIDE; + virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget) OVERRIDE; + + virtual PassRefPtr<WebCore::Widget> createJavaAppletWidget(const WebCore::IntSize&, WebCore::HTMLAppletElement*, const WebCore::KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) OVERRIDE; + + virtual WebCore::ObjectContentType objectContentType(const WebCore::KURL&, const String& mimeType, bool shouldPreferPlugInsForImages) OVERRIDE; + virtual String overrideMediaType() const OVERRIDE; + + virtual void dispatchDidClearWindowObjectInWorld(WebCore::DOMWrapperWorld*) OVERRIDE; + + virtual void documentElementAvailable() OVERRIDE; + virtual void didPerformFirstNavigation() const OVERRIDE; // "Navigation" here means a transition from one page to another that ends up in the back/forward list. + + virtual void registerForIconNotification(bool listen = true) OVERRIDE; + +#if PLATFORM(MAC) + virtual RemoteAXObjectRef accessibilityRemoteObject() OVERRIDE; + +#if ENABLE(MAC_JAVA_BRIDGE) + virtual jobject javaApplet(NSView*) OVERRIDE; +#endif + virtual NSCachedURLResponse* willCacheResponse(WebCore::DocumentLoader*, unsigned long identifier, NSCachedURLResponse*) const OVERRIDE; +#endif +#if PLATFORM(WIN) && USE(CFNETWORK) + // FIXME: Windows should use willCacheResponse - <https://bugs.webkit.org/show_bug.cgi?id=57257>. + virtual bool shouldCacheResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&, const unsigned char* data, unsigned long long length) OVERRIDE; +#endif + + virtual bool shouldUsePluginDocument(const String& /*mimeType*/) const OVERRIDE; + + virtual void didChangeScrollOffset() OVERRIDE; + + virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext() OVERRIDE; + + WebFrame* m_frame; + RefPtr<PluginView> m_pluginView; + bool m_hasSentResponseToPluginView; + bool m_frameHasCustomRepresentation; +}; + +} // 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 000000000..1f920a1fb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGeolocationClient.cpp @@ -0,0 +1,83 @@ +/* + * 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 "config.h" +#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 000000000..21fc4383f --- /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() OVERRIDE; + + virtual void startUpdating() OVERRIDE; + virtual void stopUpdating() OVERRIDE; + virtual void setEnableHighAccuracy(bool) OVERRIDE; + + virtual WebCore::GeolocationPosition* lastPosition() OVERRIDE; + + virtual void requestPermission(WebCore::Geolocation*) OVERRIDE; + virtual void cancelPermissionRequest(WebCore::Geolocation*) OVERRIDE; + + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // ENABLE(CLIENT_BASED_GEOLOCATION) + +#endif // WebGeolocationClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp new file mode 100644 index 000000000..c0f612801 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.cpp @@ -0,0 +1,628 @@ +/* + 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" + +#if USE(ACCELERATED_COMPOSITING) + +#include "WebGraphicsLayer.h" + +#include "Animation.h" +#include "BackingStore.h" +#include "Frame.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "GraphicsLayer.h" +#include "LayerTreeHostProxyMessages.h" +#include "Page.h" +#include "TiledBackingStoreRemoteTile.h" +#include "WebPage.h" +#include "text/CString.h" +#include <HashMap.h> +#include <wtf/CurrentTime.h> + +using namespace WebKit; + +namespace WebCore { + +static const float gTileDimension = 1024.0; + +static HashMap<WebLayerID, WebGraphicsLayer*>& layerByIDMap() +{ + static HashMap<WebLayerID, WebGraphicsLayer*> globalMap; + return globalMap; +} + +WebGraphicsLayer* WebGraphicsLayer::layerByID(WebKit::WebLayerID id) +{ + HashMap<WebLayerID, WebGraphicsLayer*>& table = layerByIDMap(); + HashMap<WebLayerID, WebGraphicsLayer*>::iterator it = table.find(id); + if (it == table.end()) + return 0; + return it->second; +} + +static WebLayerID toWebLayerID(GraphicsLayer* layer) +{ + return layer ? toWebGraphicsLayer(layer)->id() : 0; +} + +void WebGraphicsLayer::notifyChange() +{ + m_modified = true; + if (client()) + client()->notifySyncRequired(this); +} + +WebGraphicsLayer::WebGraphicsLayer(GraphicsLayerClient* client) + : GraphicsLayer(client) + , m_needsDisplay(false) + , m_modified(true) + , m_contentNeedsDisplay(false) + , m_hasPendingAnimations(false) + , m_inUpdateMode(false) +#if USE(TILED_BACKING_STORE) + , m_layerTreeTileClient(0) + , m_mainBackingStore(adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this)))) + , m_contentsScale(1.f) +#endif +{ + m_mainBackingStore->setContentsScale(1.0); + static WebLayerID nextLayerID = 1; + m_layerInfo.id = nextLayerID++; + layerByIDMap().add(id(), this); +} + +WebGraphicsLayer::~WebGraphicsLayer() +{ + layerByIDMap().remove(id()); + + // This would tell the UI process to release the backing store. + setContentsToImage(0); + + if (m_layerTreeTileClient) + m_layerTreeTileClient->didDeleteLayer(id()); +} + +bool WebGraphicsLayer::setChildren(const Vector<GraphicsLayer*>& children) +{ + bool ok = GraphicsLayer::setChildren(children); + if (!ok) + return false; + for (int i = 0; i < children.size(); ++i) { + WebGraphicsLayer* child = toWebGraphicsLayer(children[i]); + child->setContentsScale(m_contentsScale); + child->notifyChange(); + } + notifyChange(); + return true; +} + +void WebGraphicsLayer::addChild(GraphicsLayer* layer) +{ + GraphicsLayer::addChild(layer); + toWebGraphicsLayer(layer)->setContentsScale(m_contentsScale); + toWebGraphicsLayer(layer)->notifyChange(); + notifyChange(); +} + +void WebGraphicsLayer::addChildAtIndex(GraphicsLayer* layer, int index) +{ + GraphicsLayer::addChildAtIndex(layer, index); + toWebGraphicsLayer(layer)->setContentsScale(m_contentsScale); + toWebGraphicsLayer(layer)->notifyChange(); + notifyChange(); +} + +void WebGraphicsLayer::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling) +{ + GraphicsLayer::addChildAbove(layer, sibling); + toWebGraphicsLayer(layer)->setContentsScale(m_contentsScale); + toWebGraphicsLayer(layer)->notifyChange(); + notifyChange(); +} + +void WebGraphicsLayer::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling) +{ + GraphicsLayer::addChildBelow(layer, sibling); + toWebGraphicsLayer(layer)->setContentsScale(m_contentsScale); + toWebGraphicsLayer(layer)->notifyChange(); + notifyChange(); +} + +bool WebGraphicsLayer::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) +{ + bool ok = GraphicsLayer::replaceChild(oldChild, newChild); + if (!ok) + return false; + notifyChange(); + toWebGraphicsLayer(oldChild)->notifyChange(); + toWebGraphicsLayer(newChild)->setContentsScale(m_contentsScale); + toWebGraphicsLayer(newChild)->notifyChange(); + return true; +} + +void WebGraphicsLayer::removeFromParent() +{ + if (WebGraphicsLayer* parentLayer = toWebGraphicsLayer(parent())) + parentLayer->notifyChange(); + GraphicsLayer::removeFromParent(); + + notifyChange(); +} + +void WebGraphicsLayer::setPosition(const FloatPoint& p) +{ + if (position() == p) + return; + + GraphicsLayer::setPosition(p); + notifyChange(); +} + +void WebGraphicsLayer::setAnchorPoint(const FloatPoint3D& p) +{ + if (anchorPoint() == p) + return; + + GraphicsLayer::setAnchorPoint(p); + notifyChange(); +} + +void WebGraphicsLayer::setSize(const FloatSize& size) +{ + if (this->size() == size) + return; + + GraphicsLayer::setSize(size); + setNeedsDisplay(); + notifyChange(); +} + +void WebGraphicsLayer::setTransform(const TransformationMatrix& t) +{ + if (transform() == t) + return; + + GraphicsLayer::setTransform(t); + notifyChange(); +} + +void WebGraphicsLayer::setChildrenTransform(const TransformationMatrix& t) +{ + if (childrenTransform() == t) + return; + + GraphicsLayer::setChildrenTransform(t); + notifyChange(); +} + +void WebGraphicsLayer::setPreserves3D(bool b) +{ + if (preserves3D() == b) + return; + + GraphicsLayer::setPreserves3D(b); + notifyChange(); +} + +void WebGraphicsLayer::setMasksToBounds(bool b) +{ + if (masksToBounds() == b) + return; + GraphicsLayer::setMasksToBounds(b); + notifyChange(); +} + +void WebGraphicsLayer::setDrawsContent(bool b) +{ + if (drawsContent() == b) + return; + GraphicsLayer::setDrawsContent(b); + + if (b) + setNeedsDisplay(); + notifyChange(); +} + +void WebGraphicsLayer::setContentsOpaque(bool b) +{ + if (contentsOpaque() == b) + return; + GraphicsLayer::setContentsOpaque(b); + notifyChange(); +} + +void WebGraphicsLayer::setBackfaceVisibility(bool b) +{ + if (backfaceVisibility() == b) + return; + + GraphicsLayer::setBackfaceVisibility(b); + notifyChange(); +} + +void WebGraphicsLayer::setOpacity(float opacity) +{ + if (this->opacity() == opacity) + return; + + GraphicsLayer::setOpacity(opacity); + notifyChange(); +} + +void WebGraphicsLayer::setContentsRect(const IntRect& r) +{ + if (contentsRect() == r) + return; + + GraphicsLayer::setContentsRect(r); + notifyChange(); +} + +void WebGraphicsLayer::notifyAnimationStarted(double time) +{ + if (client()) + client()->notifyAnimationStarted(this, time); +} + +bool WebGraphicsLayer::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset) +{ + if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyOpacity)) + return false; + + WebLayerAnimation webAnimation(valueList); + webAnimation.name = keyframesName; + webAnimation.operation = WebLayerAnimation::AddAnimation; + webAnimation.boxSize = boxSize; + webAnimation.animation = Animation::create(anim); + webAnimation.startTime = timeOffset; + m_layerInfo.animations.append(webAnimation); + + m_hasPendingAnimations = true; + notifyChange(); + + return true; +} + +void WebGraphicsLayer::pauseAnimation(const String& animationName, double timeOffset) +{ + WebLayerAnimation webAnimation; + webAnimation.name = animationName; + webAnimation.operation = WebLayerAnimation::PauseAnimation; + webAnimation.startTime = WTF::currentTime() - timeOffset; + m_layerInfo.animations.append(webAnimation); + notifyChange(); +} + +void WebGraphicsLayer::removeAnimation(const String& animationName) +{ + WebLayerAnimation webAnimation; + webAnimation.name = animationName; + webAnimation.operation = WebLayerAnimation::RemoveAnimation; + m_layerInfo.animations.append(webAnimation); + notifyChange(); +} + +void WebGraphicsLayer::setContentsNeedsDisplay() +{ + RefPtr<Image> image = m_image; + setContentsToImage(0); + setContentsToImage(image.get()); +} + +void WebGraphicsLayer::setContentsToImage(Image* image) +{ + if (image == m_image) + return; + WebLayerTreeTileClient* client = layerTreeTileClient(); + int64_t newID = 0; + if (client) { + // We adopt first, in case this is the same frame - that way we avoid destroying and recreating the image. + newID = client->adoptImageBackingStore(image); + client->releaseImageBackingStore(m_layerInfo.imageBackingStoreID); + notifyChange(); + if (m_layerInfo.imageBackingStoreID && newID == m_layerInfo.imageBackingStoreID) + return; + } else { + // If client not set yet there should be no backing store ID. + ASSERT(!m_layerInfo.imageBackingStoreID); + notifyChange(); + } + + m_layerInfo.imageBackingStoreID = newID; + m_image = image; + m_layerInfo.imageIsUpdated = true; + GraphicsLayer::setContentsToImage(image); +} + +void WebGraphicsLayer::setMaskLayer(GraphicsLayer* layer) +{ + GraphicsLayer::setMaskLayer(layer); + notifyChange(); +} + +void WebGraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer) +{ + if (layer == replicaLayer()) + return; + GraphicsLayer::setReplicatedByLayer(layer); + notifyChange(); +} + +void WebGraphicsLayer::setNeedsDisplay() +{ + setNeedsDisplayInRect(IntRect(IntPoint::zero(), IntSize(size().width(), size().height()))); +} + +void WebGraphicsLayer::setNeedsDisplayInRect(const FloatRect& rect) +{ + recreateBackingStoreIfNeeded(); + m_mainBackingStore->invalidate(IntRect(rect)); + notifyChange(); +} + +WebLayerID WebGraphicsLayer::id() const +{ + return m_layerInfo.id; +} + +void WebGraphicsLayer::syncCompositingState(const FloatRect& rect) +{ + for (size_t i = 0; i < children().size(); ++i) + children()[i]->syncCompositingState(rect); + if (replicaLayer()) + replicaLayer()->syncCompositingState(rect); + if (maskLayer()) + maskLayer()->syncCompositingState(rect); + syncCompositingStateForThisLayerOnly(); +} + +WebGraphicsLayer* toWebGraphicsLayer(GraphicsLayer* layer) +{ + return static_cast<WebGraphicsLayer*>(layer); +} + +void WebGraphicsLayer::syncCompositingStateForThisLayerOnly() +{ + updateContentBuffers(); + + if (!m_modified) + return; + + m_layerInfo.name = name(); + m_layerInfo.anchorPoint = anchorPoint(); + m_layerInfo.backfaceVisible = backfaceVisibility(); + m_layerInfo.childrenTransform = childrenTransform(); + m_layerInfo.contentsOpaque = contentsOpaque(); + m_layerInfo.contentsRect = contentsRect(); + + // In the shadow layer tree we create in the UI process, layers with directly composited images are always considered to draw content. + // Otherwise, we'd have to check whether an layer with drawsContent==false has a directly composited image multiple times. + m_layerInfo.drawsContent = drawsContent() || m_image; + m_layerInfo.mask = toWebLayerID(maskLayer()); + m_layerInfo.masksToBounds = masksToBounds(); + m_layerInfo.opacity = opacity(); + m_layerInfo.parent = toWebLayerID(parent()); + m_layerInfo.pos = position(); + m_layerInfo.preserves3D = preserves3D(); + m_layerInfo.replica = toWebLayerID(replicaLayer()); + m_layerInfo.size = size(); + m_layerInfo.transform = transform(); + m_contentNeedsDisplay = false; + m_layerInfo.children.clear(); + + for (size_t i = 0; i < children().size(); ++i) + m_layerInfo.children.append(toWebLayerID(children()[i])); + + WebLayerTreeTileClient* tileClient = layerTreeTileClient(); + ASSERT(tileClient); + if (m_layerInfo.imageIsUpdated && m_image && !m_layerInfo.imageBackingStoreID) + m_layerInfo.imageBackingStoreID = tileClient->adoptImageBackingStore(m_image.get()); + + tileClient->didSyncCompositingStateForLayer(m_layerInfo); + m_modified = false; + m_layerInfo.imageIsUpdated = false; + if (m_hasPendingAnimations) + notifyAnimationStarted(WTF::currentTime()); + m_layerInfo.animations.clear(); + m_hasPendingAnimations = false; +} + +#if USE(TILED_BACKING_STORE) +void WebGraphicsLayer::tiledBackingStorePaintBegin() +{ +} + +void WebGraphicsLayer::setContentsScale(float scale) +{ + for (size_t i = 0; i < children().size(); ++i) { + WebGraphicsLayer* layer = toWebGraphicsLayer(this->children()[i]); + layer->setContentsScale(scale); + } + + m_contentsScale = scale; + if (m_mainBackingStore && m_mainBackingStore->contentsScale() == scale) + return; + + notifyChange(); + + m_previousBackingStore = m_mainBackingStore.release(); + m_mainBackingStore = adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this))); + m_mainBackingStore->setContentsScale(scale); +} + +void WebGraphicsLayer::setRootLayer(bool isRoot) +{ + m_layerInfo.isRootLayer = isRoot; + notifyChange(); +} + +void WebGraphicsLayer::setVisibleContentRectTrajectoryVector(const FloatPoint& trajectoryVector) +{ + m_mainBackingStore->setVisibleRectTrajectoryVector(trajectoryVector); +} + +void WebGraphicsLayer::setVisibleContentRect(const IntRect& rect) +{ + m_visibleContentRect = rect; + notifyChange(); + m_mainBackingStore->adjustVisibleRect(); +} + +void WebGraphicsLayer::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect) +{ + if (rect.isEmpty()) + return; + m_modified = true; + paintGraphicsLayerContents(*context, rect); +} + +void WebGraphicsLayer::tiledBackingStorePaintEnd(const Vector<IntRect>& updatedRects) +{ +} + +bool WebGraphicsLayer::tiledBackingStoreUpdatesAllowed() const +{ + if (!m_inUpdateMode) + return false; + if (WebLayerTreeTileClient* client = layerTreeTileClient()) + return client->layerTreeTileUpdatesAllowed(); + return false; +} + +IntRect WebGraphicsLayer::tiledBackingStoreContentsRect() +{ + if (m_image) + return IntRect(); + return IntRect(0, 0, size().width(), size().height()); +} + +IntRect WebGraphicsLayer::tiledBackingStoreVisibleRect() +{ + return m_visibleContentRect; +} + +Color WebGraphicsLayer::tiledBackingStoreBackgroundColor() const +{ + return contentsOpaque() ? Color::white : Color::transparent; + +} +void WebGraphicsLayer::createTile(int tileID, const UpdateInfo& updateInfo) +{ + m_modified = true; + if (WebLayerTreeTileClient* client = layerTreeTileClient()) + client->createTile(id(), tileID, updateInfo); +} + +void WebGraphicsLayer::updateTile(int tileID, const UpdateInfo& updateInfo) +{ + m_modified = true; + if (WebLayerTreeTileClient* client = layerTreeTileClient()) + client->updateTile(id(), tileID, updateInfo); +} + +void WebGraphicsLayer::removeTile(int tileID) +{ + m_modified = true; + if (WebLayerTreeTileClient* client = layerTreeTileClient()) + client->removeTile(id(), tileID); +} + +void WebGraphicsLayer::updateTileBuffersRecursively() +{ + m_mainBackingStore->updateTileBuffers(); + for (size_t i = 0; i < children().size(); ++i) { + WebGraphicsLayer* layer = toWebGraphicsLayer(this->children()[i]); + layer->updateTileBuffersRecursively(); + } +} + +WebLayerTreeTileClient* WebGraphicsLayer::layerTreeTileClient() const +{ + if (m_layerTreeTileClient) + return m_layerTreeTileClient; + WebGraphicsLayer* parent = toWebGraphicsLayer(this->parent()); + if (!parent) + return 0; + return parent->layerTreeTileClient(); +} + +void WebGraphicsLayer::updateContentBuffers() +{ + // Backing-stores for directly composited images is handled in LayerTreeHost. + if (m_image) + return; + + if (!drawsContent()) + return; + WebLayerTreeTileClient* client = layerTreeTileClient(); + if (!client) + return; + m_inUpdateMode = true; + m_mainBackingStore->updateTileBuffers(); + m_inUpdateMode = false; +} + +void WebGraphicsLayer::purgeBackingStores() +{ + for (size_t i = 0; i < children().size(); ++i) { + WebGraphicsLayer* layer = toWebGraphicsLayer(this->children()[i]); + layer->purgeBackingStores(); + } + + if (m_mainBackingStore) + m_mainBackingStore.clear(); + + if (!m_layerInfo.imageBackingStoreID) + return; + + layerTreeTileClient()->releaseImageBackingStore(m_layerInfo.imageBackingStoreID); + m_layerInfo.imageBackingStoreID = 0; +} + +void WebGraphicsLayer::recreateBackingStoreIfNeeded() +{ + for (size_t i = 0; i < children().size(); ++i) { + WebGraphicsLayer* layer = toWebGraphicsLayer(this->children()[i]); + layer->recreateBackingStoreIfNeeded(); + } + + if (!m_mainBackingStore) { + m_mainBackingStore = adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this))); + m_mainBackingStore->setContentsScale(m_contentsScale); + } + + if (m_image) + setContentsNeedsDisplay(); +} +#endif + +static PassOwnPtr<GraphicsLayer> createWebGraphicsLayer(GraphicsLayerClient* client) +{ + return adoptPtr(new WebGraphicsLayer(client)); +} + +void WebGraphicsLayer::initFactory() +{ + GraphicsLayer::setGraphicsLayerFactory(createWebGraphicsLayer); +} + +} +#endif diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h new file mode 100644 index 000000000..52955de1e --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebGraphicsLayer.h @@ -0,0 +1,165 @@ + /* + 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 WebGraphicsLayer_h +#define WebGraphicsLayer_h + +#include "FloatPoint3D.h" +#include "GraphicsLayer.h" +#include "Image.h" +#include "IntSize.h" +#include "RunLoop.h" +#include "ShareableBitmap.h" +#include "TiledBackingStore.h" +#include "TiledBackingStoreClient.h" +#include "TiledBackingStoreRemoteTile.h" +#include "TransformationMatrix.h" +#include "UpdateInfo.h" +#include "WebLayerTreeInfo.h" +#include "WebProcess.h" + +#if USE(ACCELERATED_COMPOSITING) + +namespace WebKit { + +class WebLayerTreeTileClient { +public: + // TiledBackingStoreRemoteTileClient + virtual void createTile(WebLayerID, int tileID, const UpdateInfo&) = 0; + virtual void updateTile(WebLayerID, int tileID, const UpdateInfo&) = 0; + virtual void removeTile(WebLayerID, int tileID) = 0; + virtual bool layerTreeTileUpdatesAllowed() const = 0; + virtual int64_t adoptImageBackingStore(Image*) = 0; + virtual void releaseImageBackingStore(int64_t) = 0; + virtual void didSyncCompositingStateForLayer(const WebLayerInfo&) = 0; + virtual void didDeleteLayer(WebLayerID) = 0; +}; +} + +namespace WebCore { + +class WebGraphicsLayer : public WebCore::GraphicsLayer +#if USE(TILED_BACKING_STORE) + , public TiledBackingStoreClient + , public WebKit::TiledBackingStoreRemoteTileClient +#endif +{ +public: + WebGraphicsLayer(GraphicsLayerClient*); + virtual ~WebGraphicsLayer(); + + // Reimplementations from GraphicsLayer.h. + bool setChildren(const Vector<GraphicsLayer*>&); + void addChild(GraphicsLayer*); + void addChildAtIndex(GraphicsLayer*, int); + void addChildAbove(GraphicsLayer*, GraphicsLayer*); + void addChildBelow(GraphicsLayer*, GraphicsLayer*); + bool replaceChild(GraphicsLayer*, GraphicsLayer*); + void removeFromParent(); + void setPosition(const FloatPoint&); + void setAnchorPoint(const FloatPoint3D&); + void setSize(const FloatSize&); + void setTransform(const TransformationMatrix&); + void setChildrenTransform(const TransformationMatrix&); + void setPreserves3D(bool); + void setMasksToBounds(bool); + void setDrawsContent(bool); + void setContentsOpaque(bool); + void setBackfaceVisibility(bool); + void setOpacity(float); + void setContentsRect(const IntRect&); + bool addAnimation(const KeyframeValueList&, const IntSize&, const Animation*, const String&, double); + void pauseAnimation(const String&, double); + void removeAnimation(const String&); + void setContentsToImage(Image*); + void setMaskLayer(GraphicsLayer*); + void setReplicatedByLayer(GraphicsLayer*); + void setNeedsDisplay(); + void setNeedsDisplayInRect(const FloatRect&); + void setContentsNeedsDisplay(); + void setVisibleContentRect(const IntRect&); + void setVisibleContentRectTrajectoryVector(const FloatPoint&); + virtual void syncCompositingState(const FloatRect&); + virtual void syncCompositingStateForThisLayerOnly(); + void setRootLayer(bool); + + WebKit::WebLayerID id() const; + static WebGraphicsLayer* layerByID(WebKit::WebLayerID); + bool isModified() const { return m_modified; } + void didSynchronize(); + Image* image() { return m_image.get(); } + void notifyAnimationStarted(double); + + static void initFactory(); + +#if USE(TILED_BACKING_STORE) + // TiledBackingStoreClient + virtual void tiledBackingStorePaintBegin(); + virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&); + virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea); + virtual bool tiledBackingStoreUpdatesAllowed() const; + virtual IntRect tiledBackingStoreContentsRect(); + virtual IntRect tiledBackingStoreVisibleRect(); + virtual Color tiledBackingStoreBackgroundColor() const; + + // TiledBackingStoreRemoteTileClient + virtual void createTile(int tileID, const WebKit::UpdateInfo&); + virtual void updateTile(int tileID, const WebKit::UpdateInfo&); + virtual void removeTile(int tileID); + + void setLayerTreeTileClient(WebKit::WebLayerTreeTileClient* client) { m_layerTreeTileClient = client; } + WebKit::WebLayerTreeTileClient* layerTreeTileClient() const; + + bool isReadyForTileBufferSwap() const; + void updateTileBuffersRecursively(); + void setContentsScale(float); + void updateContentBuffers(); + void purgeBackingStores(); + void recreateBackingStoreIfNeeded(); +#endif + +private: + WebKit::WebLayerInfo m_layerInfo; + WebKit::WebLayerTreeTileClient* m_layerTileClient; + RefPtr<Image> m_image; + FloatRect m_needsDisplayRect; + IntRect m_visibleContentRect; + bool m_needsDisplay : 1; + bool m_modified : 1; + bool m_contentNeedsDisplay : 1; + bool m_hasPendingAnimations : 1; + bool m_inUpdateMode : 2; + + void notifyChange(); + +#if USE(TILED_BACKING_STORE) + WebKit::WebLayerTreeTileClient* m_layerTreeTileClient; + OwnPtr<WebCore::TiledBackingStore> m_mainBackingStore; + OwnPtr<WebCore::TiledBackingStore> m_previousBackingStore; + float m_contentsScale; +#endif +}; + +WebGraphicsLayer* toWebGraphicsLayer(GraphicsLayer*); + +} +#endif + +#endif // WebGraphicsLayer_H diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp new file mode 100644 index 000000000..ea15c7f93 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspectorClient.h" + +#if ENABLE(INSPECTOR) + +#include "WebInspector.h" +#include "WebPage.h" +#include <WebCore/InspectorController.h> +#include <WebCore/Page.h> + +using namespace WebCore; + +namespace WebKit { + +void WebInspectorClient::inspectorDestroyed() +{ + closeInspectorFrontend(); + delete this; +} + +void WebInspectorClient::openInspectorFrontend(InspectorController*) +{ + WebPage* inspectorPage = m_page->inspector()->createInspectorPage(); + ASSERT_UNUSED(inspectorPage, inspectorPage); +} + +void WebInspectorClient::closeInspectorFrontend() +{ + if (m_page->inspector()) + m_page->inspector()->didClose(); +} + +void WebInspectorClient::bringFrontendToFront() +{ + m_page->inspector()->bringToFront(); +} + +void WebInspectorClient::highlight() +{ + if (!m_highlightOverlay) { + RefPtr<PageOverlay> highlightOverlay = PageOverlay::create(this); + m_highlightOverlay = highlightOverlay.get(); + m_page->installPageOverlay(highlightOverlay.release()); + } else + m_highlightOverlay->setNeedsDisplay(); +} + +void WebInspectorClient::hideHighlight() +{ + if (m_highlightOverlay) + m_page->uninstallPageOverlay(m_highlightOverlay, false); +} + +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); +} + +void WebInspectorClient::pageOverlayDestroyed(PageOverlay*) +{ +} + +void WebInspectorClient::willMoveToWebPage(PageOverlay*, WebPage* webPage) +{ + if (webPage) + return; + + // The page overlay is moving away from the web page, reset it. + ASSERT(m_highlightOverlay); + m_highlightOverlay = 0; +} + +void WebInspectorClient::didMoveToWebPage(PageOverlay*, WebPage*) +{ +} + +void WebInspectorClient::drawRect(PageOverlay* overlay, WebCore::GraphicsContext& context, const WebCore::IntRect& dirtyRect) +{ + m_page->corePage()->inspectorController()->drawHighlight(context); +} + +bool WebInspectorClient::mouseEvent(PageOverlay*, const WebMouseEvent&) +{ + return false; +} + +} // 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 000000000..397003024 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorClient.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 WebInspectorClient_h +#define WebInspectorClient_h + +#if ENABLE(INSPECTOR) + +#include "PageOverlay.h" + +#include <WebCore/InspectorClient.h> + +namespace WebCore { + class GraphicsContext; + class IntRect; +} + +namespace WebKit { + +class WebPage; + +class WebInspectorClient : public WebCore::InspectorClient, private PageOverlay::Client { +public: + WebInspectorClient(WebPage* page) + : m_page(page) + , m_highlightOverlay(0) + { + } + +private: + virtual void inspectorDestroyed() OVERRIDE; + + virtual void openInspectorFrontend(WebCore::InspectorController*) OVERRIDE; + virtual void closeInspectorFrontend() OVERRIDE; + virtual void bringFrontendToFront() OVERRIDE; + + virtual void highlight() OVERRIDE; + virtual void hideHighlight() OVERRIDE; + + virtual bool sendMessageToFrontend(const String&) OVERRIDE; + + // PageOverlay::Client + virtual void pageOverlayDestroyed(PageOverlay*) OVERRIDE; + virtual void willMoveToWebPage(PageOverlay*, WebPage*) OVERRIDE; + virtual void didMoveToWebPage(PageOverlay*, WebPage*) OVERRIDE; + virtual void drawRect(PageOverlay*, WebCore::GraphicsContext&, const WebCore::IntRect&) OVERRIDE; + virtual bool mouseEvent(PageOverlay*, const WebMouseEvent&) OVERRIDE; + + WebPage* m_page; + PageOverlay* m_highlightOverlay; +}; + +} // 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 000000000..09e1d37cc --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspectorFrontendClient.h" + +#if ENABLE(INSPECTOR) + +#include "WebInspector.h" +#include "WebPage.h" +#include <WebCore/InspectorController.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/Page.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +WebInspectorFrontendClient::WebInspectorFrontendClient(WebPage* page, WebPage* inspectorPage) + : InspectorFrontendClientLocal(page->corePage()->inspectorController(), inspectorPage->corePage(), adoptPtr(new Settings())) + , 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() +{ + m_page->inspector()->bringToFront(); +} + +void WebInspectorFrontendClient::closeWindow() +{ + m_page->corePage()->inspectorController()->disconnectFrontend(); + m_page->inspector()->didClose(); +} + +void WebInspectorFrontendClient::attachWindow() +{ + m_page->inspector()->attach(); +} + +void WebInspectorFrontendClient::detachWindow() +{ + m_page->inspector()->detach(); +} + +void WebInspectorFrontendClient::setAttachedWindowHeight(unsigned height) +{ + m_page->inspector()->setAttachedWindowHeight(height); +} + +void WebInspectorFrontendClient::inspectedURLChanged(const String& urlString) +{ + m_page->inspector()->inspectedURLChanged(urlString); +} + +} // 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 000000000..3183ab00a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebInspectorFrontendClient.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 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() OVERRIDE; + + virtual String localizedStringsURL() OVERRIDE; + virtual String hiddenPanels() OVERRIDE; + + virtual void bringToFront() OVERRIDE; + virtual void closeWindow() OVERRIDE; + + virtual void attachWindow() OVERRIDE; + virtual void detachWindow() OVERRIDE; + virtual void setAttachedWindowHeight(unsigned) OVERRIDE; + + virtual void inspectedURLChanged(const String&) OVERRIDE; + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) + +#endif // WebInspectorFrontendClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebNotificationClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebNotificationClient.cpp new file mode 100644 index 000000000..f93911390 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebNotificationClient.cpp @@ -0,0 +1,104 @@ +/* + * 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 "config.h" +#include "WebNotificationClient.h" + +#if ENABLE(NOTIFICATIONS) + +#include "NotificationPermissionRequestManager.h" +#include "WebNotificationManager.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/NotImplemented.h> +#include <WebCore/ScriptExecutionContext.h> + +using namespace WebCore; + +namespace WebKit { + +WebNotificationClient::WebNotificationClient(WebPage* page) + : m_page(page) +{ +} + +WebNotificationClient::~WebNotificationClient() +{ +} + +bool WebNotificationClient::show(Notification* notification) +{ +#if ENABLE(NOTIFICATIONS) + return WebProcess::shared().notificationManager().show(notification, m_page); +#else + notImplemented(); + return false; +#endif +} + +void WebNotificationClient::cancel(Notification* notification) +{ +#if ENABLE(NOTIFICATIONS) + WebProcess::shared().notificationManager().cancel(notification, m_page); +#else + notImplemented(); +#endif +} + +void WebNotificationClient::notificationObjectDestroyed(Notification* notification) +{ +#if ENABLE(NOTIFICATIONS) + WebProcess::shared().notificationManager().didDestroyNotification(notification, m_page); +#else + UNUSED_PARAM(notification); + notImplemented(); +#endif +} + +void WebNotificationClient::notificationControllerDestroyed() +{ + delete this; +} + +void WebNotificationClient::requestPermission(ScriptExecutionContext* context, PassRefPtr<VoidCallback> callback) +{ + m_page->notificationPermissionRequestManager()->startRequest(context->securityOrigin(), callback); +} + +void WebNotificationClient::cancelRequestsForPermission(ScriptExecutionContext* context) +{ + m_page->notificationPermissionRequestManager()->cancelRequest(context->securityOrigin()); +} + +NotificationPresenter::Permission WebNotificationClient::checkPermission(ScriptExecutionContext* context) +{ + if (!context || !context->isDocument()) + return NotificationPresenter::PermissionDenied; + return m_page->notificationPermissionRequestManager()->permissionLevel(context->securityOrigin()); +} + +} // namespace WebKit + +#endif // ENABLE(NOTIFICATIONS) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebNotificationClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebNotificationClient.h new file mode 100644 index 000000000..ad36a9621 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebNotificationClient.h @@ -0,0 +1,63 @@ +/* + * 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 WebNotificationClient_h +#define WebNotificationClient_h + +#if ENABLE(NOTIFICATIONS) + +#include <WebCore/NotificationPresenter.h> + +namespace WebCore { +class ScriptExecutionContext; +class VoidCallback; +} // namespace WebCore + +namespace WebKit { + +class WebPage; + +class WebNotificationClient : public WebCore::NotificationPresenter { +public: + WebNotificationClient(WebPage*); + virtual ~WebNotificationClient(); + +private: + virtual bool show(WebCore::Notification*) OVERRIDE; + virtual void cancel(WebCore::Notification*) OVERRIDE; + virtual void notificationObjectDestroyed(WebCore::Notification*) OVERRIDE; + virtual void notificationControllerDestroyed() OVERRIDE; + virtual void requestPermission(WebCore::ScriptExecutionContext*, PassRefPtr<WebCore::VoidCallback>) OVERRIDE; + virtual void cancelRequestsForPermission(WebCore::ScriptExecutionContext*) OVERRIDE; + virtual NotificationPresenter::Permission checkPermission(WebCore::ScriptExecutionContext*) OVERRIDE; + + WebPage* m_page; +}; + +} // namespace WebKit + +#endif // ENABLE(NOTIFICATIONS) + +#endif // WebNotificationClient_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp new file mode 100644 index 000000000..65240ee84 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.cpp @@ -0,0 +1,130 @@ +/* + * 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 "config.h" +#include "WebPlatformStrategies.h" + +#if USE(PLATFORM_STRATEGIES) + +#include "PluginInfoStore.h" +#include "WebContextMessages.h" +#include "WebCookieManager.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcess.h" +#include <WebCore/Page.h> + +#if USE(CF) +#include <wtf/RetainPtr.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +void WebPlatformStrategies::initialize() +{ + DEFINE_STATIC_LOCAL(WebPlatformStrategies, platformStrategies, ()); + setPlatformStrategies(&platformStrategies); +} + +WebPlatformStrategies::WebPlatformStrategies() + : m_pluginCacheIsPopulated(false) + , m_shouldRefreshPlugins(false) +{ +} + +CookiesStrategy* WebPlatformStrategies::createCookiesStrategy() +{ + return this; +} + +PluginStrategy* WebPlatformStrategies::createPluginStrategy() +{ + return this; +} + +VisitedLinkStrategy* WebPlatformStrategies::createVisitedLinkStrategy() +{ + return this; +} + +// CookiesStrategy + +void WebPlatformStrategies::notifyCookiesChanged() +{ + WebCookieManager::shared().dispatchCookiesDidChange(); +} + +// PluginStrategy + +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; +} + +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; +} + +// VisitedLinkStrategy + +bool WebPlatformStrategies::isLinkVisited(Page*, LinkHash linkHash, const KURL&, const AtomicString&) +{ + return WebProcess::shared().isLinkVisited(linkHash); +} + +void WebPlatformStrategies::addVisitedLink(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 000000000..970f7ce6d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPlatformStrategies.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 WebPlatformStrategies_h +#define WebPlatformStrategies_h + +#if USE(PLATFORM_STRATEGIES) + +#include <WebCore/CookiesStrategy.h> +#include <WebCore/PlatformStrategies.h> +#include <WebCore/PluginStrategy.h> +#include <WebCore/VisitedLinkStrategy.h> + +namespace WebKit { + +class WebPlatformStrategies : public WebCore::PlatformStrategies, private WebCore::CookiesStrategy, private WebCore::PluginStrategy, private WebCore::VisitedLinkStrategy { +public: + static void initialize(); + +private: + WebPlatformStrategies(); + + // WebCore::PlatformStrategies + virtual WebCore::CookiesStrategy* createCookiesStrategy() OVERRIDE; + virtual WebCore::PluginStrategy* createPluginStrategy() OVERRIDE; + virtual WebCore::VisitedLinkStrategy* createVisitedLinkStrategy() OVERRIDE; + + // WebCore::CookiesStrategy + virtual void notifyCookiesChanged() OVERRIDE; + + // WebCore::PluginStrategy + virtual void refreshPlugins() OVERRIDE; + virtual void getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>&) OVERRIDE; + void populatePluginCache(); + + // WebCore::VisitedLinkStrategy + virtual bool isLinkVisited(WebCore::Page*, WebCore::LinkHash, const WebCore::KURL& baseURL, const WTF::AtomicString& attributeURL) OVERRIDE; + virtual void addVisitedLink(WebCore::Page*, WebCore::LinkHash) OVERRIDE; + + bool m_pluginCacheIsPopulated; + bool m_shouldRefreshPlugins; + Vector<WebCore::PluginInfo> m_cachedPlugins; +}; + +} // 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 000000000..940cb95d8 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp @@ -0,0 +1,138 @@ +/* + * 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 "config.h" +#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::Separator)); + 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. + PopupMenuStyle itemStyle = m_popupClient->itemStyle(i); + items.append(WebPopupItem(WebPopupItem::Item, m_popupClient->itemText(i), itemStyle.textDirection(), itemStyle.hasTextDirectionOverride(), 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, m_popupClient->menuStyle().textDirection(), 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() +{ +#if PLATFORM(WIN) + if (!m_page || !m_popupClient) + return; + + int selectedIndex = m_popupClient->selectedIndex(); + WebProcess::shared().connection()->send(Messages::WebPageProxy::SetPopupMenuSelectedIndex(selectedIndex), m_page->pageID()); +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h new file mode 100644 index 000000000..8e6625018 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h @@ -0,0 +1,72 @@ +/* + * 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(); + + WebPage* page() { return m_page; } + + void disconnectFromPage() { m_page = 0; } + void didChangeSelectedIndex(int newIndex); + void setTextForIndex(int newIndex); +#if PLATFORM(GTK) + WebCore::PopupMenuClient* client() const { return m_popupClient; } +#endif + + virtual void show(const WebCore::IntRect&, WebCore::FrameView*, int index) OVERRIDE; + virtual void hide() OVERRIDE; + virtual void updateFromElement() OVERRIDE; + virtual void disconnectClient() OVERRIDE; + +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 000000000..39a7f32e6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010, 2011 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 "config.h" +#include "WebSearchPopupMenu.h" + +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <wtf/text/AtomicString.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& name, const Vector<String>& searchItems) +{ + if (name.isEmpty()) + return; + + WebPage* page = m_popup->page(); + if (!page) + return; + + WebProcess::shared().connection()->send(Messages::WebPageProxy::SaveRecentSearches(name, searchItems), page->pageID()); +} + +void WebSearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& resultItems) +{ + if (name.isEmpty()) + return; + + WebPage* page = m_popup->page(); + if (!page) + return; + + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::LoadRecentSearches(name), Messages::WebPageProxy::LoadRecentSearches::Reply(resultItems), page->pageID()); +} + +bool WebSearchPopupMenu::enabled() +{ + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.h new file mode 100644 index 000000000..f8910f784 --- /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() OVERRIDE; + virtual void saveRecentSearches(const WTF::AtomicString& name, const Vector<String>& searchItems) OVERRIDE; + virtual void loadRecentSearches(const WTF::AtomicString& name, Vector<String>& searchItems) OVERRIDE; + virtual bool enabled() OVERRIDE; + +private: + WebSearchPopupMenu(WebPage*, WebCore::PopupMenuClient*); + + RefPtr<WebPopupMenu> m_popup; +}; + +} + +#endif // WebSearchPopupMenu_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebContextMenuClientEfl.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebContextMenuClientEfl.cpp new file mode 100644 index 000000000..62d7b847f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebContextMenuClientEfl.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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/efl/WebEditorClientEfl.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebEditorClientEfl.cpp new file mode 100644 index 000000000..163ff2045 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebEditorClientEfl.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebEditorClient.h" + +#include "Frame.h" +#include "PlatformKeyboardEvent.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/KeyboardEvent.h> +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) +{ + notImplemented(); +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent*) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebErrorsEfl.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebErrorsEfl.cpp new file mode 100644 index 000000000..417823612 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebErrorsEfl.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebErrors.h" + +#include <WebCore/NotImplemented.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +using namespace WebCore; + +namespace WebKit { + +ResourceError cancelledError(const ResourceRequest& request) +{ + notImplemented(); + return ResourceError(); +} + +ResourceError blockedError(const ResourceRequest& request) +{ + notImplemented(); + return ResourceError(); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + notImplemented(); + return ResourceError(); +} + +ResourceError interruptedForPolicyChangeError(const ResourceRequest& request) +{ + notImplemented(); + return ResourceError(); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + notImplemented(); + return ResourceError(); +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + notImplemented(); + return ResourceError(); +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + notImplemented(); + return ResourceError(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebFrameNetworkingContext.h new file mode 100644 index 000000000..cfb509eae --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebFrameNetworkingContext.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#include "WebFrame.h" + +#include <WebCore/FrameNetworkingContext.h> + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebKit::WebFrame*) + { + return 0; + } + +private: + WebFrameNetworkingContext(WebKit::WebFrame* frame) + : WebCore::FrameNetworkingContext(frame->coreFrame()) + { + } + + virtual WTF::String userAgent() const; + virtual WTF::String referrer() const; + + WTF::String m_userAgent; +}; + +#endif // WebFrameNetworkingContext_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebPopupMenuEfl.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebPopupMenuEfl.cpp new file mode 100644 index 000000000..d1c31224a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/efl/WebPopupMenuEfl.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData&) +{ + notImplemented(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp new file mode 100644 index 000000000..d91520e99 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebContextMenuClientGtk.cpp @@ -0,0 +1,57 @@ +/* + * 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 "config.h" +#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/gtk/WebDragClientGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp new file mode 100644 index 000000000..d808ed44b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebDragClientGtk.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebDragClient.h" + +#include "ArgumentCodersGtk.h" +#include "ShareableBitmap.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include <WebCore/ClipboardGtk.h> +#include <WebCore/DragData.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/PlatformContextCairo.h> + +using namespace WebCore; + +namespace WebKit { + +static PassRefPtr<ShareableBitmap> convertCairoSurfaceToShareableBitmap(cairo_surface_t* surface) +{ + if (!surface) + return 0; + + IntSize imageSize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface)); + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha); + OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + + graphicsContext->platformContext()->drawSurfaceToContext(surface, IntRect(IntPoint(), imageSize), IntRect(IntPoint(), imageSize), graphicsContext.get()); + return bitmap.release(); +} + +void WebDragClient::startDrag(DragImageRef dragImage, const IntPoint& clientPosition, const IntPoint& globalPosition, Clipboard* clipboard, Frame*, bool) +{ + RefPtr<ShareableBitmap> bitmap = convertCairoSurfaceToShareableBitmap(dragImage); + ShareableBitmap::Handle handle; + + // If we have a bitmap, but cannot create a handle to it, we fail early. + if (bitmap && !bitmap->createHandle(handle)) + return; + + RefPtr<DataObjectGtk> dataObject = reinterpret_cast<ClipboardGtk*>(clipboard)->dataObject(); + DragData dragData(dataObject.get(), clientPosition, globalPosition, clipboard->sourceOperation()); + m_page->send(Messages::WebPageProxy::StartDrag(dragData, handle)); +} + +}; // namespace WebKit. diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp new file mode 100644 index 000000000..964a395c9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "WebEditorClient.h" + +#include "Frame.h" +#include "PlatformKeyboardEvent.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/KeyboardEvent.h> +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void WebEditorClient::getEditorCommandsForKeyEvent(const KeyboardEvent* event, Vector<WTF::String>& pendingEditorCommands) +{ + ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent); + + /* First try to interpret the command in the UI and get the commands. + UI needs to receive event type because only knows current NativeWebKeyboardEvent.*/ + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetEditorCommandsForKeyEvent(event->type()), + Messages::WebPageProxy::GetEditorCommandsForKeyEvent::Reply(pendingEditorCommands), + m_page->pageID(), CoreIPC::Connection::NoTimeout); +} + +bool WebEditorClient::executePendingEditorCommands(Frame* frame, Vector<WTF::String> pendingEditorCommands, bool allowTextInsertion) +{ + Vector<Editor::Command> commands; + for (size_t i = 0; i < pendingEditorCommands.size(); i++) { + Editor::Command command = frame->editor()->command(pendingEditorCommands.at(i).utf8().data()); + if (command.isTextInsertion() && !allowTextInsertion) + return false; + + commands.append(command); + } + + for (size_t i = 0; i < commands.size(); i++) { + if (!commands.at(i).execute()) + return false; + } + + return true; +} + +void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) +{ + Node* node = event->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + + const PlatformKeyboardEvent* platformEvent = event->keyEvent(); + if (!platformEvent) + return; + + Vector<WTF::String> pendingEditorCommands; + getEditorCommandsForKeyEvent(event, pendingEditorCommands); + if (!pendingEditorCommands.isEmpty()) { + + // During RawKeyDown events if an editor command will insert text, defer + // the insertion until the keypress event. We want keydown to bubble up + // through the DOM first. + if (platformEvent->type() == PlatformEvent::RawKeyDown) { + if (executePendingEditorCommands(frame, pendingEditorCommands, false)) + event->setDefaultHandled(); + + return; + } + + // Only allow text insertion commands if the current node is editable. + if (executePendingEditorCommands(frame, pendingEditorCommands, frame->editor()->canEdit())) { + event->setDefaultHandled(); + return; + } + } + + // Don't allow text insertion for nodes that cannot edit. + if (!frame->editor()->canEdit()) + return; + + // This is just a normal text insertion, so wait to execute the insertion + // until a keypress event happens. This will ensure that the insertion will not + // be reflected in the contents of the field until the keyup DOM event. + if (event->type() == eventNames().keypressEvent) { + + // FIXME: Add IM support + // https://bugs.webkit.org/show_bug.cgi?id=55946 + frame->editor()->insertText(platformEvent->text(), event); + event->setDefaultHandled(); + + } else { + // Don't insert null or control characters as they can result in unexpected behaviour + if (event->charCode() < ' ') + return; + + // Don't insert anything if a modifier is pressed + if (platformEvent->ctrlKey() || platformEvent->altKey()) + return; + + if (frame->editor()->insertText(platformEvent->text(), event)) + event->setDefaultHandled(); + } +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent*) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebErrorsGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebErrorsGtk.cpp new file mode 100644 index 000000000..8375d067a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebErrorsGtk.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebErrors.h" + +#include <WebCore/ErrorsGtk.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +using namespace WebCore; + +namespace WebKit { + +ResourceError cancelledError(const ResourceRequest& request) +{ + return WebCore::cancelledError(request); +} + +ResourceError blockedError(const ResourceRequest& request) +{ + return WebCore::blockedError(request); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return WebCore::cannotShowURLError(request); +} + +ResourceError interruptedForPolicyChangeError(const ResourceRequest& request) +{ + return WebCore::interruptedForPolicyChangeError(request); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return WebCore::cannotShowMIMETypeError(response); +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + return WebCore::fileDoesNotExistError(response); +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + return WebCore::pluginWillHandleLoadError(response); +} + +} // 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 000000000..d67be5d4a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebFrameNetworkingContext.h @@ -0,0 +1,53 @@ +/* + * 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 "WebFrame.h" + +#include <WebCore/FrameNetworkingContext.h> + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebKit::WebFrame*) + { + return 0; + } + +private: + WebFrameNetworkingContext(WebKit::WebFrame* frame) + : WebCore::FrameNetworkingContext(frame->coreFrame()) + { + } + + 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 000000000..154b0223a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebPopupMenuGtk.cpp @@ -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. + */ + +#include "config.h" +#include "WebPopupMenu.h" + +#include "PlatformPopupMenuData.h" +#include <WebCore/NotImplemented.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 000000000..84b7d50e9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm @@ -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. + */ + +#import "config.h" +#import "WebContextMenuClient.h" + +#import "DictionaryPopupInfo.h" +#import "WebCoreArgumentCoders.h" +#import "WebPage.h" +#import "WebPageProxyMessages.h" +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/Page.h> +#import <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +void WebContextMenuClient::lookUpInDictionary(Frame* frame) +{ + m_page->performDictionaryLookupForSelection(DictionaryPopupInfo::ContextMenu, frame, frame->selection()->selection()); +} + +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; + + m_page->send(Messages::WebPageProxy::SearchWithSpotlight(selectedString)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm new file mode 100644 index 000000000..1cfa3c000 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm @@ -0,0 +1,334 @@ +/* + * 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 "config.h" +#import "WebDragClient.h" + +#import "PasteboardTypes.h" +#import "ShareableBitmap.h" +#import "WebCoreArgumentCoders.h" +#import "WebPage.h" +#import "WebPageProxyMessages.h" +#import <WebCore/CachedImage.h> +#import <WebCore/DOMElementInternal.h> +#import <WebCore/DOMPrivate.h> +#import <WebCore/DragController.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/GraphicsContext.h> +#import <WebCore/LegacyWebArchive.h> +#import <WebCore/RenderImage.h> +#import <WebCore/ResourceHandle.h> +#import <WebCore/StringTruncator.h> +#import <WebKit/WebArchive.h> +#import <WebKit/WebKitNSStringExtras.h> +#import <WebKit/WebNSFileManagerExtras.h> +#import <WebKit/WebNSPasteboardExtras.h> +#import <WebKit/WebNSURLExtras.h> +#import <WebKitSystemInterface.h> +#import <wtf/StdLibExtras.h> + +using namespace WebCore; +using namespace WebKit; + +// Internal AppKit class. If the pasteboard handling was in the same process +// that called the dragImage method, this would be created automatically. +// Create it explicitly because dragImage is called in the UI process. +@interface NSFilePromiseDragSource : NSObject +{ + id _dragSource; + char _unknownFields[256]; +} +- (id)initWithSource:(id)dragSource; +- (void)setTypes:(NSArray *)types onPasteboard:(NSPasteboard *)pasteboard; +@end + +@interface WKPasteboardFilePromiseOwner : NSFilePromiseDragSource +@end + +@interface WKPasteboardOwner : NSObject +{ + CachedResourceHandle<WebCore::CachedImage> _image; +} +- (id)initWithImage:(WebCore::CachedImage*)image; +@end + +namespace WebKit { + +static PassRefPtr<ShareableBitmap> convertImageToBitmap(NSImage *image) +{ + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize([image size]), ShareableBitmap::SupportsAlpha); + OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + + RetainPtr<NSGraphicsContext> savedContext = [NSGraphicsContext currentContext]; + + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:graphicsContext->platformContext() flipped:YES]]; + [image drawInRect:NSMakeRect(0, 0, bitmap->size().width(), bitmap->size().height()) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; + + [NSGraphicsContext setCurrentContext:savedContext.get()]; + + return bitmap.release(); +} + +void WebDragClient::startDrag(RetainPtr<NSImage> image, const IntPoint& point, const IntPoint&, Clipboard*, Frame* frame, bool linkDrag) +{ + RefPtr<ShareableBitmap> bitmap = convertImageToBitmap(image.get()); + ShareableBitmap::Handle handle; + if (!bitmap->createHandle(handle)) + return; + + // FIXME: Seems this message should be named StartDrag, not SetDragImage. + m_page->send(Messages::WebPageProxy::SetDragImage(frame->view()->contentsToWindow(point), handle, linkDrag)); +} + +static WebCore::CachedImage* cachedImage(Element* element) +{ + RenderObject* renderer = element->renderer(); + if (!renderer) + return 0; + if (!renderer->isRenderImage()) + return 0; + WebCore::CachedImage* image = toRenderImage(renderer)->cachedImage(); + if (!image || image->errorOccurred()) + return 0; + return image; +} + +static NSArray *arrayForURLsWithTitles(NSURL *URL, NSString *title) +{ + return [NSArray arrayWithObjects:[NSArray arrayWithObject:[URL _web_originalDataAsString]], + [NSArray arrayWithObject:[title _webkit_stringByTrimmingWhitespace]], nil]; +} + +void WebDragClient::declareAndWriteDragImage(NSPasteboard *pasteboard, DOMElement *element, NSURL *URL, NSString *title, WebCore::Frame*) +{ + ASSERT(element); + ASSERT(pasteboard && pasteboard == [NSPasteboard pasteboardWithName:NSDragPboard]); + + Element* coreElement = core(element); + + WebCore::CachedImage* image = cachedImage(coreElement); + + NSString *extension = @""; + if (image) { + extension = image->image()->filenameExtension(); + if (![extension length]) + return; + } + + if (![title length]) { + title = [[URL path] lastPathComponent]; + if (![title length]) + title = [URL _web_userVisibleString]; + } + + RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreElement); + + RetainPtr<NSMutableArray> types(AdoptNS, [[NSMutableArray alloc] initWithObjects:NSFilesPromisePboardType, nil]); + [types.get() addObjectsFromArray:archive ? PasteboardTypes::forImagesWithArchive() : PasteboardTypes::forImages()]; + + m_pasteboardOwner.adoptNS([[WKPasteboardOwner alloc] initWithImage:image]); + m_filePromiseOwner.adoptNS([(WKPasteboardFilePromiseOwner *)[WKPasteboardFilePromiseOwner alloc] initWithSource:m_pasteboardOwner.get()]); + + [pasteboard declareTypes:types.get() owner:m_pasteboardOwner.leakRef()]; + + [pasteboard setPropertyList:[NSArray arrayWithObject:extension] forType:NSFilesPromisePboardType]; + + [m_filePromiseOwner.get() setTypes:[pasteboard propertyListForType:NSFilesPromisePboardType] onPasteboard:pasteboard]; + + [URL writeToPasteboard:pasteboard]; + + [pasteboard setString:[URL _web_originalDataAsString] forType:PasteboardTypes::WebURLPboardType]; + + [pasteboard setString:title forType:PasteboardTypes::WebURLNamePboardType]; + + [pasteboard setString:[URL _web_userVisibleString] forType:NSStringPboardType]; + + [pasteboard setPropertyList:arrayForURLsWithTitles(URL, title) forType:PasteboardTypes::WebURLsWithTitlesPboardType]; + + if (archive) + [pasteboard setData:(NSData *)archive->rawDataRepresentation().get() forType:PasteboardTypes::WebArchivePboardType]; +} + +void WebDragClient::dragEnded() +{ + // The draggedImage method releases its responder; we must retain the WKPasteboardFilePromiseOwner an extra time to balance the release + // inside of the function. + [m_filePromiseOwner.get() retain]; + + // The drag source we care about here is NSFilePromiseDragSource, which doesn't look at + // the arguments. It's OK to just pass arbitrary constant values, so we just pass all zeroes. + [m_filePromiseOwner.get() draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationNone]; + + m_pasteboardOwner = nullptr; + m_filePromiseOwner = nullptr; +} + +} // namespace WebKit + +@implementation WKPasteboardFilePromiseOwner + +- (id)initWithSource:(id)dragSource +{ + self = [super initWithSource:dragSource]; + if (!self) + return nil; + [_dragSource retain]; + return self; +} + +- (void)dealloc +{ + [_dragSource release]; + [super dealloc]; +} + +// The AppKit implementation of copyDropDirectory gets the current pasteboard in +// a way that only works in the process where the drag is initiated. We supply +// an implementation that gets the pasteboard by name instead. +- (CFURLRef)copyDropDirectory +{ + PasteboardRef pasteboard; + OSStatus status = PasteboardCreate((CFStringRef)NSDragPboard, &pasteboard); + if (status != noErr || !pasteboard) + return 0; + CFURLRef location = 0; + status = PasteboardCopyPasteLocation(pasteboard, &location); + CFRelease(pasteboard); + if (status != noErr || !location) + return 0; + CFMakeCollectable(location); + return location; +} + +@end + +@implementation WKPasteboardOwner + +static CachedImageClient* promisedDataClient() +{ + static CachedImageClient* client = new CachedImageClient; + return client; +} + +- (void)clearImage +{ + if (!_image) + return; + _image->removeClient(promisedDataClient()); + _image = 0; +} + +- (id)initWithImage:(WebCore::CachedImage*)image +{ + self = [super init]; + if (!self) + return nil; + + _image = image; + if (image) + image->addClient(promisedDataClient()); + return self; +} + +- (void)dealloc +{ + [self clearImage]; + [super dealloc]; +} + +- (void)finalize +{ + [self clearImage]; + [super finalize]; +} + +- (void)pasteboard:(NSPasteboard *)pasteboard provideDataForType:(NSString *)type +{ + if ([type isEqual:NSTIFFPboardType]) { + if (_image) { + if (Image* image = _image->image()) + [pasteboard setData:(NSData *)image->getTIFFRepresentation() forType:NSTIFFPboardType]; + [self clearImage]; + } + return; + } + // FIXME: Handle RTFD here. +} + +- (void)pasteboardChangedOwner:(NSPasteboard *)pasteboard +{ + [self clearImage]; + CFRelease(self); // Balanced by the leakRef that WebDragClient::declareAndWriteDragImage does when making this pasteboard owner. +} + +static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension) +{ + NSString *extensionAsSuffix = [@"." stringByAppendingString:extension]; + return [filename _webkit_hasCaseInsensitiveSuffix:extensionAsSuffix] + || ([extension _webkit_isCaseInsensitiveEqualToString:@"jpeg"] + && [filename _webkit_hasCaseInsensitiveSuffix:@".jpg"]); +} + +- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination +{ + NSFileWrapper *wrapper = nil; + NSURL *draggingImageURL = nil; + + if (_image) { + if (SharedBuffer* buffer = _image->CachedResource::data()) { + NSData *data = buffer->createNSData(); + NSURLResponse *response = _image->response().nsURLResponse(); + draggingImageURL = [response URL]; + wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease]; + NSString* filename = [response suggestedFilename]; + NSString* trueExtension(_image->image()->filenameExtension()); + if (!matchesExtensionOrEquivalent(filename, trueExtension)) + filename = [[filename stringByAppendingString:@"."] stringByAppendingString:trueExtension]; + [wrapper setPreferredFilename:filename]; + } + } + + // FIXME: Do we need to handle the case where we do not have a CachedImage? + // WebKit1 had code for this case. + + if (!wrapper) { + LOG_ERROR("Failed to create image file."); + return nil; + } + + // FIXME: Report an error if we fail to create a file. + NSString *path = [[dropDestination path] stringByAppendingPathComponent:[wrapper preferredFilename]]; + path = [[NSFileManager defaultManager] _webkit_pathWithUniqueFilenameForPath:path]; + if (![wrapper writeToFile:path atomically:NO updateFilenames:YES]) + LOG_ERROR("Failed to create image file via -[NSFileWrapper writeToFile:atomically:updateFilenames:] at path %@", path); + + if (draggingImageURL) + [[NSFileManager defaultManager] _webkit_setMetadataURL:[draggingImageURL absoluteString] referrer:nil atPath:path]; + + return [NSArray arrayWithObject:[path lastPathComponent]]; +} + +@end diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm new file mode 100644 index 000000000..9a27be83c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm @@ -0,0 +1,265 @@ +/* + * 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 "config.h" +#import "WebEditorClient.h" + +#import "WebCoreArgumentCoders.h" +#import "WebPage.h" +#import "WebFrame.h" +#import "WebPageProxyMessages.h" +#import "WebProcess.h" +#import <WebCore/ArchiveResource.h> +#import <WebCore/DocumentFragment.h> +#import <WebCore/DOMDocumentFragmentInternal.h> +#import <WebCore/DOMDocumentInternal.h> +#import <WebCore/FocusController.h> +#import <WebCore/Frame.h> +#import <WebCore/KeyboardEvent.h> +#import <WebCore/NotImplemented.h> +#import <WebCore/Page.h> +#import <WebKit/WebResource.h> +#import <WebKit/WebNSURLExtras.h> + +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->handleEditingKeyboardEvent(event, false)) + event->setDefaultHandled(); +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event) +{ + if (m_page->handleEditingKeyboardEvent(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; + Document* document = m_page->mainFrame() ? m_page->mainFrame()->document() : 0; + DOMDocumentFragment* fragment = [string _documentFromRange:NSMakeRange(0, [string length]) + document:kit(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(); +} + + +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() +{ + bool isShowing; + m_page->sendSync(Messages::WebPageProxy::SubstitutionsPanelIsShowing(), Messages::WebPageProxy::SubstitutionsPanelIsShowing::Reply(isShowing)); + return isShowing; +} + +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, WebCore::TextCheckingTypeMask 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_SNOW_LEOPARD) +void WebEditorClient::showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType type, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) +{ + m_page->send(Messages::WebPageProxy::ShowCorrectionPanel(type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings)); +} + +void WebEditorClient::dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel reason) +{ + m_page->send(Messages::WebPageProxy::DismissCorrectionPanel(reason)); +} + +String WebEditorClient::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingCorrectionPanel reason) +{ + String result; + m_page->sendSync(Messages::WebPageProxy::DismissCorrectionPanelSoon(reason), Messages::WebPageProxy::DismissCorrectionPanelSoon::Reply(result)); + return result; +} + +void WebEditorClient::recordAutocorrectionResponse(EditorClient::AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString) +{ + m_page->send(Messages::WebPageProxy::RecordAutocorrectionResponse(responseType, replacedString, replacementString)); +} +#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 000000000..6dea6a063 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm @@ -0,0 +1,90 @@ +/* + * 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 "config.h" +#import "WebErrors.h" + +#import "WebError.h" +#import "WKError.h" +#import <WebCore/LocalizedStrings.h> +#import <WebCore/ResourceRequest.h> +#import <WebCore/ResourceResponse.h> + +using namespace WebCore; +using namespace WebKit; + +namespace WebKit { + +static RetainPtr<NSError> createNSError(NSString* domain, int code, NSURL *URL) +{ + NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: + URL, @"NSErrorFailingURLKey", + [URL absoluteString], @"NSErrorFailingURLStringKey", + nil]; + + return RetainPtr<NSError>(AdoptNS, [[NSError alloc] initWithDomain:domain code:code userInfo:userInfo]); +} + +// Use NSError's if available. + +ResourceError cancelledError(const ResourceRequest& request) +{ + return ResourceError(createNSError(NSURLErrorDomain, NSURLErrorCancelled, request.url()).get()); +} + +ResourceError fileDoesNotExistError(const ResourceResponse& response) +{ + return ResourceError(createNSError(NSURLErrorDomain, NSURLErrorFileDoesNotExist, response.url()).get()); +} + + +// Otherwise, fallback to our own errors. + +ResourceError blockedError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotUseRestrictedPort, request.url(), WEB_UI_STRING("Not allowed to use restricted network port", "WebKitErrorCannotUseRestrictedPort description")); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotShowURL, request.url(), WEB_UI_STRING("The URL can’t be shown", "WebKitErrorCannotShowURL description")); +} + +ResourceError interruptedForPolicyChangeError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeFrameLoadInterruptedByPolicyChange, request.url(), WEB_UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description")); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotShowMIMEType, response.url(), WEB_UI_STRING("Content with specified MIME type can’t be shown", "WebKitErrorCannotShowMIMEType description")); +} + +ResourceError pluginWillHandleLoadError(const ResourceResponse& response) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodePlugInWillHandleLoad, response.url(), WEB_UI_STRING("Plug-in handled load", "WebKitErrorPlugInWillHandleLoad description")); +} + +} // 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 000000000..32a0591ef --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.h @@ -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. +*/ + +#ifndef WebFrameNetworkingContext_h +#define WebFrameNetworkingContext_h + +#include "WebFrame.h" + +#import <WebCore/FrameNetworkingContext.h> + +namespace WebKit { + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebFrame* frame) + { + return adoptRef(new WebFrameNetworkingContext(frame)); + } + +private: + WebFrameNetworkingContext(WebFrame* frame) + : WebCore::FrameNetworkingContext(frame->coreFrame()) + { + } + + 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 000000000..a95447174 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebFrameNetworkingContext.mm @@ -0,0 +1,52 @@ +/* + 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 "config.h" +#import "WebFrameNetworkingContext.h" + +#import <WebCore/FrameLoaderClient.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()->client()->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 000000000..1c9d7b6c3 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#import "config.h" +#import "WebPopupMenu.h" + +#import "PlatformPopupMenuData.h" +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/PopupMenuClient.h> + +using namespace WebCore; + +namespace WebKit { + +void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData& data) +{ + // FIXME: font will be nil here for custom fonts, we should fix that. + NSFont *font = m_popupClient->menuStyle().font().primaryFont()->getNSFont(); + if (!font) + return; + + CFDictionaryRef fontDescriptorAttributes = (CFDictionaryRef)[[font fontDescriptor] fontAttributes]; + if (!fontDescriptorAttributes) + return; + + data.fontInfo.fontAttributeDictionary = fontDescriptorAttributes; + data.shouldPopOver = m_popupClient->shouldPopOver(); +} + +} // 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 000000000..da0c2dd67 --- /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 000000000..29c4ac3ee --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009, 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. + */ + +#import "config.h" +#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(CGPatternCreateWithImageAndTransform); + 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(GetVerticalGlyphsForCharacters); + INIT(GetHTTPPipeliningPriority); + INIT(GetMIMETypeForExtension); + INIT(GetNSURLResponseLastModifiedDate); + INIT(SignedPublicKeyAndChallengeString); + INIT(GetPreferredExtensionForMIMEType); + INIT(GetUserToBaseCTM); + INIT(GetWheelEventDeltas); + INIT(GetNSEventKeyChar); + INIT(HitTestMediaUIPart); + INIT(InitializeMaximumHTTPConnectionCountPerHost); + INIT(MeasureMediaUIPart); + INIT(MediaControllerThemeAvailable); + INIT(PopupMenu); + INIT(QTIncludeOnlyModernMediaFileTypes); + INIT(QTMovieDataRate); + INIT(QTMovieDisableComponent); + INIT(QTMovieGetType); + INIT(QTMovieHasClosedCaptions); + INIT(QTMovieMaxTimeLoaded); + INIT(QTMovieMaxTimeLoadedChangeNotification); + INIT(QTMovieMaxTimeSeekable); + INIT(QTMovieResolvedURL); + INIT(QTMovieSelectPreferredAlternates); + INIT(QTMovieSetShowClosedCaptions); + INIT(QTMovieViewSetDrawSynchronously); + INIT(QTGetSitesInMediaDownloadCache); + INIT(QTClearMediaDownloadCacheForSite); + INIT(QTClearMediaDownloadCache); + INIT(SetBaseCTM); + INIT(SetCGFontRenderingMode); + INIT(SetCONNECTProxyAuthorizationForStream); + INIT(SetCONNECTProxyForStream); + INIT(SetCookieStoragePrivateBrowsingEnabled); + INIT(SetDragImage); + INIT(SetHTTPPipeliningMaximumPriority); + INIT(SetHTTPPipeliningPriority); + INIT(SetHTTPPipeliningMinimumFastLanePriority); + INIT(SetNSURLConnectionDefersCallbacks); + INIT(SetNSURLRequestShouldContentSniff); + INIT(SetPatternPhaseInUserSpace); + INIT(SetUpFontCache); + INIT(SignalCFReadStreamEnd); + INIT(SignalCFReadStreamError); + INIT(SignalCFReadStreamHasBytes); + INIT(CreatePrivateStorageSession); + INIT(CopyRequestWithStorageSession); + INIT(CopyHTTPCookieStorage); + INIT(GetHTTPCookieAcceptPolicy); + INIT(SetHTTPCookieAcceptPolicy); + INIT(HTTPCookiesForURL); + INIT(SetHTTPCookiesForURL); + INIT(DeleteHTTPCookie); + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + INIT(IOSurfaceContextCreate); + INIT(IOSurfaceContextCreateImage); + INIT(CreateCTTypesetterWithUniCharProviderAndOptions); + INIT(RecommendedScrollerStyle); + INIT(ExecutableWasLinkedOnOrBeforeSnowLeopard); + INIT(CopyDefaultSearchProviderDisplayName); + INIT(AVAssetResolvedURL); + INIT(Cursor); +#else + INIT(GetHyphenationLocationBeforeIndex); + INIT(GetNSEventMomentumPhase); +#endif +#if USE(CFNETWORK) + INIT(GetDefaultHTTPCookieStorage); + INIT(CopyCredentialFromCFPersistentStorage); + INIT(SetCFURLRequestShouldContentSniff); + INIT(CFURLRequestCopyHTTPRequestBodyParts); + INIT(CFURLRequestSetHTTPRequestBodyParts); + INIT(SetRequestStorageSession); +#endif + + INIT(GetAXTextMarkerTypeID); + INIT(GetAXTextMarkerRangeTypeID); + INIT(CreateAXTextMarker); + INIT(GetBytesFromAXTextMarker); + INIT(CreateAXTextMarkerRange); + INIT(CopyAXTextMarkerRangeStart); + INIT(CopyAXTextMarkerRangeEnd); + INIT(AccessibilityHandleFocusChanged); + INIT(CreateAXUIElementRef); + INIT(UnregisterUniqueIdForElement); + + INIT(GetCFURLResponseMIMEType); + INIT(GetCFURLResponseURL); + INIT(GetCFURLResponseHTTPResponse); + INIT(CopyCFURLResponseSuggestedFilename); + INIT(SetCFURLResponseMIMEType); + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + INIT(CreateVMPressureDispatchOnMainQueue); +#endif + +#if !defined(BUILDING_ON_SNOW_LEOPARD) && !defined(BUILDING_ON_LION) + INIT(GetMacOSXVersionString); +#endif + + }); +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp new file mode 100644 index 000000000..a09ec1960 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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/qt/WebDragClientQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp new file mode 100644 index 000000000..bbdb635b3 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp @@ -0,0 +1,68 @@ +/* + * 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 "config.h" +#include "WebDragClient.h" + +#include "ClipboardQt.h" +#include "DragData.h" +#include "GraphicsContext.h" +#include "ShareableBitmap.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" + +using namespace WebCore; + +namespace WebKit { + +static PassRefPtr<ShareableBitmap> convertQPixmapToShareableBitmap(QPixmap* pixmap) +{ + if (!pixmap) + return 0; + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(pixmap->size()), ShareableBitmap::SupportsAlpha); + OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + + graphicsContext->platformContext()->drawPixmap(0, 0, *pixmap); + return bitmap.release(); +} + +void WebDragClient::startDrag(DragImageRef dragImage, const IntPoint& clientPosition, const IntPoint& globalPosition, Clipboard* clipboard, Frame*, bool) +{ + QMimeData* clipboardData = static_cast<ClipboardQt*>(clipboard)->clipboardData(); + DragOperation dragOperationMask = clipboard->sourceOperation(); + static_cast<ClipboardQt*>(clipboard)->invalidateWritableData(); + DragData dragData(clipboardData, clientPosition, globalPosition, dragOperationMask); + + RefPtr<ShareableBitmap> bitmap = convertQPixmapToShareableBitmap(dragImage); + ShareableBitmap::Handle handle; + if (bitmap && !bitmap->createHandle(handle)) + return; + + m_page->send(Messages::WebPageProxy::StartDrag(dragData, handle)); +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp new file mode 100644 index 000000000..8684f1c83 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp @@ -0,0 +1,87 @@ +/* + * 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 "config.h" +#include "WebErrors.h" + +#include "WKError.h" +#include "WebError.h" +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +#include <QCoreApplication> +#include <QNetworkReply> + +using namespace WebCore; + +namespace WebKit { + +ResourceError cancelledError(const ResourceRequest& request) +{ + ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().string(), + QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8)); + error.setIsCancellation(true); + return error; +} + +ResourceError blockedError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotUseRestrictedPort, request.url().string(), + QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError cannotShowURLError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotShowURL, request.url().string(), + QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError interruptedForPolicyChangeError(const ResourceRequest& request) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeFrameLoadInterruptedByPolicyChange, request.url().string(), + QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0, QCoreApplication::UnicodeUTF8)); +} + +ResourceError cannotShowMIMETypeError(const ResourceResponse& response) +{ + return ResourceError(WebError::webKitErrorDomain(), kWKErrorCodeCannotShowMIMEType, 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(WebError::webKitErrorDomain(), kWKErrorCodePlugInWillHandleLoad, 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 000000000..070d479d0 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp @@ -0,0 +1,71 @@ +/* + 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 "WebFrame.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <QNetworkAccessManager> +#include <QObject> +#include <QVariant> + +namespace WebCore { + +WebFrameNetworkingContext::WebFrameNetworkingContext(WebKit::WebFrame* frame) + : FrameNetworkingContext(frame->coreFrame()) + , m_originatingObject(adoptPtr(new QObject)) + , m_mimeSniffingEnabled(true) +{ + // The page ID is needed later for HTTP authentication and SSL errors. + m_originatingObject->setProperty("pageID", qulonglong(frame->page()->pageID())); +} + +WebFrameNetworkingContext::~WebFrameNetworkingContext() +{ +} + +PassRefPtr<WebFrameNetworkingContext> WebFrameNetworkingContext::create(WebKit::WebFrame* frame) +{ + return adoptRef(new WebFrameNetworkingContext(frame)); +} + +QObject* WebFrameNetworkingContext::originatingObject() const +{ + return m_originatingObject.get(); +} + +QNetworkAccessManager* WebFrameNetworkingContext::networkAccessManager() const +{ + return WebKit::WebProcess::shared().networkAccessManager(); +} + +bool WebFrameNetworkingContext::mimeSniffingEnabled() const +{ + return m_mimeSniffingEnabled; +} + +bool WebFrameNetworkingContext::thirdPartyCookiePolicyPermission(const QUrl &) const +{ + // ### TODO. Used QWebSettings in WK1. + return true; +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h new file mode 100644 index 000000000..7ec62640f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h @@ -0,0 +1,52 @@ +/* + 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 <wtf/OwnPtr.h> + +namespace WebKit { +class WebFrame; +} + +namespace WebCore { + +class WebFrameNetworkingContext : public FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebKit::WebFrame*); + virtual QObject* originatingObject() const; + +private: + WebFrameNetworkingContext(WebKit::WebFrame*); + virtual ~WebFrameNetworkingContext(); + + virtual QNetworkAccessManager* networkAccessManager() const; + virtual bool mimeSniffingEnabled() const; + virtual bool thirdPartyCookiePolicyPermission(const QUrl&) const; + + OwnPtr<QObject> m_originatingObject; + bool m_mimeSniffingEnabled; +}; + +} + +#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 000000000..b21f06ccf --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebPopupMenuQt.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 "config.h" +#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 000000000..c866c1de2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebContextMenuClientWin.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 "config.h" +#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/WebDragClientWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp new file mode 100644 index 000000000..554a55b6c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragClientWin.cpp @@ -0,0 +1,101 @@ +/* + * 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 "config.h" +#include "WebDragClient.h" + +#include "ShareableBitmap.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include <WebCore/BitmapInfo.h> +#include <WebCore/COMPtr.h> +#include <WebCore/ClipboardWin.h> +#include <WebCore/DragController.h> +#include <WebCore/Frame.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> +#include <shlobj.h> + +using namespace WebCore; + +namespace WebKit { + +static DWORD draggingSourceOperationMaskToDragCursors(DragOperation op) +{ + DWORD result = DROPEFFECT_NONE; + if (op == DragOperationEvery) + return DROPEFFECT_COPY | DROPEFFECT_LINK | DROPEFFECT_MOVE; + if (op & DragOperationCopy) + result |= DROPEFFECT_COPY; + if (op & DragOperationLink) + result |= DROPEFFECT_LINK; + if (op & DragOperationMove) + result |= DROPEFFECT_MOVE; + if (op & DragOperationGeneric) + result |= DROPEFFECT_MOVE; + return result; +} + +void WebDragClient::startDrag(DragImageRef image, const IntPoint& imageOrigin, const IntPoint& dragPoint, Clipboard* clipboard, Frame* frame, bool isLink) +{ + COMPtr<IDataObject> dataObject = static_cast<ClipboardWin*>(clipboard)->dataObject(); + + if (!dataObject) + return; + + OwnPtr<HDC> bitmapDC = adoptPtr(CreateCompatibleDC(0)); + BITMAPINFO bitmapInfo = {0}; + bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + GetDIBits(bitmapDC.get(), image, 0, 0, 0, &bitmapInfo, DIB_RGB_COLORS); + if (bitmapInfo.bmiHeader.biSizeImage <= 0) + bitmapInfo.bmiHeader.biSizeImage = bitmapInfo.bmiHeader.biWidth * abs(bitmapInfo.bmiHeader.biHeight) * (bitmapInfo.bmiHeader.biBitCount + 7) / 8; + + RefPtr<SharedMemory> memoryBuffer = SharedMemory::create(bitmapInfo.bmiHeader.biSizeImage); + + bitmapInfo.bmiHeader.biCompression = BI_RGB; + GetDIBits(bitmapDC.get(), image, 0, bitmapInfo.bmiHeader.biHeight, memoryBuffer->data(), &bitmapInfo, DIB_RGB_COLORS); + + SharedMemory::Handle handle; + if (!memoryBuffer->createHandle(handle, SharedMemory::ReadOnly)) + return; + DWORD okEffect = draggingSourceOperationMaskToDragCursors(m_page->corePage()->dragController()->sourceDragOperation()); + + DragData dragData(dataObject.get(), IntPoint(), IntPoint(), DragOperationNone); + int fileSize; + String pathname; + dragData.getDragFileDescriptorData(fileSize, pathname); + RefPtr<SharedMemory> fileContentBuffer; + SharedMemory::Handle fileContentHandle; + if (fileSize) { + fileContentBuffer = SharedMemory::create(fileSize); + dragData.getDragFileContentData(fileSize, fileContentBuffer->data()); + fileContentBuffer->createHandle(fileContentHandle, SharedMemory::ReadOnly); + } + + m_page->send(Messages::WebPageProxy::StartDragDrop(imageOrigin, dragPoint, okEffect, dragData.dragDataMap(), (uint64_t)fileSize, pathname, fileContentHandle, IntSize(bitmapInfo.bmiHeader.biWidth, bitmapInfo.bmiHeader.biHeight), handle, isLink), m_page->pageID()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragSource.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragSource.cpp new file mode 100644 index 000000000..b4f1414eb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragSource.cpp @@ -0,0 +1,87 @@ +/* + * 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 COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebDragSource.h" + +#include <WebCore/Cursor.h> +#include <WebCore/DragActions.h> +#include <WebCore/EventHandler.h> +#include <WebCore/Frame.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformMouseEvent.h> +#include <wtf/CurrentTime.h> + +using namespace WebCore; + +PassRefPtr<WebDragSource> WebDragSource::createInstance() +{ + return adoptRef(new WebDragSource); +} + +WebDragSource::WebDragSource() +{ +} + +HRESULT WebDragSource::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDropSource)) { + *ppvObject = this; + AddRef(); + + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG WebDragSource::AddRef(void) +{ + ref(); + return refCount(); +} + +ULONG WebDragSource::Release(void) +{ + deref(); + return refCount(); +} + +HRESULT WebDragSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfState) +{ + if (fEscapePressed) + return DRAGDROP_S_CANCEL; + + if (grfState & (MK_LBUTTON | MK_RBUTTON)) + return S_OK; + + return DRAGDROP_S_DROP; +} + +HRESULT WebDragSource::GiveFeedback(DWORD dwEffect) +{ + return DRAGDROP_S_USEDEFAULTCURSORS; +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragSource.h b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragSource.h new file mode 100644 index 000000000..c2c5f3f76 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebDragSource.h @@ -0,0 +1,46 @@ +/* + * 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 COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebDragSource_h +#define WebDragSource_h + +#include <WTF/RefCounted.h> +#include <WebCore/COMPtr.h> +#include <objidl.h> + +class WebDragSource : public IDropSource, public RefCounted<WebDragSource> { +public: + static PassRefPtr<WebDragSource> createInstance(); + +private: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfState); + virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect); + WebDragSource(); +}; + +#endif // !WebDragSource_h diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebErrorsWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebErrorsWin.cpp new file mode 100644 index 000000000..668604339 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebErrorsWin.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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 interruptedForPolicyChangeError(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 000000000..6b20c1f97 --- /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 000000000..5f3f55765 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebFrameNetworkingContext.h @@ -0,0 +1,49 @@ +/* + 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 "WebFrame.h" + +#include <WebCore/FrameNetworkingContext.h> +#include <WebCore/ResourceError.h> +#include <WebCore/ResourceRequest.h> + +class WebFrameNetworkingContext : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<WebFrameNetworkingContext> create(WebKit::WebFrame* frame) + { + return adoptRef(new WebFrameNetworkingContext(frame)); + } + +private: + WebFrameNetworkingContext(WebKit::WebFrame* frame) + : WebCore::FrameNetworkingContext(frame->coreFrame()) + { + } + + 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 000000000..7427f118a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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().fontMetrics().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<float>(popupWidth, ceilf(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); + + IntSize backingStoreSize(backingStoreWidth, (itemCount * data.m_itemHeight)); + data.m_notSelectedBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha); + data.m_selectedBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha); + + 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 < 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(); + // FIXME: defaultWritingDirection should return a TextDirection not a Unicode::Direction. + TextDirection direction = itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft ? RTL : LTR; + TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, direction); + + 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.fontMetrics().ascent() + (itemRect.height() - itemFont.fontMetrics().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 000000000..03a8cb5c5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebKitMain.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CommandLine.h" + +#include "PluginProcessMain.h" +#include "ProcessLauncher.h" +#include "WebProcessMain.h" +#include <wtf/text/CString.h> + +#if PLATFORM(MAC) +#include <objc/objc-auto.h> +#elif PLATFORM(WIN) +#include <shlwapi.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) + +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); +} + +#ifndef NDEBUG +static void pauseProcessIfNeeded(HMODULE module) +{ + // 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))) + return; + + wchar_t path[MAX_PATH]; + DWORD length = ::GetModuleFileNameW(module, path, WTF_ARRAY_LENGTH(path)); + if (!length || length == WTF_ARRAY_LENGTH(path)) + return; + + wchar_t* startOfFilename = ::PathFindFileNameW(path); + String filenameString(startOfFilename, length - (startOfFilename - path)); + + String message = L"You can now attach a debugger to " + filenameString + L". You can use the same debugger for " + filenameString + L" and the UI process, if desired. Click OK when you are ready for " + filenameString + L" to continue."; + String title = filenameString + L" has launched"; + ::MessageBoxW(0, message.charactersWithNullTermination(), title.charactersWithNullTermination(), MB_OK | MB_ICONINFORMATION); +} +#endif + +extern "C" __declspec(dllexport) +int WebKitMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrCmdLine, int nCmdShow) +{ +#ifndef NDEBUG + pauseProcessIfNeeded(hInstance); +#endif + + enableDataExecutionPrevention(); + + enableTerminationOnHeapCorruption(); + + disableUserModeCallbackExceptionFilter(); + + CommandLine commandLine; + if (!commandLine.parse(lpstrCmdLine)) + return EXIT_FAILURE; + + return WebKitMain(commandLine); +} + +#endif diff --git a/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.cpp new file mode 100644 index 000000000..7c93dae7f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DecoderAdapter.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 "config.h" +#include "DecoderAdapter.h" + +#include "DataReference.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) +{ + CoreIPC::DataReference dataReference; + if (!m_decoder.decodeVariableLengthByteArray(dataReference)) + return false; + + bytes = dataReference.vector(); + return true; +} + +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 000000000..bd34ea8d3 --- /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 000000000..9d42ce4a5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.cpp @@ -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. + */ + +#include "config.h" +#include "DrawingArea.h" + +// Subclasses +#include "DrawingAreaImpl.h" + +#if USE(TILED_BACKING_STORE) +#include "TiledDrawingArea.h" +#endif + +#if PLATFORM(MAC) +#include "TiledCoreAnimationDrawingArea.h" +#endif + +#include "WebPageCreationParameters.h" + +namespace WebKit { + +PassOwnPtr<DrawingArea> DrawingArea::create(WebPage* webPage, const WebPageCreationParameters& parameters) +{ + switch (parameters.drawingAreaType) { + case DrawingAreaTypeImpl: + return DrawingAreaImpl::create(webPage, parameters); +#if USE(TILED_BACKING_STORE) + case DrawingAreaTypeTiled: + return adoptPtr(new TiledDrawingArea(webPage)); +#endif +#if PLATFORM(MAC) + case DrawingAreaTypeTiledCoreAnimation: + return TiledCoreAnimationDrawingArea::create(webPage, parameters); +#endif + } + + return nullptr; +} + +DrawingArea::DrawingArea(DrawingAreaType type, WebPage* webPage) + : m_type(type) + , 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 000000000..ffbbdbb57 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.h @@ -0,0 +1,122 @@ +/* + * 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/FloatPoint.h> +#include <WebCore/IntRect.h> +#include <wtf/Noncopyable.h> +#include <wtf/PassOwnPtr.h> + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebCore { + class GraphicsLayer; +} + +namespace WebKit { + +class WebPage; +struct WebPageCreationParameters; + +#if PLATFORM(WIN) +struct WindowGeometry; +#endif + +class DrawingArea { + WTF_MAKE_NONCOPYABLE(DrawingArea); + +public: + static PassOwnPtr<DrawingArea> create(WebPage*, const WebPageCreationParameters&); + virtual ~DrawingArea(); + + void didReceiveDrawingAreaMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + + virtual void setNeedsDisplay(const WebCore::IntRect&) = 0; + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) = 0; + + // FIXME: These should be pure virtual. + virtual void pageBackgroundTransparencyChanged() { } + virtual void forceRepaint() { } + virtual void setLayerTreeStateIsFrozen(bool) { } + virtual bool layerTreeStateIsFrozen() const { return false; } + + virtual void didInstallPageOverlay() { } + virtual void didUninstallPageOverlay() { } + virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&) { } + virtual void pageCustomRepresentationChanged() { } + + virtual void setPaintingEnabled(bool) { } + +#if USE(ACCELERATED_COMPOSITING) + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0; + virtual void scheduleCompositingLayerSync() = 0; +#if USE(TEXTURE_MAPPER) + virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*) = 0; +#endif +#endif + +#if PLATFORM(WIN) + virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&) = 0; +#endif + +protected: + DrawingArea(DrawingAreaType, WebPage*); + + DrawingAreaType m_type; + WebPage* m_webPage; + +private: + // CoreIPC message handlers. + // FIXME: These should be pure virtual. + virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset) { } + virtual void didUpdate() { } + virtual void suspendPainting() { } + virtual void resumePainting() { } + +#if PLATFORM(MAC) + // Used by TiledCoreAnimationDrawingArea. + virtual void updateGeometry(const WebCore::IntSize& viewSize) { } +#endif + +#if USE(TILED_BACKING_STORE) + virtual void setSize(const WebCore::IntSize& viewSize) { } + virtual void setVisibleContentRectAndScale(const WebCore::IntRect&, float) { } + virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&) { } + virtual void setContentsScale(float scale) { } + virtual void renderNextFrame() { } + virtual void takeSnapshot(const WebCore::IntSize& targetSize, const WebCore::IntRect& contentsRect) { } +#endif +}; + +} // 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 000000000..48c3e1ae5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in @@ -0,0 +1,42 @@ +# 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 { + UpdateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, WebCore::IntSize size, WebCore::IntSize scrollOffset) + DidUpdate() + SuspendPainting() + ResumePainting() + PageCustomRepresentationChanged() + +#if PLATFORM(MAC) + // Used by TiledCoreAnimationDrawingArea. + UpdateGeometry(WebCore::IntSize viewSize) +#endif + +#if USE(TILED_BACKING_STORE) + SetSize(WebCore::IntSize viewSize) + SetVisibleContentRectAndScale(WebCore::IntRect visibleContentRect, float scale) + SetVisibleContentRectTrajectoryVector(WebCore::FloatPoint trajectoryVector) + RenderNextFrame() + TakeSnapshot(WebCore::IntSize size, WebCore::IntRect contentsRect) +#endif +} diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp new file mode 100644 index 000000000..e281d3652 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp @@ -0,0 +1,679 @@ +/* + * 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 "config.h" +#include "DrawingAreaImpl.h" + +#include "DrawingAreaProxyMessages.h" +#include "LayerTreeContext.h" +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include "WebPage.h" +#include "WebPageCreationParameters.h" +#include "WebProcess.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> +#include <WebCore/Settings.h> + +using namespace WebCore; +using namespace std; + +namespace WebKit { + +PassOwnPtr<DrawingAreaImpl> DrawingAreaImpl::create(WebPage* webPage, const WebPageCreationParameters& parameters) +{ + return adoptPtr(new DrawingAreaImpl(webPage, parameters)); +} + +DrawingAreaImpl::~DrawingAreaImpl() +{ + if (m_layerTreeHost) + m_layerTreeHost->invalidate(); +} + +DrawingAreaImpl::DrawingAreaImpl(WebPage* webPage, const WebPageCreationParameters& parameters) + : DrawingArea(DrawingAreaTypeImpl, webPage) + , m_backingStoreStateID(0) + , m_isPaintingEnabled(true) + , m_inUpdateBackingStoreState(false) + , m_shouldSendDidUpdateBackingStoreState(false) + , m_isWaitingForDidUpdate(false) + , m_compositingAccordingToProxyMessages(false) + , m_layerTreeStateIsFrozen(false) + , m_wantsToExitAcceleratedCompositingMode(false) + , m_isPaintingSuspended(!parameters.isVisible) + , m_alwaysUseCompositing(false) + , m_displayTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::displayTimerFired) + , m_exitCompositingTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::exitAcceleratedCompositingMode) +{ + if (webPage->corePage()->settings()->acceleratedDrawingEnabled()) + m_alwaysUseCompositing = true; + + if (m_alwaysUseCompositing) + enterAcceleratedCompositingMode(0); +} + +void DrawingAreaImpl::setNeedsDisplay(const IntRect& rect) +{ + if (!m_isPaintingEnabled) + return; + + IntRect dirtyRect = rect; + dirtyRect.intersect(m_webPage->bounds()); + + if (dirtyRect.isEmpty()) + return; + + if (m_layerTreeHost) { + ASSERT(m_dirtyRegion.isEmpty()); + + m_layerTreeHost->setNonCompositedContentsNeedDisplay(dirtyRect); + return; + } + + if (m_webPage->mainFrameHasCustomRepresentation()) + return; + + m_dirtyRegion.unite(dirtyRect); + scheduleDisplay(); +} + +void DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollOffset) +{ + if (!m_isPaintingEnabled) + return; + + if (m_layerTreeHost) { + ASSERT(m_scrollRect.isEmpty()); + ASSERT(m_scrollOffset.isEmpty()); + ASSERT(m_dirtyRegion.isEmpty()); + + m_layerTreeHost->scrollNonCompositedContents(scrollRect, scrollOffset); + return; + } + + if (m_webPage->mainFrameHasCustomRepresentation()) + return; + + 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_scrollOffset = 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, scrollOffset), scrollRect); + + // And add them back. + m_dirtyRegion.unite(movedDirtyRegionInScrollRect); + } + + // Compute the scroll repaint region. + Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollOffset)); + + m_dirtyRegion.unite(scrollRepaintRegion); + scheduleDisplay(); + + m_scrollRect = scrollRect; + m_scrollOffset += scrollOffset; +} + +void DrawingAreaImpl::setLayerTreeStateIsFrozen(bool isFrozen) +{ + if (m_layerTreeStateIsFrozen == isFrozen) + return; + + m_layerTreeStateIsFrozen = isFrozen; + + if (m_layerTreeHost) + m_layerTreeHost->setLayerFlushSchedulingEnabled(!isFrozen); + + if (isFrozen) + m_exitCompositingTimer.stop(); + else if (m_wantsToExitAcceleratedCompositingMode) + exitAcceleratedCompositingModeSoon(); +} + +void DrawingAreaImpl::forceRepaint() +{ + setNeedsDisplay(m_webPage->bounds()); + + m_webPage->layoutIfNeeded(); + + if (m_layerTreeHost) { + // FIXME: We need to do the same work as the layerHostDidFlushLayers function here, + // but clearly it doesn't make sense to call the function with that name. + // Consider refactoring and renaming it. + if (m_compositingAccordingToProxyMessages) + m_layerTreeHost->forceRepaint(); + else { + // Call setShouldNotifyAfterNextScheduledLayerFlush(false) here to + // prevent layerHostDidFlushLayers() from being called a second time. + m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false); + layerHostDidFlushLayers(); + } + return; + } + + m_isWaitingForDidUpdate = false; + display(); +} + +void DrawingAreaImpl::didInstallPageOverlay() +{ + if (m_layerTreeHost) + m_layerTreeHost->didInstallPageOverlay(); +} + +void DrawingAreaImpl::didUninstallPageOverlay() +{ + if (m_layerTreeHost) + m_layerTreeHost->didUninstallPageOverlay(); + + setNeedsDisplay(m_webPage->bounds()); +} + +void DrawingAreaImpl::setPageOverlayNeedsDisplay(const IntRect& rect) +{ + if (m_layerTreeHost) { + m_layerTreeHost->setPageOverlayNeedsDisplay(rect); + return; + } + + setNeedsDisplay(rect); +} + +void DrawingAreaImpl::pageCustomRepresentationChanged() +{ + if (!m_alwaysUseCompositing) + return; + + if (m_webPage->mainFrameHasCustomRepresentation()) { + if (m_layerTreeHost) + exitAcceleratedCompositingMode(); + } else if (!m_layerTreeHost) + enterAcceleratedCompositingMode(0); +} + +void DrawingAreaImpl::setPaintingEnabled(bool paintingEnabled) +{ + m_isPaintingEnabled = paintingEnabled; +} + +void DrawingAreaImpl::layerHostDidFlushLayers() +{ + ASSERT(m_layerTreeHost); + + m_layerTreeHost->forceRepaint(); + + if (m_shouldSendDidUpdateBackingStoreState && !exitAcceleratedCompositingModePending()) { + sendDidUpdateBackingStoreState(); + return; + } + + if (!m_layerTreeHost) + return; + +#if USE(ACCELERATED_COMPOSITING) + ASSERT(!m_compositingAccordingToProxyMessages); + if (!exitAcceleratedCompositingModePending()) { + m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext())); + m_compositingAccordingToProxyMessages = true; + } +#endif +} + +void DrawingAreaImpl::setRootCompositingLayer(GraphicsLayer* graphicsLayer) +{ + // FIXME: Instead of using nested if statements, we should keep a compositing state + // enum in the DrawingAreaImpl object and have a changeAcceleratedCompositingState function + // that takes the new state. + + if (graphicsLayer) { + if (!m_layerTreeHost) { + // We're actually entering accelerated compositing mode. + enterAcceleratedCompositingMode(graphicsLayer); + } else { + // We're already in accelerated compositing mode, but the root compositing layer changed. + + m_exitCompositingTimer.stop(); + m_wantsToExitAcceleratedCompositingMode = false; + + // If we haven't sent the EnterAcceleratedCompositingMode message, make sure that the + // layer tree host calls us back after the next layer flush so we can send it then. + if (!m_compositingAccordingToProxyMessages) + m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true); + + m_layerTreeHost->setRootCompositingLayer(graphicsLayer); + } + } else { + if (m_layerTreeHost) { + m_layerTreeHost->setRootCompositingLayer(0); + if (!m_alwaysUseCompositing) { + // We'll exit accelerated compositing mode on a timer, to avoid re-entering + // compositing code via display() and layout. + // If we're leaving compositing mode because of a setSize, it is safe to + // exit accelerated compositing mode right away. + if (m_inUpdateBackingStoreState) + exitAcceleratedCompositingMode(); + else + exitAcceleratedCompositingModeSoon(); + } + } + } +} + +void DrawingAreaImpl::scheduleCompositingLayerSync() +{ + if (!m_layerTreeHost) + return; + m_layerTreeHost->scheduleLayerFlush(); +} + +void DrawingAreaImpl::updateBackingStoreState(uint64_t stateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset) +{ + ASSERT(!m_inUpdateBackingStoreState); + m_inUpdateBackingStoreState = true; + + ASSERT_ARG(stateID, stateID >= m_backingStoreStateID); + if (stateID != m_backingStoreStateID) { + m_backingStoreStateID = stateID; + m_shouldSendDidUpdateBackingStoreState = true; + + m_webPage->setDeviceScaleFactor(deviceScaleFactor); + m_webPage->setSize(size); + m_webPage->layoutIfNeeded(); + m_webPage->scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset); + + if (m_layerTreeHost) { + m_layerTreeHost->deviceScaleFactorDidChange(); + m_layerTreeHost->sizeDidChange(size); + } else + m_dirtyRegion = m_webPage->bounds(); + } else { + ASSERT(size == m_webPage->size()); + if (!m_shouldSendDidUpdateBackingStoreState) { + // We've already sent a DidUpdateBackingStoreState message for this state. We have nothing more to do. + m_inUpdateBackingStoreState = false; + return; + } + } + + // The UI process has updated to a new backing store state. Any Update messages we sent before + // this point will be ignored. We wait to set this to false until after updating the page's + // size so that any displays triggered by the relayout will be ignored. If we're supposed to + // respond to the UpdateBackingStoreState message immediately, we'll do a display anyway in + // sendDidUpdateBackingStoreState; otherwise we shouldn't do one right now. + m_isWaitingForDidUpdate = false; + + if (respondImmediately) { + // Make sure to resume painting if we're supposed to respond immediately, otherwise we'll just + // send back an empty UpdateInfo struct. + if (m_isPaintingSuspended) + resumePainting(); + + sendDidUpdateBackingStoreState(); + } + + m_inUpdateBackingStoreState = false; +} + +void DrawingAreaImpl::sendDidUpdateBackingStoreState() +{ + ASSERT(!m_isWaitingForDidUpdate); + ASSERT(m_shouldSendDidUpdateBackingStoreState); + + m_shouldSendDidUpdateBackingStoreState = false; + + UpdateInfo updateInfo; + + if (!m_isPaintingSuspended && !m_layerTreeHost) + display(updateInfo); + + LayerTreeContext layerTreeContext; + + if (m_isPaintingSuspended || m_layerTreeHost) { + updateInfo.viewSize = m_webPage->size(); + updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor(); + + if (m_layerTreeHost) { + layerTreeContext = m_layerTreeHost->layerTreeContext(); + + // We don't want the layer tree host to notify after the next scheduled + // layer flush because that might end up sending an EnterAcceleratedCompositingMode + // message back to the UI process, but the updated layer tree context + // will be sent back in the DidUpdateBackingStoreState message. + m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false); + m_layerTreeHost->forceRepaint(); + } + } + + m_webPage->send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext)); + m_compositingAccordingToProxyMessages = !layerTreeContext.isEmpty(); +} + +void DrawingAreaImpl::didUpdate() +{ + // We might get didUpdate messages from the UI process even after we've + // entered accelerated compositing mode. Ignore them. + if (m_layerTreeHost) + return; + + m_isWaitingForDidUpdate = false; + + // Display if needed. We call displayTimerFired here since it will throttle updates to 60fps. + displayTimerFired(); +} + +void DrawingAreaImpl::suspendPainting() +{ + ASSERT(!m_isPaintingSuspended); + + if (m_layerTreeHost) + m_layerTreeHost->pauseRendering(); + + m_isPaintingSuspended = true; + m_displayTimer.stop(); + + m_webPage->corePage()->suspendScriptedAnimations(); +} + +void DrawingAreaImpl::resumePainting() +{ + if (!m_isPaintingSuspended) { + // FIXME: We can get a call to resumePainting when painting is not suspended. + // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>. + return; + } + + if (m_layerTreeHost) + m_layerTreeHost->resumeRendering(); + + m_isPaintingSuspended = false; + + // FIXME: We shouldn't always repaint everything here. + setNeedsDisplay(m_webPage->bounds()); + + m_webPage->corePage()->resumeScriptedAnimations(); +} + +void DrawingAreaImpl::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer) +{ + m_exitCompositingTimer.stop(); + m_wantsToExitAcceleratedCompositingMode = false; + + ASSERT(!m_layerTreeHost); + + m_layerTreeHost = LayerTreeHost::create(m_webPage); + if (!m_inUpdateBackingStoreState) + m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true); + + m_layerTreeHost->setRootCompositingLayer(graphicsLayer); + + // Non-composited content will now be handled exclusively by the layer tree host. + m_dirtyRegion = Region(); + m_scrollRect = IntRect(); + m_scrollOffset = IntSize(); + m_displayTimer.stop(); + m_isWaitingForDidUpdate = false; +} + +void DrawingAreaImpl::exitAcceleratedCompositingMode() +{ + if (m_alwaysUseCompositing && !m_webPage->mainFrameHasCustomRepresentation()) + return; + + ASSERT(!m_layerTreeStateIsFrozen); + + m_exitCompositingTimer.stop(); + m_wantsToExitAcceleratedCompositingMode = false; + + ASSERT(m_layerTreeHost); + + m_layerTreeHost->invalidate(); + m_layerTreeHost = nullptr; + m_dirtyRegion = m_webPage->bounds(); + + if (m_inUpdateBackingStoreState) + return; + + if (m_shouldSendDidUpdateBackingStoreState) { + sendDidUpdateBackingStoreState(); + return; + } + + UpdateInfo updateInfo; + if (m_isPaintingSuspended) { + updateInfo.viewSize = m_webPage->size(); + updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor(); + } else + display(updateInfo); + +#if USE(ACCELERATED_COMPOSITING) + // Send along a complete update of the page so we can paint the contents right after we exit the + // accelerated compositing mode, eliminiating flicker. + if (m_compositingAccordingToProxyMessages) { + m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo)); + m_compositingAccordingToProxyMessages = false; + } else { + // If we left accelerated compositing mode before we sent an EnterAcceleratedCompositingMode message to the + // UI process, we still need to let it know about the new contents, so send an Update message. + m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo)); + } +#endif +} + +void DrawingAreaImpl::exitAcceleratedCompositingModeSoon() +{ + if (m_layerTreeStateIsFrozen) { + m_wantsToExitAcceleratedCompositingMode = true; + return; + } + + if (exitAcceleratedCompositingModePending()) + return; + + m_exitCompositingTimer.startOneShot(0); +} + +void DrawingAreaImpl::scheduleDisplay() +{ + ASSERT(!m_layerTreeHost); + + if (m_isWaitingForDidUpdate) + return; + + if (m_isPaintingSuspended) + return; + + if (m_dirtyRegion.isEmpty()) + return; + + if (m_displayTimer.isActive()) + return; + + m_displayTimer.startOneShot(0); +} + +void DrawingAreaImpl::displayTimerFired() +{ + display(); +} + +void DrawingAreaImpl::display() +{ + ASSERT(!m_layerTreeHost); + ASSERT(!m_isWaitingForDidUpdate); + ASSERT(!m_inUpdateBackingStoreState); + + if (m_isPaintingSuspended) + return; + + if (m_dirtyRegion.isEmpty()) + return; + + if (m_shouldSendDidUpdateBackingStoreState) { + sendDidUpdateBackingStoreState(); + return; + } + + UpdateInfo updateInfo; + display(updateInfo); + + if (m_layerTreeHost) { + // The call to update caused layout which turned on accelerated compositing. + // Don't send an Update message in this case. + return; + } + + m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo)); + m_isWaitingForDidUpdate = true; +} + +static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects) +{ + const size_t rectThreshold = 10; + const double wastedSpaceThreshold = 0.75; + + 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(); + + double wastedSpace = 1 - (static_cast<double>(rectsArea) / boundsArea); + + return wastedSpace <= wastedSpaceThreshold; +} + +#if !PLATFORM(WIN) +PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap) +{ + return bitmap->createGraphicsContext(); +} +#endif + +void DrawingAreaImpl::display(UpdateInfo& updateInfo) +{ + ASSERT(!m_isPaintingSuspended); + ASSERT(!m_layerTreeHost); + ASSERT(!m_webPage->size().isEmpty()); + + // FIXME: It would be better if we could avoid painting altogether when there is a custom representation. + if (m_webPage->mainFrameHasCustomRepresentation()) { + // ASSUMPTION: the custom representation will be painting the dirty region for us. + m_dirtyRegion = Region(); + return; + } + + m_webPage->layoutIfNeeded(); + + // The layout may have put the page into accelerated compositing mode. If the LayerTreeHost is + // in charge of displaying, we have nothing more to do. + if (m_layerTreeHost) + return; + + updateInfo.viewSize = m_webPage->size(); + updateInfo.deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor(); + + IntRect bounds = m_dirtyRegion.bounds(); + ASSERT(m_webPage->bounds().contains(bounds)); + + IntSize bitmapSize = bounds.size(); + float deviceScaleFactor = m_webPage->corePage()->deviceScaleFactor(); + bitmapSize.scale(deviceScaleFactor); + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bitmapSize, ShareableBitmap::SupportsAlpha); + if (!bitmap) + return; + + if (!bitmap->createHandle(updateInfo.bitmapHandle)) + return; + + Vector<IntRect> rects = m_dirtyRegion.rects(); + + if (shouldPaintBoundsRect(bounds, rects)) { + rects.clear(); + rects.append(bounds); + } + + updateInfo.scrollRect = m_scrollRect; + updateInfo.scrollOffset = m_scrollOffset; + + m_dirtyRegion = Region(); + m_scrollRect = IntRect(); + m_scrollOffset = IntSize(); + + OwnPtr<GraphicsContext> graphicsContext = createGraphicsContext(bitmap.get()); + graphicsContext->applyDeviceScaleFactor(deviceScaleFactor); + + updateInfo.updateRectBounds = bounds; + + graphicsContext->translate(-bounds.x(), -bounds.y()); + + for (size_t i = 0; i < rects.size(); ++i) { + m_webPage->drawRect(*graphicsContext, rects[i]); + if (m_webPage->hasPageOverlay()) + m_webPage->drawPageOverlay(*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(); +} + +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +void DrawingAreaImpl::didReceiveLayerTreeHostMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (m_layerTreeHost) + m_layerTreeHost->didReceiveLayerTreeHostMessage(connection, messageID, arguments); +} +#endif + + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h new file mode 100644 index 000000000..0dabf603a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h @@ -0,0 +1,143 @@ +/* + * 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 "LayerTreeHost.h" +#include "RunLoop.h" +#include <WebCore/Region.h> + +namespace WebCore { + class GraphicsContext; +} + +namespace WebKit { + +class ShareableBitmap; +class UpdateInfo; + +class DrawingAreaImpl : public DrawingArea { +public: + static PassOwnPtr<DrawingAreaImpl> create(WebPage*, const WebPageCreationParameters&); + virtual ~DrawingAreaImpl(); + + void layerHostDidFlushLayers(); + +private: + DrawingAreaImpl(WebPage*, const WebPageCreationParameters&); + + // DrawingArea + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); + virtual void setLayerTreeStateIsFrozen(bool); + virtual bool layerTreeStateIsFrozen() const { return m_layerTreeStateIsFrozen; } + virtual void forceRepaint(); + + virtual void didInstallPageOverlay(); + virtual void didUninstallPageOverlay(); + virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&); + + virtual void setPaintingEnabled(bool); + + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + virtual void scheduleCompositingLayerSync(); + +#if PLATFORM(WIN) + virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&); +#endif + +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) + virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +#endif + + // CoreIPC message handlers. + virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, float deviceScaleFactor, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset); + virtual void didUpdate(); + virtual void suspendPainting(); + virtual void resumePainting(); + + virtual void pageCustomRepresentationChanged(); + + void sendDidUpdateBackingStoreState(); + + void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*); + void exitAcceleratedCompositingModeSoon(); + bool exitAcceleratedCompositingModePending() const { return m_exitCompositingTimer.isActive(); } + void exitAcceleratedCompositingMode(); + + void scheduleDisplay(); + void displayTimerFired(); + void display(); + void display(UpdateInfo&); + PassOwnPtr<WebCore::GraphicsContext> createGraphicsContext(ShareableBitmap*); + + uint64_t m_backingStoreStateID; + + WebCore::Region m_dirtyRegion; + WebCore::IntRect m_scrollRect; + WebCore::IntSize m_scrollOffset; + + // Whether painting is enabled. If painting is disabled, any calls to setNeedsDisplay and scroll are ignored. + bool m_isPaintingEnabled; + + // Whether we're currently processing an UpdateBackingStoreState message. + bool m_inUpdateBackingStoreState; + + // When true, we should send an UpdateBackingStoreState message instead of any other messages + // we normally send to the UI process. + bool m_shouldSendDidUpdateBackingStoreState; + + // 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; + + // True between sending the 'enter compositing' messages, and the 'exit compositing' message. + bool m_compositingAccordingToProxyMessages; + + // When true, we maintain the layer tree in its current state by not leaving accelerated compositing mode + // and not scheduling layer flushes. + bool m_layerTreeStateIsFrozen; + + // True when we were asked to exit accelerated compositing mode but couldn't because layer tree + // state was frozen. + bool m_wantsToExitAcceleratedCompositingMode; + + // Whether painting is suspended. We'll still keep track of the dirty region but we + // won't paint until painting has resumed again. + bool m_isPaintingSuspended; + bool m_alwaysUseCompositing; + + RunLoop::Timer<DrawingAreaImpl> m_displayTimer; + RunLoop::Timer<DrawingAreaImpl> m_exitCompositingTimer; + + // The layer tree host that handles accelerated compositing. + RefPtr<LayerTreeHost> m_layerTreeHost; +}; + +} // 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 000000000..547b68d73 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EncoderAdapter.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 "config.h" +#include "EncoderAdapter.h" + +#include "DataReference.h" +#include "WebCoreArgumentCoders.h" + +namespace WebKit { + +EncoderAdapter::EncoderAdapter() + : m_encoder(CoreIPC::ArgumentEncoder::create(0)) +{ +} + +CoreIPC::DataReference EncoderAdapter::dataReference() const +{ + return CoreIPC::DataReference(m_encoder->buffer(), m_encoder->bufferSize()); +} + +void EncoderAdapter::encodeBytes(const uint8_t* bytes, size_t size) +{ + m_encoder->encodeVariableLengthByteArray(CoreIPC::DataReference(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 000000000..47de7afd5 --- /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 dataReference() 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/EventDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp new file mode 100644 index 000000000..6486587d0 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp @@ -0,0 +1,148 @@ +/* + * 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 "config.h" +#include "EventDispatcher.h" + +#include "RunLoop.h" +#include "WebEvent.h" +#include "WebEventConversion.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/Page.h> +#include <wtf/MainThread.h> + +#if ENABLE(THREADED_SCROLLING) +#include <WebCore/ScrollingCoordinator.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +EventDispatcher::EventDispatcher() +{ +} + +EventDispatcher::~EventDispatcher() +{ +} + +#if ENABLE(THREADED_SCROLLING) +void EventDispatcher::addScrollingCoordinatorForPage(WebPage* webPage) +{ + MutexLocker locker(m_scrollingCoordinatorsMutex); + + ASSERT(webPage->corePage()->scrollingCoordinator()); + ASSERT(!m_scrollingCoordinators.contains(webPage->pageID())); + m_scrollingCoordinators.set(webPage->pageID(), webPage->corePage()->scrollingCoordinator()); +} + +void EventDispatcher::removeScrollingCoordinatorForPage(WebPage* webPage) +{ + MutexLocker locker(m_scrollingCoordinatorsMutex); + ASSERT(m_scrollingCoordinators.contains(webPage->pageID())); + + m_scrollingCoordinators.remove(webPage->pageID()); +} +#endif + +void EventDispatcher::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage) +{ + if (messageID.is<CoreIPC::MessageClassEventDispatcher>()) { + didReceiveEventDispatcherMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage); + return; + } +} + +void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent) +{ +#if ENABLE(THREADED_SCROLLING) + MutexLocker locker(m_scrollingCoordinatorsMutex); + if (ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinators.get(pageID).get()) { + PlatformWheelEvent platformWheelEvent = platform(wheelEvent); + + if (scrollingCoordinator->handleWheelEvent(platformWheelEvent)) { + sendDidHandleEvent(pageID, wheelEvent); + return; + } + } +#endif + + RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchWheelEvent, this, pageID, wheelEvent)); +} + +#if ENABLE(GESTURE_EVENTS) +void EventDispatcher::gestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent) +{ +#if ENABLE(THREADED_SCROLLING) + MutexLocker locker(m_scrollingCoordinatorsMutex); + if (ScrollingCoordinator* scrollingCoordinator = m_scrollingCoordinators.get(pageID).get()) { + PlatformGestureEvent platformGestureEvent = platform(gestureEvent); + + if (scrollingCoordinator->handleGestureEvent(platformGestureEvent)) { + sendDidHandleEvent(pageID, gestureEvent); + return; + } + } +#endif + + RunLoop::main()->dispatch(bind(&EventDispatcher::dispatchGestureEvent, this, pageID, gestureEvent)); +} +#endif + +void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& wheelEvent) +{ + ASSERT(isMainThread()); + + WebPage* webPage = WebProcess::shared().webPage(pageID); + if (!webPage) + return; + + webPage->wheelEvent(wheelEvent); +} + +#if ENABLE(GESTURE_EVENTS) +void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent) +{ + ASSERT(isMainThread()); + + WebPage* webPage = WebProcess::shared().webPage(pageID); + if (!webPage) + return; + + webPage->gestureEvent(gestureEvent); +} +#endif + +#if ENABLE(THREADED_SCROLLING) +void EventDispatcher::sendDidHandleEvent(uint64_t pageID, const WebEvent& event) +{ + WebProcess::shared().connection()->send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(event.type()), true), pageID); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h new file mode 100644 index 000000000..7cd2f9550 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h @@ -0,0 +1,90 @@ +/* + * 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 EventDispatcher_h +#define EventDispatcher_h + +#include "Connection.h" +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/RefPtr.h> +#include <wtf/ThreadingPrimitives.h> + +namespace WebCore { + class ScrollingCoordinator; +} + +namespace WebKit { + +class WebEvent; +class WebPage; +class WebWheelEvent; + +#if ENABLE(GESTURE_EVENTS) +class WebGestureEvent; +#endif + +class EventDispatcher : public CoreIPC::Connection::QueueClient { + WTF_MAKE_NONCOPYABLE(EventDispatcher); + +public: + EventDispatcher(); + ~EventDispatcher(); + +#if ENABLE(THREADED_SCROLLING) + void addScrollingCoordinatorForPage(WebPage*); + void removeScrollingCoordinatorForPage(WebPage*); +#endif + +private: + // CoreIPC::Connection::QueueClient + virtual void didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, bool& didHandleMessage) OVERRIDE; + + // Implemented in generated EventDispatcherMessageReceiver.cpp + void didReceiveEventDispatcherMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage); + + // Message handlers + void wheelEvent(uint64_t pageID, const WebWheelEvent&); +#if ENABLE(GESTURE_EVENTS) + void gestureEvent(uint64_t pageID, const WebGestureEvent&); +#endif + + // This is called on the main thread. + void dispatchWheelEvent(uint64_t pageID, const WebWheelEvent&); +#if ENABLE(GESTURE_EVENTS) + void dispatchGestureEvent(uint64_t pageID, const WebGestureEvent&); +#endif + +#if ENABLE(THREADED_SCROLLING) + void sendDidHandleEvent(uint64_t pageID, const WebEvent&); + + Mutex m_scrollingCoordinatorsMutex; + HashMap<uint64_t, RefPtr<WebCore::ScrollingCoordinator> > m_scrollingCoordinators; +#endif +}; + +} // namespace WebKit + +#endif // EventDispatcher_h diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in new file mode 100644 index 000000000..a15571be5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in @@ -0,0 +1,30 @@ +# 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 -> EventDispatcher { + WheelEvent(uint64_t pageID, WebKit::WebWheelEvent event) DispatchOnConnectionQueue + +#if ENABLE(GESTURE_EVENTS) + GestureEvent(uint64_t pageID, WebKit::WebGestureEvent event) DispatchOnConnectionQueue +#endif + +} diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.cpp b/Source/WebKit2/WebProcess/WebPage/FindController.cpp new file mode 100644 index 000000000..9bdd80bb9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/FindController.cpp @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> + +using namespace std; +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) +{ + if (maxMatchCount == numeric_limits<unsigned>::max()) + --maxMatchCount; + + unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1); + m_webPage->corePage()->unmarkAllTextMatches(); + + // Check if we have more matches than allowed. + if (matchCount > maxMatchCount) + matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount); + + 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) { + if (maxMatchCount == numeric_limits<unsigned>::max()) + --maxMatchCount; + + 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, false); + } + + 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, false); + + hideFindIndicator(); +} + +bool FindController::updateFindIndicator(Frame* selectedFrame, bool isShowingOverlay, bool shouldAnimate) +{ + if (!selectedFrame) + return false; + + IntRect selectionRect = enclosingIntRect(selectedFrame->selection()->bounds()); + + // Selection rect can be empty for matches that are currently obscured from view. + if (selectionRect.isEmpty()) + return false; + + // We want the selection rect in window coordinates. + IntRect selectionRectInWindowCoordinates = selectedFrame->view()->contentsToWindow(selectionRect); + + Vector<FloatRect> textRects; + selectedFrame->selection()->getClippedVisibleTextRectangles(textRects); + + IntSize backingStoreSize = selectionRect.size(); + backingStoreSize.scale(m_webPage->corePage()->deviceScaleFactor()); + + // Create a backing store and paint the find indicator text into it. + RefPtr<ShareableBitmap> findIndicatorTextBackingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha); + if (!findIndicatorTextBackingStore) + return false; + + OwnPtr<GraphicsContext> graphicsContext = findIndicatorTextBackingStore->createGraphicsContext(); + graphicsContext->scale(FloatSize(m_webPage->corePage()->deviceScaleFactor(), m_webPage->corePage()->deviceScaleFactor())); + + IntRect paintRect = selectionRect; + paintRect.move(selectedFrame->view()->frameRect().x(), selectedFrame->view()->frameRect().y()); + paintRect.move(-selectedFrame->view()->scrollOffset()); + + graphicsContext->translate(-paintRect.x(), -paintRect.y()); + selectedFrame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorForceBlackText | PaintBehaviorFlattenCompositingLayers); + selectedFrame->document()->updateLayout(); + + selectedFrame->view()->paint(graphicsContext.get(), paintRect); + selectedFrame->view()->setPaintBehavior(PaintBehaviorNormal); + + ShareableBitmap::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, m_webPage->corePage()->deviceScaleFactor(), handle, !isShowingOverlay, shouldAnimate)); + m_isShowingFindIndicator = true; + + return true; +} + +void FindController::hideFindIndicator() +{ + if (!m_isShowingFindIndicator) + return; + + ShareableBitmap::Handle handle; + m_webPage->send(Messages::WebPageProxy::SetFindIndicator(FloatRect(), Vector<FloatRect>(), m_webPage->corePage()->deviceScaleFactor(), handle, false, true)); + m_isShowingFindIndicator = false; +} + +void FindController::showFindIndicatorInSelection() +{ + Frame* selectedFrame = m_webPage->corePage()->focusController()->focusedOrMainFrame(); + if (!selectedFrame) + return; + + updateFindIndicator(selectedFrame, false); +} + +void FindController::deviceScaleFactorDidChange() +{ + ASSERT(isShowingOverlay()); + + Frame* selectedFrame = frameWithSelection(m_webPage->corePage()); + if (!selectedFrame) + return; + + updateFindIndicator(selectedFrame, true, 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 float overlayBackgroundRed = 0.1; +static const float overlayBackgroundGreen = 0.1; +static const float overlayBackgroundBlue = 0.1; +static const float overlayBackgroundAlpha = 0.25; + +static Color overlayBackgroundColor(float fractionFadedIn) +{ + return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha * fractionFadedIn); +} + +static Color holeShadowColor(float fractionFadedIn) +{ + return Color(0.0f, 0.0f, 0.0f, fractionFadedIn); +} + +static Color holeFillColor(float fractionFadedIn) +{ + return Color(1.0f, 1.0f, 1.0f, fractionFadedIn); +} + +void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect) +{ + float fractionFadedIn = pageOverlay->fractionFadedIn(); + + Vector<IntRect> rects = rectsForTextMatches(); + + // Draw the background. + graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB); + + { + GraphicsContextStateSaver stateSaver(graphicsContext); + + graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB); + graphicsContext.setFillColor(holeFillColor(fractionFadedIn), 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.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 000000000..da03b79a7 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/FindController.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 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(); + void showFindIndicatorInSelection(); + + bool isShowingOverlay() const { return m_isShowingFindIndicator && m_findPageOverlay; } + + void deviceScaleFactorDidChange(); + +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, bool shouldAnimate = true); + +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/LayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp new file mode 100644 index 000000000..031c3fa6a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp @@ -0,0 +1,67 @@ +/* + * 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 "config.h" +#include "LayerTreeHost.h" + +#if USE(CA) +#if PLATFORM(MAC) +#include "LayerTreeHostCAMac.h" +#elif PLATFORM(WIN) +#include "LayerTreeHostCAWin.h" +#endif +#endif + +#if PLATFORM(QT) && USE(TEXTURE_MAPPER) +#include "qt/LayerTreeHostQt.h" +#endif + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<LayerTreeHost> LayerTreeHost::create(WebPage* webPage) +{ +#if PLATFORM(MAC) + return LayerTreeHostCAMac::create(webPage); +#elif PLATFORM(WIN) && HAVE(WKQCA) + return LayerTreeHostCAWin::create(webPage); +#elif PLATFORM(QT) && USE(TEXTURE_MAPPER) + return LayerTreeHostQt::create(webPage); +#else + return 0; +#endif +} + +LayerTreeHost::LayerTreeHost(WebPage* webPage) + : m_webPage(webPage) +{ +} + +LayerTreeHost::~LayerTreeHost() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h new file mode 100644 index 000000000..61fbe2fc3 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h @@ -0,0 +1,115 @@ +/* + * 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 LayerTreeHost_h +#define LayerTreeHost_h + +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace CoreIPC { +class ArgumentDecoder; +class Connection; +class MessageID; +} + +namespace WebCore { +class FloatPoint; +class IntRect; +class IntSize; +class GraphicsLayer; +} + +namespace WebKit { + +class LayerTreeContext; +class UpdateInfo; +class WebPage; + +#if PLATFORM(WIN) +struct WindowGeometry; +#endif + +class LayerTreeHost : public RefCounted<LayerTreeHost> { +public: + static PassRefPtr<LayerTreeHost> create(WebPage*); + virtual ~LayerTreeHost(); + + static bool supportsAcceleratedCompositing(); + + virtual const LayerTreeContext& layerTreeContext() = 0; + virtual void scheduleLayerFlush() = 0; + virtual void setLayerFlushSchedulingEnabled(bool) = 0; + virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool) = 0; + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0; + virtual void invalidate() = 0; + + virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&) = 0; + virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) = 0; + virtual void forceRepaint() = 0; + virtual void sizeDidChange(const WebCore::IntSize& newSize) = 0; + virtual void deviceScaleFactorDidChange() = 0; + + virtual void didInstallPageOverlay() = 0; + virtual void didUninstallPageOverlay() = 0; + virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&) = 0; + + virtual void pauseRendering() { } + virtual void resumeRendering() { } + +#if USE(TILED_BACKING_STORE) + virtual void setVisibleContentRectAndScale(const WebCore::IntRect&, float scale) { } + virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&) { } + virtual void setVisibleContentRectForLayer(int layerID, const WebCore::IntRect&) { } + virtual void renderNextFrame() { } + virtual void purgeBackingStores() { } + virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +#endif + +#if PLATFORM(WIN) + virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&) = 0; +#endif + +protected: + explicit LayerTreeHost(WebPage*); + + WebPage* m_webPage; + + +#if USE(TILED_BACKING_STORE) + bool m_waitingForUIProcess; +#endif +}; + +#if !PLATFORM(WIN) && !PLATFORM(QT) +inline bool LayerTreeHost::supportsAcceleratedCompositing() +{ + return true; +} +#endif + +} // namespace WebKit + +#endif // LayerTreeHost_h diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in new file mode 100644 index 000000000..d2e9c384e --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.messages.in @@ -0,0 +1,29 @@ +# +# Copyright (C) 2011 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. +# + + +#if USE(TILED_BACKING_STORE) +messages -> LayerTreeHost { + SetVisibleContentRectForLayer(int layerID, WebCore::IntRect visibleContentRect) + SetVisibleContentRectTrajectoryVector(WebCore::FloatPoint trajectoryVectory) + SetVisibleContentRectAndScale(WebCore::IntRect contentRect, float scale) + RenderNextFrame() + PurgeBackingStores() +} +#endif diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp new file mode 100644 index 000000000..aa32b6a09 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PageOverlay.h" + +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/Page.h> +#include <WebCore/ScrollbarTheme.h> + +using namespace WebCore; + +namespace WebKit { + +static const double fadeAnimationDuration = 0.2; +static const double fadeAnimationFrameRate = 30; + +PassRefPtr<PageOverlay> PageOverlay::create(Client* client) +{ + return adoptRef(new PageOverlay(client)); +} + +PageOverlay::PageOverlay(Client* client) + : m_client(client) + , m_webPage(0) + , m_fadeAnimationTimer(WebProcess::shared().runLoop(), this, &PageOverlay::fadeAnimationTimerFired) + , m_fadeAnimationStartTime(0.0) + , m_fadeAnimationDuration(fadeAnimationDuration) + , m_fadeAnimationType(NoAnimation) + , m_fractionFadedIn(1.0) +{ +} + +PageOverlay::~PageOverlay() +{ +} + +IntRect PageOverlay::bounds() const +{ + FrameView* frameView = m_webPage->corePage()->mainFrame()->view(); + + int width = frameView->width(); + int height = frameView->height(); + + if (!ScrollbarTheme::theme()->usesOverlayScrollbars()) { + if (frameView->verticalScrollbar()) + width -= frameView->verticalScrollbar()->width(); + 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); + + m_fadeAnimationTimer.stop(); +} + +void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect) +{ + if (m_webPage) + m_webPage->drawingArea()->setPageOverlayNeedsDisplay(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; + + GraphicsContextStateSaver stateSaver(graphicsContext); + graphicsContext.beginTransparencyLayer(1); + graphicsContext.setCompositeOperation(CompositeCopy); + + m_client->drawRect(this, graphicsContext, paintRect); + + graphicsContext.endTransparencyLayer(); +} + +bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent) +{ + // Ignore events outside the bounds. + if (!bounds().contains(mouseEvent.position())) + return false; + + return m_client->mouseEvent(this, mouseEvent); +} + +void PageOverlay::startFadeInAnimation() +{ + m_fractionFadedIn = 0.0; + m_fadeAnimationType = FadeInAnimation; + + startFadeAnimation(); +} + +void PageOverlay::startFadeOutAnimation() +{ + m_fractionFadedIn = 1.0; + m_fadeAnimationType = FadeOutAnimation; + + startFadeAnimation(); +} + +void PageOverlay::startFadeAnimation() +{ + m_fadeAnimationStartTime = currentTime(); + + // Start the timer + m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate); +} + +void PageOverlay::fadeAnimationTimerFired() +{ + float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration; + + if (animationProgress >= 1.0) + animationProgress = 1.0; + + double sine = sin(piOverTwoFloat * animationProgress); + float fadeAnimationValue = sine * sine; + + m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue; + setNeedsDisplay(); + + if (animationProgress == 1.0) { + m_fadeAnimationTimer.stop(); + + bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation; + m_fadeAnimationType = NoAnimation; + + if (wasFadingOut) { + // If this was a fade out, go ahead and uninstall the page overlay. + m_webPage->uninstallPageOverlay(this, false); + } + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h new file mode 100644 index 000000000..1f61cebe9 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h @@ -0,0 +1,105 @@ +/* + * 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 "RunLoop.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&); + + void startFadeInAnimation(); + void startFadeOutAnimation(); + + float fractionFadedIn() const { return m_fractionFadedIn; } + +protected: + explicit PageOverlay(Client*); + +private: + // APIObject + virtual Type type() const { return APIType; } + + WebCore::IntRect bounds() const; + + void startFadeAnimation(); + void fadeAnimationTimerFired(); + + Client* m_client; + WebPage* m_webPage; + + RunLoop::Timer<PageOverlay> m_fadeAnimationTimer; + double m_fadeAnimationStartTime; + double m_fadeAnimationDuration; + + enum FadeAnimationType { + NoAnimation, + FadeInAnimation, + FadeOutAnimation, + }; + + FadeAnimationType m_fadeAnimationType; + float m_fractionFadedIn; +}; + +} // namespace WebKit + +#endif // PageOverlay_h diff --git a/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp new file mode 100644 index 000000000..4140e7279 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2011 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 "config.h" +#include "TiledBackingStoreRemoteTile.h" + +#if USE(TILED_BACKING_STORE) + +#include "GraphicsContext.h" +#include "ImageBuffer.h" +#include "TiledBackingStoreClient.h" +#include "UpdateInfo.h" + +using namespace WebCore; + +namespace WebKit { + +TiledBackingStoreRemoteTile::TiledBackingStoreRemoteTile(TiledBackingStoreRemoteTileClient* client, TiledBackingStore* tiledBackingStore, const Coordinate& tileCoordinate) + : m_client(client) + , m_tiledBackingStore(tiledBackingStore) + , m_coordinate(tileCoordinate) + , m_rect(tiledBackingStore->tileRectForCoordinate(tileCoordinate)) + , m_ID(0) + , m_dirtyRect(m_rect) +{ +} + +TiledBackingStoreRemoteTile::~TiledBackingStoreRemoteTile() +{ + if (m_ID) + m_client->removeTile(m_ID); +} + +bool TiledBackingStoreRemoteTile::isDirty() const +{ + return !m_dirtyRect.isEmpty(); +} + +void TiledBackingStoreRemoteTile::invalidate(const IntRect& dirtyRect) +{ + IntRect tileDirtyRect = intersection(dirtyRect, m_rect); + if (tileDirtyRect.isEmpty()) + return; + + m_dirtyRect.unite(tileDirtyRect); +} + +Vector<IntRect> TiledBackingStoreRemoteTile::updateBackBuffer() +{ + if (!isDirty()) + return Vector<IntRect>(); + + // FIXME: Only use a local buffer when we know the tile is animated (after the first invalidate) + // and destroy it after a few seconds of inactivity. We can render directly to shared + // memory in other cases. + if (!m_localBuffer || m_localBuffer->size() != m_rect.size()) { + m_localBuffer = ImageBuffer::create(m_rect.size()); + m_localBuffer->context()->translate(-m_rect.x(), -m_rect.y()); + m_localBuffer->context()->scale(FloatSize(m_tiledBackingStore->contentsScale(), m_tiledBackingStore->contentsScale())); + } + // This assumes that the GraphicsContext on the ImageBuffer acts synchronously + // for us to be able to draw this buffer on the ShareableBitmap right after. + m_tiledBackingStore->client()->tiledBackingStorePaint(m_localBuffer->context(), m_tiledBackingStore->mapToContents(m_dirtyRect)); + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(m_rect.size(), ShareableBitmap::SupportsAlpha); + OwnPtr<GraphicsContext> graphicsContext(bitmap->createGraphicsContext()); + graphicsContext->drawImageBuffer(m_localBuffer.get(), ColorSpaceDeviceRGB, IntPoint(0, 0)); + + UpdateInfo updateInfo; + updateInfo.updateRectBounds = m_rect; + updateInfo.updateScaleFactor = m_tiledBackingStore->contentsScale(); + bitmap->createHandle(updateInfo.bitmapHandle); + + static int id = 0; + if (!m_ID) { + m_ID = ++id; + m_client->createTile(m_ID, updateInfo); + } else + m_client->updateTile(m_ID, updateInfo); + + m_dirtyRect = IntRect(); + return Vector<IntRect>(); +} + +void TiledBackingStoreRemoteTile::swapBackBufferToFront() +{ + // Handled by tiledBackingStorePaintEnd. +} + +bool TiledBackingStoreRemoteTile::isReadyToPaint() const +{ + return !!m_ID; +} + +void TiledBackingStoreRemoteTile::paint(GraphicsContext* context, const IntRect& rect) +{ + ASSERT_NOT_REACHED(); +} + +void TiledBackingStoreRemoteTile::resize(const IntSize& newSize) +{ + m_rect = IntRect(m_rect.location(), newSize); + m_dirtyRect = m_rect; +} + +TiledBackingStoreRemoteTileBackend::TiledBackingStoreRemoteTileBackend(TiledBackingStoreRemoteTileClient* client) + : m_client(client) +{ +} + +PassRefPtr<WebCore::Tile> TiledBackingStoreRemoteTileBackend::createTile(WebCore::TiledBackingStore* tiledBackingStore, const WebCore::Tile::Coordinate& tileCoordinate) +{ + return TiledBackingStoreRemoteTile::create(m_client, tiledBackingStore, tileCoordinate); +} + +void TiledBackingStoreRemoteTileBackend::paintCheckerPattern(WebCore::GraphicsContext*, const WebCore::FloatRect&) +{ +} + +} // namespace WebKit + +#endif // USE(TILED_BACKING_STORE) diff --git a/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h new file mode 100644 index 000000000..12b2e0602 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledBackingStoreRemoteTile.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2011 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 TiledBackingStoreRemoteTile_h +#define TiledBackingStoreRemoteTile_h + +#if USE(TILED_BACKING_STORE) + +#include "Tile.h" +#include "TiledBackingStore.h" +#include "WebCore/IntRect.h" + +namespace WebCore { +class ImageBuffer; +class TiledBackingStore; +} + +namespace WebKit { + +class TiledBackingStoreRemoteTileClient; +class UpdateInfo; + +class TiledBackingStoreRemoteTile : public WebCore::Tile { +public: + static PassRefPtr<Tile> create(TiledBackingStoreRemoteTileClient* client, WebCore::TiledBackingStore* tiledBackingStore, const Coordinate& tileCoordinate) { return adoptRef(new TiledBackingStoreRemoteTile(client, tiledBackingStore, tileCoordinate)); } + ~TiledBackingStoreRemoteTile(); + + bool isDirty() const; + void invalidate(const WebCore::IntRect&); + Vector<WebCore::IntRect> updateBackBuffer(); + void swapBackBufferToFront(); + bool isReadyToPaint() const; + void paint(WebCore::GraphicsContext*, const WebCore::IntRect&); + + const Coordinate& coordinate() const { return m_coordinate; } + const WebCore::IntRect& rect() const { return m_rect; } + void resize(const WebCore::IntSize&); + +private: + TiledBackingStoreRemoteTile(TiledBackingStoreRemoteTileClient*, WebCore::TiledBackingStore*, const Coordinate&); + + TiledBackingStoreRemoteTileClient* m_client; + WebCore::TiledBackingStore* m_tiledBackingStore; + Coordinate m_coordinate; + WebCore::IntRect m_rect; + + int m_ID; + WebCore::IntRect m_dirtyRect; + + OwnPtr<WebCore::ImageBuffer> m_localBuffer; +}; + +class TiledBackingStoreRemoteTileClient { +public: + virtual ~TiledBackingStoreRemoteTileClient() { } + virtual void createTile(int tileID, const UpdateInfo&) = 0; + virtual void updateTile(int tileID, const UpdateInfo&) = 0; + virtual void removeTile(int tileID) = 0; +}; + +class TiledBackingStoreRemoteTileBackend : public WebCore::TiledBackingStoreBackend { +public: + static PassOwnPtr<WebCore::TiledBackingStoreBackend> create(TiledBackingStoreRemoteTileClient* client) { return adoptPtr(new TiledBackingStoreRemoteTileBackend(client)); } + PassRefPtr<WebCore::Tile> createTile(WebCore::TiledBackingStore*, const WebCore::Tile::Coordinate&); + void paintCheckerPattern(WebCore::GraphicsContext*, const WebCore::FloatRect&); + +private: + TiledBackingStoreRemoteTileBackend(TiledBackingStoreRemoteTileClient*); + TiledBackingStoreRemoteTileClient* m_client; +}; + + +} // namespace WebKit + +#endif // USE(TILED_BACKING_STORE) + +#endif // TiledBackingStoreRemoteTile diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp new file mode 100644 index 000000000..c482e664b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2010, 2011 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 "config.h" +#include "TiledDrawingArea.h" + +#if USE(TILED_BACKING_STORE) + +#include "DrawingAreaProxyMessages.h" +#include "MessageID.h" +#include "UpdateInfo.h" +#include "WebCoreArgumentCoders.h" +#include "WebPage.h" +#include "WebProcess.h" + +using namespace WebCore; + +namespace WebKit { + +TiledDrawingArea::TiledDrawingArea(WebPage* webPage) + : DrawingArea(DrawingAreaTypeTiled, webPage) + , m_suspended(false) + , m_isWaitingForUIProcess(false) + , m_didSendTileUpdate(false) + , m_mainBackingStore(adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this)))) +{ +} + +TiledDrawingArea::~TiledDrawingArea() +{ +} + +void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + // FIXME: Do something much smarter. + setNeedsDisplay(scrollRect); +} + +void TiledDrawingArea::setNeedsDisplay(const IntRect& rect) +{ + m_mainBackingStore->invalidate(rect); +} + +void TiledDrawingArea::setSize(const IntSize& viewSize) +{ + ASSERT(!m_suspended); + ASSERT_ARG(viewSize, !viewSize.isEmpty()); + + m_webPage->setSize(viewSize); +} + +void TiledDrawingArea::setVisibleContentRectAndScale(const WebCore::IntRect& visibleContentsRect, float scale) +{ + m_visibleContentRect = visibleContentsRect; + + if (scale != m_mainBackingStore->contentsScale()) { + // Keep the tiles for the previous scale until enough content is available to be shown on the screen for the new scale. + // If we already have a previous set of tiles it means that two scale changed happened successively. + // In that case, make sure that our current main tiles have more content to show than the "previous previous" + // within the visible rect before replacing it. + if (!m_previousBackingStore || m_mainBackingStore->coverageRatio(m_visibleContentRect) > m_previousBackingStore->coverageRatio(m_visibleContentRect)) + m_previousBackingStore = m_mainBackingStore.release(); + + m_mainBackingStore = adoptPtr(new TiledBackingStore(this, TiledBackingStoreRemoteTileBackend::create(this))); + m_mainBackingStore->setContentsScale(scale); + } else + m_mainBackingStore->adjustVisibleRect(); +} + +void TiledDrawingArea::setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint& trajectoryVector) +{ + m_mainBackingStore->setVisibleRectTrajectoryVector(trajectoryVector); +} + +void TiledDrawingArea::renderNextFrame() +{ + m_isWaitingForUIProcess = false; + m_mainBackingStore->updateTileBuffers(); +} + +void TiledDrawingArea::suspendPainting() +{ + ASSERT(!m_suspended); + + m_suspended = true; +} + +void TiledDrawingArea::resumePainting() +{ + ASSERT(m_suspended); + + m_suspended = false; + m_mainBackingStore->updateTileBuffers(); +} + +void TiledDrawingArea::tiledBackingStorePaintBegin() +{ + m_webPage->layoutIfNeeded(); +} + +void TiledDrawingArea::tiledBackingStorePaint(GraphicsContext* graphicsContext, const IntRect& contentRect) +{ + m_webPage->drawRect(*graphicsContext, contentRect); +} + +void TiledDrawingArea::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea) +{ + if (m_didSendTileUpdate) { + // Since we know that all tile updates following a page invalidate will all be rendered + // in one paint pass for all the tiles, we can send the swap tile message here. + m_webPage->send(Messages::DrawingAreaProxy::DidRenderFrame()); + m_isWaitingForUIProcess = true; + m_didSendTileUpdate = false; + + // Make sure that we destroy the previous backing store and remove its tiles only after DidRenderFrame + // was sent to swap recently created tiles' buffer. Else a frame could be rendered after the previous + // tiles were removed and before the new tile have their first back buffer swapped. + if (m_previousBackingStore && m_mainBackingStore->coverageRatio(m_visibleContentRect) >= 1.0f) + m_previousBackingStore.clear(); + } +} + +bool TiledDrawingArea::tiledBackingStoreUpdatesAllowed() const +{ + return !m_suspended && !m_isWaitingForUIProcess; +} + +IntRect TiledDrawingArea::tiledBackingStoreContentsRect() +{ + return IntRect(IntPoint::zero(), m_webPage->size()); +} + +IntRect TiledDrawingArea::tiledBackingStoreVisibleRect() +{ + return m_visibleContentRect; +} + +Color TiledDrawingArea::tiledBackingStoreBackgroundColor() const +{ + return Color::transparent; +} + +void TiledDrawingArea::createTile(int tileID, const UpdateInfo& updateInfo) +{ + m_webPage->send(Messages::DrawingAreaProxy::CreateTile(tileID, updateInfo)); + m_didSendTileUpdate = true; +} +void TiledDrawingArea::updateTile(int tileID, const UpdateInfo& updateInfo) +{ + m_webPage->send(Messages::DrawingAreaProxy::UpdateTile(tileID, updateInfo)); + m_didSendTileUpdate = true; +} +void TiledDrawingArea::removeTile(int tileID) +{ + m_webPage->send(Messages::DrawingAreaProxy::RemoveTile(tileID)); +} + +#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +void TiledDrawingArea::didReceiveLayerTreeHostMessage(CoreIPC::Connection* connection, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments) +{ +} +#endif +} // namespace WebKit + +#endif // USE(TILED_BACKING_STORE) diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h new file mode 100644 index 000000000..cbcbd3090 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.h @@ -0,0 +1,90 @@ +/* + * 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 USE(TILED_BACKING_STORE) + +#include "DrawingArea.h" +#include "TiledBackingStoreClient.h" +#include "TiledBackingStoreRemoteTile.h" +#include <WebCore/IntRect.h> + +namespace WebKit { + +class TiledDrawingArea : public DrawingArea, public WebCore::TiledBackingStoreClient, public TiledBackingStoreRemoteTileClient { +public: + explicit TiledDrawingArea(WebPage*); + virtual ~TiledDrawingArea(); + + virtual void setNeedsDisplay(const WebCore::IntRect&); + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollDelta); + +#if USE(ACCELERATED_COMPOSITING) + virtual void attachCompositingContext() { } + virtual void detachCompositingContext() { } + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) { } + virtual void scheduleCompositingLayerSync() { } + virtual void didReceiveLayerTreeHostMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); +#endif + +private: + // CoreIPC message handlers. + virtual void setSize(const WebCore::IntSize& viewSize); + virtual void setVisibleContentRectAndScale(const WebCore::IntRect&, float); + virtual void setVisibleContentRectTrajectoryVector(const WebCore::FloatPoint&); + virtual void renderNextFrame(); + virtual void suspendPainting(); + virtual void resumePainting(); + + // TiledBackingStoreClient + virtual void tiledBackingStorePaintBegin(); + virtual void tiledBackingStorePaint(WebCore::GraphicsContext*, const WebCore::IntRect& contentRect); + virtual void tiledBackingStorePaintEnd(const Vector<WebCore::IntRect>& paintedArea); + virtual bool tiledBackingStoreUpdatesAllowed() const; + virtual WebCore::IntRect tiledBackingStoreContentsRect(); + virtual WebCore::IntRect tiledBackingStoreVisibleRect(); + virtual WebCore::Color tiledBackingStoreBackgroundColor() const; + + // TiledBackingStoreRemoteTileClient + virtual void createTile(int tileID, const UpdateInfo&); + virtual void updateTile(int tileID, const UpdateInfo&); + virtual void removeTile(int tileID); + + bool m_suspended; + bool m_isWaitingForUIProcess; + bool m_didSendTileUpdate; + WebCore::IntRect m_visibleContentRect; + + OwnPtr<WebCore::TiledBackingStore> m_mainBackingStore; + OwnPtr<WebCore::TiledBackingStore> m_previousBackingStore; +}; + +} // namespace WebKit + +#endif // USE(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 000000000..7a6045eb6 --- /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 "config.h" +#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() +{ + DEFINE_STATIC_LOCAL(IDToHistoryItemMap, map, ()); + return map; +} + +static HistoryItemToIDMap& historyItemToIDMap() +{ + DEFINE_STATIC_LOCAL(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.dataReference()), 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(); +} + +uint64_t WebBackForwardListProxy::idForItem(HistoryItem* item) +{ + ASSERT(item); + return historyItemToIDMap().get(item); +} + +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()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h new file mode 100644 index 000000000..b69eb123d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.h @@ -0,0 +1,69 @@ +/* + * 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 uint64_t idForItem(WebCore::HistoryItem*); + 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(); + + 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 000000000..e7e2e745f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp @@ -0,0 +1,97 @@ +/* + * 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 "config.h" +#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/Frame.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(); + + // Mark the WebPage has having a shown context menu then notify the UIProcess. + m_page->contextMenuShowing(); + 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 000000000..3d9291aa3 --- /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/WebFrame.cpp b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp new file mode 100644 index 000000000..b32543eee --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "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/JSContextRef.h> +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/JSValueRef.h> +#include <WebCore/AnimationController.h> +#include <WebCore/ArchiveResource.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/HTMLNames.h> +#include <WebCore/JSCSSStyleDeclaration.h> +#include <WebCore/JSElement.h> +#include <WebCore/JSRange.h> +#include <WebCore/Page.h> +#include <WebCore/RenderTreeAsText.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/TextIterator.h> +#include <WebCore/TextResourceDecoder.h> +#include <wtf/text/StringBuilder.h> + +#if PLATFORM(MAC) || PLATFORM(WIN) +#include <WebCore/LegacyWebArchive.h> +#endif + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace JSC; +using namespace WebCore; + +namespace WebKit { + +DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webFrameCounter, ("WebFrame")); + +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 ResourceResponse& response) +{ + ASSERT(m_policyDownloadID); + + DownloadManager::shared().convertHandleToDownload(m_policyDownloadID, page(), handle, request, 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->mainWebFrame() == 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(); + + DocumentLoader* documentLoader = m_coreFrame->loader()->documentLoader(); + if (!documentLoader) + return String(); + + return documentLoader->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(m_coreFrame->document()); +} + +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); +} + +bool WebFrame::pauseTransitionOnElementWithId(const String& propertyName, 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->pauseTransitionAtTime(coreNode->renderer(), propertyName, 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()); +} + +IntRect WebFrame::contentBounds() const +{ + if (!m_coreFrame) + return IntRect(); + + FrameView* view = m_coreFrame->view(); + if (!view) + return IntRect(); + + return IntRect(0, 0, view->contentsWidth(), view->contentsHeight()); +} + +IntRect WebFrame::visibleContentBounds() const +{ + if (!m_coreFrame) + return IntRect(); + + FrameView* view = m_coreFrame->view(); + if (!view) + return IntRect(); + + IntRect contentRect = view->visibleContentRect(true); + return IntRect(0, 0, contentRect.width(), contentRect.height()); +} + +IntRect WebFrame::visibleContentBoundsExcludingScrollbars() const +{ + if (!m_coreFrame) + return IntRect(); + + FrameView* view = m_coreFrame->view(); + if (!view) + return IntRect(); + + IntRect contentRect = view->visibleContentRect(false); + return IntRect(0, 0, contentRect.width(), contentRect.height()); +} + +IntSize WebFrame::scrollOffset() const +{ + if (!m_coreFrame) + return IntSize(); + + FrameView* view = m_coreFrame->view(); + if (!view) + return IntSize(); + + return view->scrollOffset(); +} + +bool WebFrame::hasHorizontalScrollbar() const +{ + if (!m_coreFrame) + return false; + + FrameView* view = m_coreFrame->view(); + if (!view) + return false; + + return view->horizontalScrollbar(); +} + +bool WebFrame::hasVerticalScrollbar() const +{ + if (!m_coreFrame) + return false; + + FrameView* view = m_coreFrame->view(); + if (!view) + return false; + + return view->verticalScrollbar(); +} + +bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha) +{ + if (!m_coreFrame) + return false; + + FrameView* view = m_coreFrame->view(); + if (!view) + return false; + + Color bgColor = view->documentBackgroundColor(); + if (!bgColor.isValid()) + return false; + + bgColor.getRGBA(*red, *green, *blue, *alpha); + return true; +} + +bool WebFrame::containsAnyFormElements() const +{ + if (!m_coreFrame) + return false; + + Document* document = m_coreFrame->document(); + if (!document) + return false; + + for (Node* node = document->documentElement(); node; node = node->traverseNextNode()) { + if (!node->isElementNode()) + continue; + if (static_cast<Element*>(node)->hasTagName(HTMLNames::formTag)) + return true; + } + return false; +} + +WebFrame* WebFrame::frameForContext(JSContextRef context) +{ + JSObjectRef globalObjectRef = JSContextGetGlobalObject(context); + JSC::JSObject* globalObjectObj = toJS(globalObjectRef); + if (strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell") != 0) + return 0; + + Frame* coreFrame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->impl()->frame(); + return static_cast<WebFrameLoaderClient*>(coreFrame->loader()->client())->webFrame(); +} + +JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world) +{ + if (!m_coreFrame) + return 0; + + 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) +{ + if (!m_coreFrame) + return 0; + + 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(); +} + +String WebFrame::suggestedFilenameForResourceWithURL(const KURL& url) const +{ + if (!m_coreFrame) + return String(); + + DocumentLoader* loader = m_coreFrame->loader()->documentLoader(); + if (!loader) + return String(); + + // First, try the main resource. + if (loader->url() == url) + return loader->response().suggestedFilename(); + + // Next, try subresources. + RefPtr<ArchiveResource> resource = loader->subresource(url); + if (resource) + return resource->response().suggestedFilename(); + + return page()->cachedSuggestedFilenameForURL(url); +} + +String WebFrame::mimeTypeForResourceWithURL(const KURL& url) const +{ + if (!m_coreFrame) + return String(); + + DocumentLoader* loader = m_coreFrame->loader()->documentLoader(); + if (!loader) + return String(); + + // First, try the main resource. + if (loader->url() == url) + return loader->response().mimeType(); + + // Next, try subresources. + RefPtr<ArchiveResource> resource = loader->subresource(url); + if (resource) + return resource->mimeType(); + + return page()->cachedResponseMIMETypeForURL(url); +} + +void WebFrame::setTextDirection(const String& direction) +{ + if (!m_coreFrame || !m_coreFrame->editor()) + return; + + if (direction == "auto") + m_coreFrame->editor()->setBaseWritingDirection(NaturalWritingDirection); + else if (direction == "ltr") + m_coreFrame->editor()->setBaseWritingDirection(LeftToRightWritingDirection); + else if (direction == "rtl") + m_coreFrame->editor()->setBaseWritingDirection(RightToLeftWritingDirection); +} + +#if PLATFORM(MAC) || PLATFORM(WIN) +RetainPtr<CFDataRef> WebFrame::webArchiveData() const +{ + if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreFrame()->document())) + return archive->rawDataRepresentation(); + + return 0; +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.h b/Source/WebKit2/WebProcess/WebPage/WebFrame.h new file mode 100644 index 000000000..29ced42de --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.h @@ -0,0 +1,164 @@ +/* + * 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> +#include <wtf/RetainPtr.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::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*); + WebCore::IntRect contentBounds() const; + WebCore::IntRect visibleContentBounds() const; + WebCore::IntRect visibleContentBoundsExcludingScrollbars() const; + WebCore::IntSize scrollOffset() const; + bool hasHorizontalScrollbar() const; + bool hasVerticalScrollbar() const; + bool getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha); + bool containsAnyFormElements() const; + + static WebFrame* frameForContext(JSContextRef); + + 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); + bool pauseTransitionOnElementWithId(const String& propertyName, const String& elementID, double time); + void suspendAnimations(); + void resumeAnimations(); + String layerTreeAsText() const; + + unsigned pendingUnloadCount() const; + + bool allowsFollowingLink(const WebCore::KURL&) const; + + String provisionalURL() const; + String suggestedFilenameForResourceWithURL(const WebCore::KURL&) const; + String mimeTypeForResourceWithURL(const WebCore::KURL&) const; + + void setTextDirection(const String&); + + // 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; } + +#if PLATFORM(MAC) || PLATFORM(WIN) + RetainPtr<CFDataRef> webArchiveData() const; +#endif + +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 000000000..e1383c832 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include "WebInspectorFrontendClient.h" +#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 { + +PassRefPtr<WebInspector> WebInspector::create(WebPage* page) +{ + return adoptRef(new WebInspector(page)); +} + +WebInspector::WebInspector(WebPage* page) + : m_page(page) + , m_inspectorPage(0) + , m_frontendClient(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); + + OwnPtr<WebInspectorFrontendClient> frontendClient = adoptPtr(new WebInspectorFrontendClient(m_page, m_inspectorPage)); + m_frontendClient = frontendClient.get(); + m_inspectorPage->corePage()->inspectorController()->setInspectorFrontendClient(frontendClient.release()); + 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()); +} + +void WebInspector::bringToFront() +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::BringToFront(), m_page->pageID()); +} + +void WebInspector::inspectedURLChanged(const String& urlString) +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::InspectedURLChanged(urlString), m_page->pageID()); +} + +void WebInspector::attach() +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::Attach(), m_page->pageID()); +} + +void WebInspector::detach() +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::Detach(), m_page->pageID()); +} + +void WebInspector::setAttachedWindowHeight(unsigned height) +{ + WebProcess::shared().connection()->send(Messages::WebInspectorProxy::SetAttachedWindowHeight(height), 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::evaluateScriptForTest(long callID, const String& script) +{ + m_page->corePage()->inspectorController()->evaluateForTestInFrontend(callID, script); +} + +void WebInspector::showConsole() +{ + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->showConsole(); +} + +void WebInspector::startJavaScriptDebugging() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->setDebuggingEnabled(true); +#endif +} + +void WebInspector::stopJavaScriptDebugging() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->setDebuggingEnabled(false); +#endif +} + +void WebInspector::setJavaScriptProfilingEnabled(bool enabled) +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->show(); + if (!m_frontendClient) + return; + if (enabled) + m_page->corePage()->inspectorController()->enableProfiler(); + else + m_page->corePage()->inspectorController()->disableProfiler(); +#endif +} + +void WebInspector::startJavaScriptProfiling() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->startProfilingJavaScript(); +#endif +} + +void WebInspector::stopJavaScriptProfiling() +{ +#if ENABLE(JAVASCRIPT_DEBUGGER) + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->stopProfilingJavaScript(); +#endif +} + +void WebInspector::startPageProfiling() +{ + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->setTimelineProfilingEnabled(true); +} + +void WebInspector::stopPageProfiling() +{ + m_page->corePage()->inspectorController()->show(); + if (m_frontendClient) + m_frontendClient->setTimelineProfilingEnabled(false); +} + +} // 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 000000000..79ff8074a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebInspector.h @@ -0,0 +1,110 @@ +/* + * 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 "APIObject.h" +#include "Connection.h" +#include <wtf/Forward.h> +#include <wtf/Noncopyable.h> + +namespace WebKit { + +class WebInspectorFrontendClient; +class WebPage; +struct WebPageCreationParameters; + +class WebInspector : public APIObject { +public: + static const Type APIType = TypeBundleInspector; + + static PassRefPtr<WebInspector> create(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*); + + // Called by WebInspector messages + void show(); + void close(); + + void evaluateScriptForTest(long callID, const String& script); + + void setJavaScriptProfilingEnabled(bool); + void startPageProfiling(); + void stopPageProfiling(); + +#if PLATFORM(MAC) + static void setLocalizedStringsPath(const String&); +#endif + +private: + friend class WebInspectorClient; + friend class WebInspectorFrontendClient; + + explicit WebInspector(WebPage*); + + virtual Type type() const { return APIType; } + + // Called from WebInspectorClient + WebPage* createInspectorPage(); + + // Called from WebInspectorFrontendClient + void didLoadInspectorPage(); + void didClose(); + void bringToFront(); + void inspectedURLChanged(const String&); + + void attach(); + void detach(); + + void setAttachedWindowHeight(unsigned); + + // Implemented in platform WebInspector file + String localizedStringsURL() const; + + void showConsole(); + + void startJavaScriptDebugging(); + void stopJavaScriptDebugging(); + + void startJavaScriptProfiling(); + void stopJavaScriptProfiling(); + + WebPage* m_page; + WebPage* m_inspectorPage; + WebInspectorFrontendClient* m_frontendClient; +}; + +} // 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 000000000..dc184b68a --- /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 000000000..bcf3e8024 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebOpenPanelResultListener.cpp @@ -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. + */ + +#include "config.h" +#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 000000000..073d66adb --- /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 000000000..660f6f99c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp @@ -0,0 +1,2900 @@ +/* + * 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 "config.h" +#include "WebPage.h" + +#include "Arguments.h" +#include "DataReference.h" +#include "DecoderAdapter.h" +#include "DrawingArea.h" +#include "InjectedBundle.h" +#include "InjectedBundleBackForwardList.h" +#include "LayerTreeHost.h" +#include "MessageID.h" +#include "NetscapePlugin.h" +#include "NotificationPermissionRequestManager.h" +#include "PageOverlay.h" +#include "PluginProxy.h" +#include "PluginView.h" +#include "PrintInfo.h" +#include "RunLoop.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 "WebFullScreenManager.h" +#include "WebGeolocationClient.h" +#include "WebGeometry.h" +#include "WebImage.h" +#include "WebInspector.h" +#include "WebInspectorClient.h" +#include "WebNotificationClient.h" +#include "WebOpenPanelResultListener.h" +#include "WebPageCreationParameters.h" +#include "WebPageGroupProxy.h" +#include "WebPageProxyMessages.h" +#include "WebPopupMenu.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include "WebProcessProxyMessages.h" +#include <JavaScriptCore/APICast.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/DragSession.h> +#include <WebCore/EventHandler.h> +#include <WebCore/FocusController.h> +#include <WebCore/FormState.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoadRequest.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/FrameView.h> +#include <WebCore/HTMLFormElement.h> +#include <WebCore/HistoryItem.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/MouseEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/PluginDocument.h> +#include <WebCore/PrintContext.h> +#include <WebCore/RenderArena.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/RenderTreeAsText.h> +#include <WebCore/RenderView.h> +#include <WebCore/ReplaceSelectionCommand.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/SchemeRegistry.h> +#include <WebCore/ScriptValue.h> +#include <WebCore/SerializedScriptValue.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> + +#include <WebCore/Range.h> +#include <WebCore/VisiblePosition.h> + +#if ENABLE(PLUGIN_PROCESS) +#if PLATFORM(MAC) +#include "MachPort.h" +#endif +#endif + +#if PLATFORM(MAC) +#include "BuiltInPDFView.h" +#endif + +#if PLATFORM(QT) +#include "HitTestResult.h" +#include <QMimeData> +#endif + +#if PLATFORM(GTK) +#include "DataObjectGtk.h" +#endif + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace JSC; +using namespace WebCore; +using namespace std; + +namespace WebKit { + +class SendStopResponsivenessTimer { +public: + SendStopResponsivenessTimer(WebPage* page) + : m_page(page) + { + } + + ~SendStopResponsivenessTimer() + { + m_page->send(Messages::WebPageProxy::StopResponsivenessTimer()); + } + +private: + WebPage* m_page; +}; + +DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage")); + +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_useFixedLayout(false) + , 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) + , m_keyboardEventBeingInterpreted(0) +#elif PLATFORM(WIN) + , m_nativeWindow(parameters.nativeWindow) +#endif + , m_setCanStartMediaTimer(WebProcess::shared().runLoop(), this, &WebPage::setCanStartMediaTimerFired) + , m_findController(this) + , m_geolocationPermissionRequestManager(this) + , m_pageID(pageID) + , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel) + , m_canRunModal(parameters.canRunModal) + , m_isRunningModal(false) + , m_cachedMainFrameIsPinnedToLeftSide(false) + , m_cachedMainFrameIsPinnedToRightSide(false) + , m_cachedPageCount(0) + , m_isShowingContextMenu(false) +#if PLATFORM(WIN) + , m_gestureReachedScrollingLimit(false) +#endif +{ + ASSERT(m_pageID); + // FIXME: This is a non-ideal location for this Setting and + // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214 + Settings::setDefaultMinDOMTimerInterval(0.004); + + 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 +#if ENABLE(NOTIFICATIONS) + pageClients.notificationClient = new WebNotificationClient(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(); + + m_drawingArea = DrawingArea::create(this, parameters); + m_drawingArea->setPaintingEnabled(false); + + m_mainFrame = WebFrame::createMainFrame(this); + + setUseFixedLayout(parameters.useFixedLayout); + + setDrawsBackground(parameters.drawsBackground); + setDrawsTransparentBackground(parameters.drawsTransparentBackground); + + setPaginationMode(parameters.paginationMode); + setPageLength(parameters.pageLength); + setGapBetweenPages(parameters.gapBetweenPages); + + setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled); + + setActive(parameters.isActive); + setFocused(parameters.isFocused); + setIsInWindow(parameters.isInWindow); + + m_userAgent = parameters.userAgent; + + WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID); + + if (!parameters.sessionState.isEmpty()) + restoreSession(parameters.sessionState); + + m_drawingArea->setPaintingEnabled(true); + +#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::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client) +{ + m_policyClient.initialize(client); +} + +void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client) +{ + m_resourceLoadClient.initialize(client); +} + +void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) +{ + m_uiClient.initialize(client); +} + +#if ENABLE(FULLSCREEN_API) +void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client) +{ + m_fullScreenClient.initialize(client); +} +#endif + +PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, 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()) { +#if PLATFORM(MAC) + if (parameters.mimeType == "application/pdf" + || (parameters.mimeType.isEmpty() && parameters.url.path().lower().endsWith(".pdf"))) + return BuiltInPDFView::create(frame); +#else + UNUSED_PARAM(frame); +#endif + return 0; + } + +#if ENABLE(PLUGIN_PROCESS) + return PluginProxy::create(pluginPath); +#else + NetscapePlugin::setSetExceptionFunction(NPRuntimeObjectMap::setGlobalException); + return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath)); +#endif +} + +EditorState WebPage::editorState() const +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + ASSERT(frame); + + EditorState result; + result.selectionIsNone = frame->selection()->isNone(); + result.selectionIsRange = frame->selection()->isRange(); + result.isContentEditable = frame->selection()->isContentEditable(); + result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable(); + result.isInPasswordField = frame->selection()->isInPasswordField(); + result.hasComposition = frame->editor()->hasComposition(); + result.shouldIgnoreCompositionSelectionChange = frame->editor()->ignoreCompositionSelectionChange(); + +#if PLATFORM(QT) + size_t location = 0; + size_t length = 0; + + Element* selectionRoot = frame->selection()->rootEditableElement(); + Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement(); + + if (!scope) + return result; + + RefPtr<Range> range; + if (result.hasComposition && (range = frame->editor()->compositionRange())) { + frame->editor()->getCompositionSelection(result.anchorPosition, result.cursorPosition); + + result.compositionRect = frame->view()->contentsToWindow(range->boundingBox()); + } + + if (!result.hasComposition && !result.selectionIsNone && (range = frame->selection()->selection().firstRange())) { + TextIterator::getLocationAndLengthFromRange(scope, range.get(), location, length); + bool baseIsFirst = frame->selection()->selection().isBaseFirst(); + + result.cursorPosition = (baseIsFirst) ? location + length : location; + result.anchorPosition = (baseIsFirst) ? location : location + length; + result.selectedText = range->text(); + } + + if (range) + result.microFocus = frame->view()->contentsToWindow(frame->editor()->firstRectForRange(range.get())); + + // FIXME: We should only transfer innerText when it changes and do this on the UI side. + if (result.isContentEditable && !result.isInPasswordField) { + result.surroundingText = scope->innerText(); + if (result.hasComposition) { + // The anchor is always the left position when they represent a composition. + result.surroundingText.remove(result.anchorPosition, result.cursorPosition - result.anchorPosition); + } + } +#endif + + return result; +} + +String WebPage::renderTreeExternalRepresentation() const +{ + return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); +} + +uint64_t WebPage::renderTreeSize() const +{ + if (!m_page) + return 0; + + Frame* mainFrame = m_page->mainFrame(); + if (!mainFrame) + return 0; + + uint64_t size = 0; + for (Frame* coreFrame = mainFrame; coreFrame; coreFrame = coreFrame->tree()->traverseNext()) + size += coreFrame->document()->renderArena()->totalRenderArenaSize(); + + return size; +} + +void WebPage::setTracksRepaints(bool trackRepaints) +{ + if (FrameView* view = mainFrameView()) + view->setTracksRepaints(trackRepaints); +} + +bool WebPage::isTrackingRepaints() const +{ + if (FrameView* view = mainFrameView()) + return view->isTrackingRepaints(); + + return false; +} + +void WebPage::resetTrackedRepaints() +{ + if (FrameView* view = mainFrameView()) + view->resetTrackedRepaints(); +} + +PassRefPtr<ImmutableArray> WebPage::trackedRepaintRects() +{ + FrameView* view = mainFrameView(); + if (!view) + return ImmutableArray::create(); + + const Vector<IntRect>& rects = view->trackedRepaintRects(); + size_t size = rects.size(); + if (!size) + return ImmutableArray::create(); + + Vector<RefPtr<APIObject> > vector; + vector.reserveInitialCapacity(size); + + for (size_t i = 0; i < size; ++i) + vector.uncheckedAppend(WebRect::create(toAPI(rects[i]))); + + return ImmutableArray::adopt(vector); +} + +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() +{ + if (Frame* frame = mainFrame()) + frame->tree()->clearName(); +} + +#if USE(ACCELERATED_COMPOSITING) +void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer) +{ + m_drawingArea->setRootCompositingLayer(layer); +} + +void WebPage::exitAcceleratedCompositingMode() +{ + m_drawingArea->setRootCompositingLayer(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 ENABLE(FULLSCREEN_API) + m_fullScreenManager = 0; +#endif + + if (m_activePopupMenu) { + m_activePopupMenu->disconnectFromPage(); + m_activePopupMenu = 0; + } + + if (m_activeOpenPanelResultListener) { + m_activeOpenPanelResultListener->disconnectFromPage(); + m_activeOpenPanelResultListener = 0; + } + + m_sandboxExtensionTracker.invalidate(); + + m_underlayPage = nullptr; + m_printContext = nullptr; + m_mainFrame->coreFrame()->loader()->detachFromParent(); + m_page = nullptr; + m_drawingArea = nullptr; + + bool isRunningModal = m_isRunningModal; + m_isRunningModal = false; + + // The WebPage can be destroyed by this call. + WebProcess::shared().removeWebPage(m_pageID); + + if (isRunningModal) + WebProcess::shared().runLoop()->stop(); +} + +void WebPage::tryClose() +{ + SendStopResponsivenessTimer stopper(this); + + if (!m_mainFrame->coreFrame()->loader()->shouldClose()) { + send(Messages::WebPageProxy::StopResponsivenessTimer()); + return; + } + + send(Messages::WebPageProxy::ClosePage(true)); +} + +void WebPage::sendClose() +{ + send(Messages::WebPageProxy::ClosePage(false)); +} + +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) +{ + SendStopResponsivenessTimer stopper(this); + + 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) +{ + SendStopResponsivenessTimer stopper(this); + + 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::linkClicked(const String& url, const WebMouseEvent& event) +{ + Frame* frame = m_page->mainFrame(); + if (!frame) + return; + + RefPtr<Event> coreEvent; + if (event.type() != WebEvent::NoType) + coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0); + + frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)), + false, false, coreEvent.get(), 0, MaybeSendReferrer); +} + +void WebPage::stopLoadingFrame(uint64_t frameID) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + if (!frame) + return; + + frame->coreFrame()->loader()->stopForUserCancel(); +} + +void WebPage::stopLoading() +{ + SendStopResponsivenessTimer stopper(this); + + m_mainFrame->coreFrame()->loader()->stopForUserCancel(); +} + +void WebPage::setDefersLoading(bool defersLoading) +{ + m_page->setDefersLoading(defersLoading); +} + +void WebPage::reload(bool reloadFromOrigin) +{ + SendStopResponsivenessTimer stopper(this); + + m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin); +} + +void WebPage::goForward(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + SendStopResponsivenessTimer stopper(this); + + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + ASSERT(item); + if (!item) + return; + + m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); + m_page->goToItem(item, FrameLoadTypeForward); +} + +void WebPage::goBack(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + SendStopResponsivenessTimer stopper(this); + + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + ASSERT(item); + if (!item) + return; + + m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); + m_page->goToItem(item, FrameLoadTypeBack); +} + +void WebPage::goToBackForwardItem(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + SendStopResponsivenessTimer stopper(this); + + HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID); + ASSERT(item); + if (!item) + return; + + m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle); + m_page->goToItem(item, FrameLoadTypeIndexedBackForward); +} + +void WebPage::tryRestoreScrollPosition() +{ + m_page->mainFrame()->loader()->history()->restoreScrollPositionAndViewState(); +} + +void WebPage::layoutIfNeeded() +{ + if (m_mainFrame->coreFrame()->view()) + m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive(); + + if (m_underlayPage) { + if (FrameView *frameView = m_underlayPage->mainFrameView()) + frameView->updateLayoutAndStyleIfNeededRecursive(); + } +} + +void WebPage::setSize(const WebCore::IntSize& viewSize) +{ + FrameView* view = m_page->mainFrame()->view(); + +#if USE(TILED_BACKING_STORE) + // If we are resizing to content ignore external attempts. + if (view->useFixedLayout()) + return; +#endif + + if (m_viewSize == viewSize) + return; + + view->resize(viewSize); + view->setNeedsLayout(); + m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize)); + + m_viewSize = viewSize; +} + +#if USE(TILED_BACKING_STORE) +void WebPage::setFixedVisibleContentRect(const IntRect& rect) +{ + ASSERT(m_useFixedLayout); + + Frame* frame = m_page->mainFrame(); + + frame->view()->setFixedVisibleContentRect(rect); +} + +void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize) +{ + ASSERT(m_useFixedLayout); + ASSERT(!targetLayoutSize.isEmpty()); + + FrameView* view = m_page->mainFrame()->view(); + + view->setDelegatesScrolling(true); + view->setUseFixedLayout(true); + view->setPaintsEntireContents(true); + + if (view->fixedLayoutSize() == targetLayoutSize) + return; + + // Always reset even when empty. + view->setFixedLayoutSize(targetLayoutSize); + + // Schedule a layout to use the new target size. + if (!view->layoutPending()) { + view->setNeedsLayout(); + view->scheduleRelayout(); + } +} + +void WebPage::resizeToContentsIfNeeded() +{ + ASSERT(m_useFixedLayout); + + FrameView* view = m_page->mainFrame()->view(); + + if (!view->useFixedLayout()) + return; + + IntSize contentSize = view->contentsSize(); + if (contentSize == m_viewSize) + return; + + m_viewSize = contentSize; + view->resize(m_viewSize); + view->setNeedsLayout(); +} + +void WebPage::setViewportSize(const IntSize& size) +{ + ASSERT(m_useFixedLayout); + + if (m_viewportSize == size) + return; + + m_viewportSize = size; + + // Recalculate the recommended layout size, when the available size (device pixel) changes. + Settings* settings = m_page->settings(); + + int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), size.width()); + + IntSize targetLayoutSize = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, settings->deviceWidth(), settings->deviceHeight(), settings->deviceDPI(), size).layoutSize; + setResizesToContentsUsingLayoutSize(targetLayoutSize); +} + +#endif + +void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset) +{ + Frame* frame = m_page->mainFrame(); + + IntPoint scrollPosition = frame->view()->scrollPosition(); + IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); + + // If the current scroll position in a direction is the max scroll position + // we don't want to scroll at all. + IntSize newScrollOffset; + if (scrollPosition.x() < maximumScrollPosition.x()) + newScrollOffset.setWidth(scrollOffset.width()); + if (scrollPosition.y() < maximumScrollPosition.y()) + newScrollOffset.setHeight(scrollOffset.height()); + + if (newScrollOffset.isZero()) + return; + + frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset); +} + +void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect) +{ + GraphicsContextStateSaver stateSaver(graphicsContext); + graphicsContext.clip(rect); + + if (m_underlayPage) { + m_underlayPage->drawRect(graphicsContext, rect); + + graphicsContext.beginTransparencyLayer(1); + m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); + graphicsContext.endTransparencyLayer(); + return; + } + + m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect); +} + +void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect) +{ + ASSERT(m_pageOverlay); + + GraphicsContextStateSaver stateSaver(graphicsContext); + graphicsContext.clip(rect); + m_pageOverlay->drawRect(graphicsContext, rect); +} + +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::windowScreenDidChange(uint64_t displayID) +{ + m_page->windowScreenDidChange(static_cast<PlatformDisplayID>(displayID)); +} + +void WebPage::scalePage(double scale, const IntPoint& origin) +{ + m_page->setPageScaleFactor(scale, origin); + + send(Messages::WebPageProxy::PageScaleFactorDidChange(scale)); +} + +double WebPage::pageScaleFactor() const +{ + return m_page->pageScaleFactor(); +} + +void WebPage::setDeviceScaleFactor(float scaleFactor) +{ + if (scaleFactor == m_page->deviceScaleFactor()) + return; + + m_page->setDeviceScaleFactor(scaleFactor); + + // Tell all our plug-in views that the device scale factor changed. +#if PLATFORM(MAC) + for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it) + (*it)->setDeviceScaleFactor(scaleFactor); +#endif + + if (m_findController.isShowingOverlay()) { + // We must have updated layout to get the selection rects right. + layoutIfNeeded(); + m_findController.deviceScaleFactorDidChange(); + } +} + +float WebPage::deviceScaleFactor() const +{ + return m_page->deviceScaleFactor(); +} + +void WebPage::setUseFixedLayout(bool fixed) +{ + m_useFixedLayout = fixed; + + FrameView* view = mainFrameView(); + if (!view) + return; + + view->setUseFixedLayout(fixed); + if (!fixed) + view->setFixedLayoutSize(IntSize()); +} + +void WebPage::setFixedLayoutSize(const IntSize& size) +{ + FrameView* view = mainFrameView(); + if (!view) + return; + + view->setFixedLayoutSize(size); + view->forceLayout(); +} + +void WebPage::setPaginationMode(uint32_t mode) +{ + Page::Pagination pagination = m_page->pagination(); + pagination.mode = static_cast<Page::Pagination::Mode>(mode); + m_page->setPagination(pagination); +} + +void WebPage::setPageLength(double pageLength) +{ + Page::Pagination pagination = m_page->pagination(); + pagination.pageLength = pageLength; + m_page->setPagination(pagination); +} + +void WebPage::setGapBetweenPages(double gap) +{ + Page::Pagination pagination = m_page->pagination(); + pagination.gap = gap; + m_page->setPagination(pagination); +} + +void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay) +{ + bool shouldFadeIn = true; + + if (m_pageOverlay) { + m_pageOverlay->setPage(0); + + if (pageOverlay) { + // We're installing a page overlay when a page overlay is already active. + // In this case we don't want to fade in the new overlay. + shouldFadeIn = false; + } + } + + m_pageOverlay = pageOverlay; + m_pageOverlay->setPage(this); + + if (shouldFadeIn) + m_pageOverlay->startFadeInAnimation(); + + m_drawingArea->didInstallPageOverlay(); +#if PLATFORM(WIN) + send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(true)); +#endif + + m_pageOverlay->setNeedsDisplay(); +} + +void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut) +{ + if (pageOverlay != m_pageOverlay) + return; + + if (fadeOut) { + m_pageOverlay->startFadeOutAnimation(); + return; + } + + m_pageOverlay->setPage(0); + m_pageOverlay = nullptr; + + m_drawingArea->didUninstallPageOverlay(); +#if PLATFORM(WIN) + send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(false)); +#endif +} + +PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options) +{ + FrameView* frameView = m_mainFrame->coreFrame()->view(); + if (!frameView) + return 0; + + IntSize bitmapSize = rect.size(); + float deviceScaleFactor = corePage()->deviceScaleFactor(); + bitmapSize.scale(deviceScaleFactor); + + RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, options); + if (!snapshot->bitmap()) + return 0; + + OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); + graphicsContext->applyDeviceScaleFactor(deviceScaleFactor); + graphicsContext->translate(-rect.x(), -rect.y()); + + frameView->updateLayoutAndStyleIfNeededRecursive(); + + PaintBehavior oldBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); + frameView->paint(graphicsContext.get(), rect); + frameView->setPaintBehavior(oldBehavior); + + return snapshot.release(); +} + +PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options) +{ + FrameView* frameView = m_mainFrame->coreFrame()->view(); + if (!frameView) + return 0; + + float combinedScaleFactor = scaleFactor * corePage()->deviceScaleFactor(); + IntSize size(ceil(rect.width() * combinedScaleFactor), ceil(rect.height() * combinedScaleFactor)); + RefPtr<WebImage> snapshot = WebImage::create(size, options); + if (!snapshot->bitmap()) + return 0; + + OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext(); + graphicsContext->applyDeviceScaleFactor(combinedScaleFactor); + graphicsContext->translate(-rect.x(), -rect.y()); + + frameView->updateLayoutAndStyleIfNeededRecursive(); + + PaintBehavior oldBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers); + frameView->paintContents(graphicsContext.get(), rect); + frameView->setPaintBehavior(oldBehavior); + + return snapshot.release(); +} + +PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options) +{ + return scaledSnapshotInDocumentCoordinates(rect, 1, options); +} + +void WebPage::pageDidScroll() +{ + // Hide the find indicator. + m_findController.hideFindIndicator(); + + m_uiClient.pageDidScroll(this); + + send(Messages::WebPageProxy::PageDidScroll()); +} + +#if USE(TILED_BACKING_STORE) +void WebPage::pageDidRequestScroll(const IntPoint& point) +{ + send(Messages::WebPageProxy::PageDidRequestScroll(point)); +} +#endif + +WebContextMenu* WebPage::contextMenu() +{ + if (!m_contextMenu) + m_contextMenu = WebContextMenu::create(this); + return m_contextMenu.get(); +} + +// 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 handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, Page* page) +{ + IntPoint point = page->mainFrame()->view()->windowToContents(platformMouseEvent.position()); + HitTestResult result = page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false); + + Frame* frame = page->mainFrame(); + if (result.innerNonSharedNode()) + frame = result.innerNonSharedNode()->document()->frame(); + + bool handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent); + if (handled) + page->chrome()->showContextMenu(); + + return handled; +} + +static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page, bool onlyUpdateScrollbars) +{ + Frame* frame = page->mainFrame(); + if (!frame->view()) + return false; + + PlatformMouseEvent platformMouseEvent = platform(mouseEvent); + + switch (platformMouseEvent.type()) { + case PlatformEvent::MousePressed: { + if (isContextClick(platformMouseEvent)) + page->contextMenuController()->clearContextMenu(); + + bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent); + if (isContextClick(platformMouseEvent)) + handled = handleContextMenuEvent(platformMouseEvent, page); + + return handled; + } + case PlatformEvent::MouseReleased: + return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent); + case PlatformEvent::MouseMoved: + return frame->eventHandler()->mouseMoved(platformMouseEvent, onlyUpdateScrollbars); + default: + ASSERT_NOT_REACHED(); + return false; + } +} + +void WebPage::mouseEvent(const WebMouseEvent& mouseEvent) +{ + // Don't try to handle any pending mouse events if a context menu is showing. + if (m_isShowingContextMenu) { + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false)); + return; + } + + bool handled = false; + + if (m_pageOverlay) { + // Let the page overlay handle the event. + handled = m_pageOverlay->mouseEvent(mouseEvent); + } + + if (!handled) { + CurrentEvent currentEvent(mouseEvent); + + // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse + // button is currently pressed. It is possible that neither of those things will be true since on + // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one + // of those cases where the page is not active and the mouse is not pressed, then we can fire a more + // efficient scrollbars-only version of the event. + bool onlyUpdateScrollbars = !(m_page->focusController()->isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)); + handled = handleMouseEvent(mouseEvent, m_page.get(), onlyUpdateScrollbars); + } + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled)); +} + +void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled) +{ + // Don't try to handle any pending mouse events if a context menu is showing. + if (m_isShowingContextMenu) { + handled = true; + return; + } + + handled = m_pageOverlay && m_pageOverlay->mouseEvent(mouseEvent); + + if (!handled) { + CurrentEvent currentEvent(mouseEvent); + + // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse + // button is currently pressed. It is possible that neither of those things will be true since on + // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one + // of those cases where the page is not active and the mouse is not pressed, then we can fire a more + // efficient scrollbars-only version of the event. + bool onlyUpdateScrollbars = !(m_page->focusController()->isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)); + handled = handleMouseEvent(mouseEvent, m_page.get(), onlyUpdateScrollbars); + } +} + +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)); +} + +void WebPage::wheelEventSyncForTesting(const WebWheelEvent& wheelEvent, bool& handled) +{ + CurrentEvent currentEvent(wheelEvent); + + handled = handleWheelEvent(wheelEvent, m_page.get()); +} + +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()); + // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler). + if (!handled) + handled = performDefaultBehaviorForKeyEvent(keyboardEvent); + + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled)); +} + +void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled) +{ + CurrentEvent currentEvent(keyboardEvent); + + handled = handleKeyEvent(keyboardEvent, m_page.get()); + if (!handled) + handled = performDefaultBehaviorForKeyEvent(keyboardEvent); +} + +#if ENABLE(GESTURE_EVENTS) +static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page) +{ + Frame* frame = page->mainFrame(); + if (!frame->view()) + return false; + + PlatformGestureEvent platformGestureEvent = platform(gestureEvent); + return frame->eventHandler()->handleGestureEvent(platformGestureEvent); +} + +void WebPage::gestureEvent(const WebGestureEvent& gestureEvent) +{ + CurrentEvent currentEvent(gestureEvent); + + bool handled = handleGestureEvent(gestureEvent, m_page.get()); + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled)); +} +#endif + +void WebPage::validateCommand(const String& commandName, uint64_t callbackID) +{ + 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::ValidateCommandCallback(commandName, isEnabled, state, callbackID)); +} + +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, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + if (uint64_t currentItemID = restoreSession(sessionState)) + goToBackForwardItem(currentItemID, sandboxExtensionHandle); +} + +#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)); +} + +void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled) +{ + CurrentEvent currentEvent(touchEvent); + handled = handleTouchEvent(touchEvent, m_page.get()); +} +#endif + +void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); +} + +void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity); +} + +void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity) +{ + scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity)); +} + +void WebPage::centerSelectionInVisibleArea() +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + frame->selection()->revealSelection(ScrollAlignment::alignCenterAlways); + m_findController.showFindIndicatorInSelection(); +} + +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::viewWillStartLiveResize() +{ + if (!m_page) + return; + + // FIXME: This should propagate to all ScrollableAreas. + if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) { + if (FrameView* view = frame->view()) + view->willStartLiveResize(); + } +} + +void WebPage::viewWillEndLiveResize() +{ + if (!m_page) + return; + + // FIXME: This should propagate to all ScrollableAreas. + if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) { + if (FrameView* view = frame->view()) + view->willEndLiveResize(); + } +} + +void WebPage::setFocused(bool isFocused) +{ + m_page->focusController()->setFocused(isFocused); +} + +void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event) +{ + if (!m_page || !m_page->focusController()) + return; + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + frame->document()->setFocusedNode(0); + + if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) { + PlatformKeyboardEvent platformEvent(platform(event)); + platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown); + m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame->document()->defaultView()).get()); + return; + } + + 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::setCanStartMediaTimerFired() +{ + if (m_page) + m_page->setCanStartMedia(true); +} + +void WebPage::setIsInWindow(bool isInWindow) +{ + if (!isInWindow) { + m_setCanStartMediaTimer.stop(); + m_page->setCanStartMedia(false); + m_page->willMoveOffscreen(); + } else { + // Defer the call to Page::setCanStartMedia() since it ends up sending a syncrhonous messages to the UI process + // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing + // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>. + m_setCanStartMediaTimer.startOneShot(0); + 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; +} + +IntPoint WebPage::screenToWindow(const IntPoint& point) +{ + IntPoint windowPoint; + sendSync(Messages::WebPageProxy::ScreenToWindow(point), Messages::WebPageProxy::ScreenToWindow::Reply(windowPoint)); + return windowPoint; +} + +IntRect WebPage::windowToScreen(const IntRect& rect) +{ + IntRect screenRect; + sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect)); + return screenRect; +} + +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()); +} + +KeyboardUIMode WebPage::keyboardUIMode() +{ + bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled(); + return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0)); +} + +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. + + // Retain the SerializedScriptValue at this level so it (and the internal data) lives + // long enough for the DataReference to be encoded by the sent message. + RefPtr<SerializedScriptValue> serializedResultValue; + CoreIPC::DataReference dataReference; + + JSLock lock(SilenceAssertionsOnly); + if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) { + if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0))) + dataReference = serializedResultValue->data(); + } + + send(Messages::WebPageProxy::ScriptValueCallback(dataReference, 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)); +} + +static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const KURL& resourceURL) +{ + DocumentLoader* loader = frame->loader()->documentLoader(); + if (!loader) + return 0; + + RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL); + if (!subresource) + return 0; + + return subresource->data(); +} + +void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID) +{ + CoreIPC::DataReference dataReference; + KURL resourceURL(KURL(), resourceURLString); + + RefPtr<SharedBuffer> buffer; + if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) { + buffer = resourceDataForFrame(frame->coreFrame(), resourceURL); + if (!buffer) { + // Try to get the resource data from the cache. + buffer = cachedResponseDataForURL(resourceURL); + } + + if (buffer) + 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 ((data = frame->webArchiveData())) + dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get())); + } +#endif + + send(Messages::WebPageProxy::DataCallback(dataReference, callbackID)); +} + +void WebPage::forceRepaintWithoutCallback() +{ + m_drawingArea->forceRepaint(); +} + +void WebPage::forceRepaint(uint64_t callbackID) +{ + forceRepaintWithoutCallback(); + send(Messages::WebPageProxy::VoidCallback(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->setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey())); + settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey())); + settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey())); + 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())); +#if ENABLE(WEB_ARCHIVE) + settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey())); +#endif + settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey())); + settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey())); + settings->setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey())); + settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey())); + settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey())); + settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey())); + settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey())); + settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey())); + settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey())); + settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey())); + settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey())); + + settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey())); + settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey())); + settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey())); + settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey())); + settings->setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey())); + settings->setDeviceDPI(store.getUInt32ValueForKey(WebPreferencesKey::deviceDPIKey())); + settings->setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey())); + settings->setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey())); + settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey()))); + settings->setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey())); + + settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); + settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); + settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing()); + settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey())); + settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey())); + settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey())); + settings->setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey())); + settings->setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey())); + settings->setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey())); + +#if ENABLE(SQL_DATABASE) + AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey())); +#endif + +#if ENABLE(FULLSCREEN_API) + settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey())); +#endif + + settings->setLocalStorageDatabasePath(WebProcess::shared().localStorageDirectory()); + +#if USE(AVFOUNDATION) + settings->setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey())); +#endif + +#if ENABLE(WEB_SOCKETS) + settings->setUseHixie76WebSocketProtocol(store.getBoolValueForKey(WebPreferencesKey::hixie76WebSocketProtocolEnabledKey())); +#endif + +#if ENABLE(WEB_AUDIO) + settings->setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey())); +#endif + + settings->setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey())); + settings->setSuppressIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressIncrementalRenderingKey())); + settings->setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey())); + settings->setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey())); + +#if ENABLE(VIDEO_TRACK) + settings->setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey())); + settings->setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey())); + settings->setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey())); +#endif + + platformPreferencesDidChange(store); +} + +#if ENABLE(INSPECTOR) +WebInspector* WebPage::inspector() +{ + if (m_isClosed) + return 0; + if (!m_inspector) + m_inspector = WebInspector::create(this); + return m_inspector.get(); +} +#endif + +#if ENABLE(FULLSCREEN_API) +WebFullScreenManager* WebPage::fullScreenManager() +{ + if (!m_fullScreenManager) + m_fullScreenManager = WebFullScreenManager::create(this); + return m_fullScreenManager.get(); +} +#endif + +NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager() +{ + if (m_notificationPermissionRequestManager) + return m_notificationPermissionRequestManager.get(); + + m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this); + return m_notificationPermissionRequestManager.get(); +} + +#if !PLATFORM(GTK) && !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() == PlatformEvent::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 + +#if PLATFORM(WIN) +void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags) +{ + if (!m_page) { + send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession())); + return; + } + + DragData dragData(dataMap, 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(); + } +} + +#elif PLATFORM(QT) || PLATFORM(GTK) +void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData) +{ + if (!m_page) { + send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession())); +#if PLATFORM(QT) + QMimeData* data = const_cast<QMimeData*>(dragData.platformData()); +#elif PLATFORM(GTK) + DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData()); +#endif + delete data; + return; + } + + 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(); + } + // DragData does not delete its platformData so we need to do that here. +#if PLATFORM(QT) + QMimeData* data = const_cast<QMimeData*>(dragData.platformData()); +#elif PLATFORM(GTK) + DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData()); +#endif + delete data; +} + +#else +void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle) +{ + if (!m_page) { + send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession())); + 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: { + ASSERT(!m_pendingDropSandboxExtension); + + m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle); + + m_page->dragController()->performDrag(&dragData); + + // If we started loading a local file, the sandbox extension tracker would have adopted this + // pending drop sandbox extension. If not, we'll play it safe and invalidate it. + if (m_pendingDropSandboxExtension) { + m_pendingDropSandboxExtension->invalidate(); + m_pendingDropSandboxExtension = nullptr; + } + + break; + } + + default: + ASSERT_NOT_REACHED(); + } +} +#endif + +void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation) +{ + IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y()); + IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y()); + + m_page->dragController()->dragEnded(); + FrameView* view = m_page->mainFrame()->view(); + if (!view) + return; + // FIXME: These are fake modifier keys here, but they should be real ones instead. + PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime()); + m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation); +} + +void WebPage::willPerformLoadDragDestinationAction() +{ + m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release()); +} + +WebUndoStep* WebPage::webUndoStep(uint64_t stepID) +{ + return m_undoStepMap.get(stepID).get(); +} + +void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry) +{ + m_undoStepMap.set(stepID, entry); +} + +void WebPage::removeWebEditCommand(uint64_t stepID) +{ + m_undoStepMap.remove(stepID); +} + +void WebPage::unapplyEditCommand(uint64_t stepID) +{ + WebUndoStep* step = webUndoStep(stepID); + if (!step) + return; + + step->step()->unapply(); +} + +void WebPage::reapplyEditCommand(uint64_t stepID) +{ + WebUndoStep* step = webUndoStep(stepID); + if (!step) + return; + + m_isInRedo = true; + step->step()->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; +} + +#if ENABLE(WEB_PROCESS_SANDBOX) +void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle) +{ + SandboxExtension::create(handle)->consumePermanently(); +} +#endif + +void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) +{ + m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed); +} + +void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed) +{ + notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, 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); +} + +#if PLATFORM(GTK) +void WebPage::failedToShowPopupMenu() +{ + if (!m_activePopupMenu) + return; + + m_activePopupMenu->client()->popupDidHide(); +} +#endif + +void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) +{ + if (!m_contextMenu) + return; + + m_contextMenu->itemSelected(item); + m_contextMenu = 0; +} + +void WebPage::replaceSelectionWithText(Frame* frame, const String& text) +{ + bool selectReplacement = true; + bool smartReplace = false; + return frame->editor()->replaceSelectionWithText(text, selectReplacement, smartReplace); +} + +void WebPage::clearSelection() +{ + m_page->focusController()->focusedOrMainFrame()->selection()->clear(); +} + +bool WebPage::mainFrameHasCustomRepresentation() const +{ + if (Frame* frame = mainFrame()) + return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->frameHasCustomRepresentation(); + + return false; +} + +void WebPage::didChangeScrollOffsetForMainFrame() +{ + Frame* frame = m_page->mainFrame(); + IntPoint scrollPosition = frame->view()->scrollPosition(); + IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); + IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition(); + + bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x()); + bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x()); + + if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) { + send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide)); + + m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide; + m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide; + } +} + +void WebPage::mainFrameDidLayout() +{ + unsigned pageCount = m_page->pageCount(); + if (pageCount != m_cachedPageCount) { + send(Messages::WebPageProxy::DidChangePageCount(pageCount)); + m_cachedPageCount = pageCount; + } +} + +#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); +} + +#endif + +bool WebPage::windowIsFocused() const +{ +#if PLATFORM(MAC) + if (!m_windowIsVisible) + return false; +#endif + return m_page->focusController()->isFocused() && m_page->focusController()->isActive(); +} + +void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + if (messageID.is<CoreIPC::MessageClassDrawingArea>()) { + if (m_drawingArea) + m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments); + return; + } + +#if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING) + if (messageID.is<CoreIPC::MessageClassLayerTreeHost>()) { + if (m_drawingArea) + m_drawingArea->didReceiveLayerTreeHostMessage(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 + +#if ENABLE(FULLSCREEN_API) + if (messageID.is<CoreIPC::MessageClassWebFullScreenManager>()) { + fullScreenManager()->didReceiveMessage(connection, messageID, arguments); + return; + } +#endif + + didReceiveWebPageMessage(connection, messageID, arguments); +} + +void WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply) +{ + 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) +{ + Frame* mainframe = m_mainFrame->coreFrame(); + HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true); + + Node* node = result.innerNode(); + + if (!node) + return; + + IntRect zoomableArea = node->getRect(); + + while (true) { + bool found = !node->isTextNode() && !node->isShadowRoot(); + + // No candidate found, bail out. + if (!found && !node->parentNode()) + return; + + // Candidate found, and it is a better candidate than its parent. + // NB: A parent is considered a better candidate iff the node is + // contained by it and it is the only child. + if (found && (!node->parentNode() || node->parentNode()->childNodeCount() != 1)) + break; + + node = node->parentNode(); + zoomableArea.unite(node->getRect()); + } + + if (node->document() && node->document()->frame() && node->document()->frame()->view()) { + const ScrollView* view = node->document()->frame()->view(); + zoomableArea = view->contentsToWindow(zoomableArea); + } + + send(Messages::WebPageProxy::DidFindZoomableArea(point, 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::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension) +{ + setPendingProvisionalSandboxExtension(pendingDropSandboxExtension); +} + +void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) +{ + ASSERT(frame->isMainFrame()); + + setPendingProvisionalSandboxExtension(SandboxExtension::create(handle)); +} + +void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension) +{ + // If we get two beginLoad calls in succession, without a provisional load starting, then + // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case. + if (m_pendingProvisionalSandboxExtension) { + m_pendingProvisionalSandboxExtension->invalidate(); + m_pendingProvisionalSandboxExtension = nullptr; + } + + m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension; +} + +static bool shouldReuseCommittedSandboxExtension(WebFrame* frame) +{ + ASSERT(frame->isMainFrame()); + + FrameLoader* frameLoader = frame->coreFrame()->loader(); + FrameLoadType frameLoadType = frameLoader->loadType(); + + // If the page is being reloaded, it should reuse whatever extension is committed. + if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin) + return true; + + DocumentLoader* documentLoader = frameLoader->documentLoader(); + DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader(); + if (!documentLoader || !provisionalDocumentLoader) + return false; + + if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile()) + return true; + + return false; +} + +void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame) +{ + if (!frame->isMainFrame()) + return; + + // We should only reuse the commited sandbox extension if it is not null. It can be + // null if the last load was for an error page. + if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame)) { + m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release(); + ASSERT(!m_committedSandboxExtension); + } + + 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; + + if (!m_provisionalSandboxExtension) + return; + + m_provisionalSandboxExtension->invalidate(); + m_provisionalSandboxExtension = nullptr; +} + +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 + +#if USE(CG) +static RetainPtr<CGPDFDocumentRef> pdfDocumentForPrintingFrame(Frame* coreFrame) +{ + Document* document = coreFrame->document(); + if (!document) + return 0; + + if (!document->isPluginDocument()) + return 0; + + PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget()); + if (!pluginView) + return 0; + + return pluginView->pdfDocumentForPrinting(); +} +#endif // USE(CG) + +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 USE(CG) + if (pdfDocumentForPrintingFrame(coreFrame)) + return; +#endif // USE(CG) + + if (!m_printContext) + m_printContext = adoptPtr(new PrintContext(coreFrame)); + + m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight); + + float fullPageHeight; + m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true); +} + +void WebPage::endPrinting() +{ + m_printContext = nullptr; +} + +void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID) +{ + Vector<IntRect> resultPageRects; + double resultTotalScaleFactorForPrinting = 1; + + beginPrinting(frameID, printInfo); + + if (m_printContext) { + resultPageRects = m_printContext->pageRects(); + resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor; + } +#if USE(CG) + else { + WebFrame* frame = WebProcess::shared().webFrame(frameID); + Frame* coreFrame = frame ? frame->coreFrame() : 0; + RetainPtr<CGPDFDocumentRef> pdfDocument = coreFrame ? pdfDocumentForPrintingFrame(coreFrame) : 0; + if (pdfDocument && CGPDFDocumentAllowsPrinting(pdfDocument.get())) { + CFIndex pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument.get()); + IntRect pageRect(0, 0, ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight)); + for (CFIndex i = 1; i <= pageCount; ++i) { + resultPageRects.append(pageRect); + pageRect.move(0, pageRect.height()); + } + } + } +#endif // USE(CG) + + // 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)); + + send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID)); +} + +#if USE(CG) +static inline CGFloat roundCGFloat(CGFloat f) +{ + if (sizeof(CGFloat) == sizeof(float)) + return roundf(static_cast<float>(f)); + return static_cast<CGFloat>(round(f)); +} + +static void drawPDFPage(CGPDFDocumentRef pdfDocument, CFIndex pageIndex, CGContextRef context, CGFloat pageSetupScaleFactor, CGSize paperSize) +{ + CGContextSaveGState(context); + + CGContextScaleCTM(context, pageSetupScaleFactor, pageSetupScaleFactor); + + CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument, pageIndex + 1); + CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox); + if (CGRectIsEmpty(cropBox)) + cropBox = CGRectIntersection(cropBox, CGPDFPageGetBoxRect(page, kCGPDFMediaBox)); + else + cropBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); + + bool shouldRotate = (paperSize.width < paperSize.height) != (cropBox.size.width < cropBox.size.height); + if (shouldRotate) + swap(cropBox.size.width, cropBox.size.height); + + // Center. + CGFloat widthDifference = paperSize.width / pageSetupScaleFactor - cropBox.size.width; + CGFloat heightDifference = paperSize.height / pageSetupScaleFactor - cropBox.size.height; + if (widthDifference || heightDifference) + CGContextTranslateCTM(context, roundCGFloat(widthDifference / 2), roundCGFloat(heightDifference / 2)); + + if (shouldRotate) { + CGContextRotateCTM(context, static_cast<CGFloat>(piOverTwoDouble)); + CGContextTranslateCTM(context, 0, -cropBox.size.width); + } + + CGContextDrawPDFPage(context, page); + + CGContextRestoreGState(context); +} +#endif // USE(CG) + +#if PLATFORM(MAC) || PLATFORM(WIN) +void WebPage::drawRectToPDF(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + Frame* coreFrame = frame ? frame->coreFrame() : 0; + + RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0)); + + if (coreFrame) { +#if !USE(CG) + UNUSED_PARAM(printInfo); + + ASSERT(coreFrame->document()->printing()); +#else + ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame)); + + // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. + RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); + + CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height()); + RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); + RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CGPDFContextBeginPage(context.get(), pageInfo.get()); + + if (RetainPtr<CGPDFDocumentRef> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) { + CFIndex pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument.get()); + IntSize paperSize(ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight)); + IntRect pageRect(IntPoint(), paperSize); + for (CFIndex i = 0; i < pageCount; ++i) { + if (pageRect.intersects(rect)) { + CGContextSaveGState(context.get()); + + CGContextTranslateCTM(context.get(), pageRect.x() - rect.x(), pageRect.y() - rect.y()); + drawPDFPage(pdfDocument.get(), i, context.get(), printInfo.pageSetupScaleFactor, paperSize); + + CGContextRestoreGState(context.get()); + } + pageRect.move(0, pageRect.height()); + } + } else { + GraphicsContext ctx(context.get()); + ctx.scale(FloatSize(1, -1)); + ctx.translate(0, -rect.height()); + m_printContext->spoolRect(ctx, rect); + } + + CGPDFContextEndPage(context.get()); + CGPDFContextClose(context.get()); +#endif + } + + send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID)); +} + +void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID) +{ + WebFrame* frame = WebProcess::shared().webFrame(frameID); + Frame* coreFrame = frame ? frame->coreFrame() : 0; + + RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0)); + + if (coreFrame) { + +#if !USE(CG) + ASSERT(coreFrame->document()->printing()); +#else + ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame)); + + RetainPtr<CGPDFDocumentRef> pdfDocument = pdfDocumentForPrintingFrame(coreFrame); + + // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. + RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); + + CGRect mediaBox = m_printContext && m_printContext->pageCount() ? m_printContext->pageRect(0) : CGRectMake(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight); + RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0)); + size_t pageCount = m_printContext ? m_printContext->pageCount() : CGPDFDocumentGetNumberOfPages(pdfDocument.get()); + for (uint32_t page = first; page < first + count; ++page) { + if (page >= pageCount) + break; + + RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CGPDFContextBeginPage(context.get(), pageInfo.get()); + + if (pdfDocument) + drawPDFPage(pdfDocument.get(), page, context.get(), printInfo.pageSetupScaleFactor, CGSizeMake(printInfo.availablePaperWidth, printInfo.availablePaperHeight)); + else { + GraphicsContext ctx(context.get()); + ctx.scale(FloatSize(1, -1)); + ctx.translate(0, -m_printContext->pageRect(page).height()); + m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width()); + } + + CGPDFContextEndPage(context.get()); + } + CGPDFContextClose(context.get()); +#endif + } + + send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID)); +} +#endif + +void WebPage::runModal() +{ + if (m_isClosed) + return; + if (m_isRunningModal) + return; + + m_isRunningModal = true; + send(Messages::WebPageProxy::RunModal()); + RunLoop::run(); + ASSERT(!m_isRunningModal); +} + +void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled) +{ + m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled); +} + +bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) +{ + if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol())) + return true; + return platformCanHandleRequest(request); +} + +#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD) +void WebPage::handleCorrectionPanelResult(const String& result) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + frame->editor()->handleCorrectionPanelResult(result); +} +#endif + +void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); +} + +void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); +} + +void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time) +{ + mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time)); +} + +String WebPage::viewportConfigurationAsText(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight) +{ + ViewportArguments arguments = mainFrame()->document()->viewportArguments(); + ViewportAttributes attrs = WebCore::computeViewportAttributes(arguments, /* default layout width for non-mobile pages */ 980, deviceWidth, deviceHeight, deviceDPI, IntSize(availableWidth, availableHeight)); + WebCore::restrictMinimumScaleFactorToViewportSize(attrs, IntSize(availableWidth, availableHeight)); + WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attrs); + return String::format("viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n", attrs.layoutSize.width(), attrs.layoutSize.height(), attrs.initialScale, attrs.minimumScale, attrs.maximumScale, attrs.userScalable); +} + +void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || !frame->editor()->canEdit()) + return; + + Vector<CompositionUnderline> underlines; + underlines.append(CompositionUnderline(0, compositionString.length(), Color(Color::black), false)); + frame->editor()->setComposition(compositionString, underlines, from, from + length); +} + +bool WebPage::hasCompositionForTesting() +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + return frame && frame->editor()->hasComposition(); +} + +void WebPage::confirmCompositionForTesting(const String& compositionString) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || !frame->editor()->canEdit()) + return; + + if (compositionString.isNull()) + frame->editor()->confirmComposition(); + frame->editor()->confirmComposition(compositionString); +} + +Frame* WebPage::mainFrame() const +{ + return m_page ? m_page->mainFrame() : 0; +} + +FrameView* WebPage::mainFrameView() const +{ + if (Frame* frame = mainFrame()) + return frame->view(); + + return 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h new file mode 100644 index 000000000..40072cfbf --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h @@ -0,0 +1,748 @@ +/* + * 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 "ImmutableArray.h" +#include "InjectedBundlePageContextMenuClient.h" +#include "InjectedBundlePageEditorClient.h" +#include "InjectedBundlePageFormClient.h" +#include "InjectedBundlePageFullScreenClient.h" +#include "InjectedBundlePageLoaderClient.h" +#include "InjectedBundlePagePolicyClient.h" +#include "InjectedBundlePageResourceLoadClient.h" +#include "InjectedBundlePageUIClient.h" +#include "MessageSender.h" +#include "Plugin.h" +#include "SandboxExtension.h" +#include "ShareableBitmap.h" +#include "WebUndoStep.h" +#include <WebCore/DragData.h> +#include <WebCore/Editor.h> +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/IntRect.h> +#include <WebCore/PlatformScreen.h> +#include <WebCore/ScrollTypes.h> +#include <WebCore/WebCoreKeyboardUIMode.h> +#include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +#if PLATFORM(QT) +#include "ArgumentCodersQt.h" +#include "QtNetworkAccessManager.h" +#include "QtNetworkReply.h" +#include "QtNetworkReplyData.h" +#include "QtNetworkRequestData.h" +#include <QNetworkReply> +#include <QNetworkRequest> +#endif + +#if PLATFORM(GTK) +#include "ArgumentCodersGtk.h" +#endif + +#if ENABLE(TOUCH_EVENTS) +#include <WebCore/PlatformTouchEvent.h> +#endif + +#if PLATFORM(MAC) +#include "DictionaryPopupInfo.h" +#include <wtf/RetainPtr.h> +OBJC_CLASS NSDictionary; +OBJC_CLASS NSObject; +OBJC_CLASS WKAccessibilityWebPageObject; +#endif + +namespace CoreIPC { + class ArgumentDecoder; + class Connection; + class MessageID; +} + +namespace WebCore { + class GraphicsContext; + class Frame; + class FrameView; + class KeyboardEvent; + class Page; + class PrintContext; + class Range; + class ResourceRequest; + class SharedBuffer; + class VisibleSelection; + struct KeypressCommand; +} + +namespace WebKit { + +class DrawingArea; +class InjectedBundleBackForwardList; +class NotificationPermissionRequestManager; +class PageOverlay; +class PluginView; +class SessionState; +class WebContextMenu; +class WebContextMenuItemData; +class WebEvent; +class WebFrame; +class WebFullScreenManager; +class WebImage; +class WebInspector; +class WebKeyboardEvent; +class WebMouseEvent; +class WebNotificationClient; +class WebOpenPanelResultListener; +class WebPageGroupProxy; +class WebPopupMenu; +class WebWheelEvent; +struct AttributedString; +struct EditorState; +struct PrintInfo; +struct WebPageCreationParameters; +struct WebPreferencesStore; + +#if ENABLE(GESTURE_EVENTS) +class WebGestureEvent; +#endif + +#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; } + WebCore::IntRect bounds() const { return WebCore::IntRect(WebCore::IntPoint(), size()); } + + InjectedBundleBackForwardList* backForwardList(); + DrawingArea* drawingArea() const { return m_drawingArea.get(); } + + WebPageGroupProxy* pageGroup() const { return m_pageGroup.get(); } + + void scrollMainFrameIfNotAtMaxScrollPosition(const WebCore::IntSize& scrollOffset); + + void scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity); + + void centerSelectionInVisibleArea(); + +#if ENABLE(INSPECTOR) + WebInspector* inspector(); +#endif + +#if ENABLE(FULLSCREEN_API) + WebFullScreenManager* fullScreenManager(); +#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 drawPageOverlay(WebCore::GraphicsContext&, const WebCore::IntRect&); + void layoutIfNeeded(); + + // -- Called from WebCore clients. +#if PLATFORM(MAC) + bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*, bool saveCommands); +#elif !PLATFORM(GTK) + bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*); +#endif + + void show(); + String userAgent() const { return m_userAgent; } + WebCore::IntRect windowResizerRect() const; + WebCore::KeyboardUIMode keyboardUIMode(); + + WebUndoStep* webUndoStep(uint64_t); + void addWebUndoStep(uint64_t, WebUndoStep*); + 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*); + void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + + // -- InjectedBundle methods + void initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient*); + void initializeInjectedBundleEditorClient(WKBundlePageEditorClient*); + void initializeInjectedBundleFormClient(WKBundlePageFormClient*); + void initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient*); + void initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient*); + void initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient*); + void initializeInjectedBundleUIClient(WKBundlePageUIClient*); +#if ENABLE(FULLSCREEN_API) + void initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient*); +#endif + + InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; } + InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; } + InjectedBundlePageFormClient& injectedBundleFormClient() { return m_formClient; } + InjectedBundlePageLoaderClient& injectedBundleLoaderClient() { return m_loaderClient; } + InjectedBundlePagePolicyClient& injectedBundlePolicyClient() { return m_policyClient; } + InjectedBundlePageResourceLoadClient& injectedBundleResourceLoadClient() { return m_resourceLoadClient; } + InjectedBundlePageUIClient& injectedBundleUIClient() { return m_uiClient; } +#if ENABLE(FULLSCREEN_API) + InjectedBundlePageFullScreenClient& injectedBundleFullScreenClient() { return m_fullScreenClient; } +#endif + + void setUnderlayPage(PassRefPtr<WebPage> underlayPage) { m_underlayPage = underlayPage; } + + bool findStringFromInjectedBundle(const String&, FindOptions); + + WebFrame* mainWebFrame() const { return m_mainFrame.get(); } + + WebCore::Frame* mainFrame() const; // May return 0. + WebCore::FrameView* mainFrameView() const; // May return 0. + + PassRefPtr<Plugin> createPlugin(WebFrame*, const Plugin::Parameters&); + + EditorState editorState() const; + + String renderTreeExternalRepresentation() const; + uint64_t renderTreeSize() const; + + void setTracksRepaints(bool); + bool isTrackingRepaints() const; + void resetTrackedRepaints(); + PassRefPtr<ImmutableArray> trackedRepaintRects(); + + 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 windowScreenDidChange(uint64_t); + + void scalePage(double scale, const WebCore::IntPoint& origin); + double pageScaleFactor() const; + + void setUseFixedLayout(bool); + bool useFixedLayout() const { return m_useFixedLayout; } + void setFixedLayoutSize(const WebCore::IntSize&); + + void setPaginationMode(uint32_t /* WebCore::Page::Pagination::Mode */); + void setPageLength(double); + void setGapBetweenPages(double); + + bool drawsBackground() const { return m_drawsBackground; } + bool drawsTransparentBackground() const { return m_drawsTransparentBackground; } + + void stopLoading(); + void stopLoadingFrame(uint64_t frameID); + void setDefersLoading(bool deferLoading); + +#if USE(ACCELERATED_COMPOSITING) + 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; } +#elif PLATFORM(WIN) + HWND nativeWindow() const { return m_nativeWindow; } +#endif + + bool windowIsFocused() const; + void installPageOverlay(PassRefPtr<PageOverlay>); + void uninstallPageOverlay(PageOverlay*, bool fadeOut); + bool hasPageOverlay() const { return m_pageOverlay; } + WebCore::IntPoint screenToWindow(const WebCore::IntPoint&); + WebCore::IntRect windowToScreen(const WebCore::IntRect&); + + PassRefPtr<WebImage> snapshotInViewCoordinates(const WebCore::IntRect&, ImageOptions); + PassRefPtr<WebImage> snapshotInDocumentCoordinates(const WebCore::IntRect&, ImageOptions); + PassRefPtr<WebImage> scaledSnapshotInDocumentCoordinates(const WebCore::IntRect&, double scaleFactor, ImageOptions); + + static const WebEvent* currentEvent(); + + FindController& findController() { return m_findController; } + GeolocationPermissionRequestManager& geolocationPermissionRequestManager() { return m_geolocationPermissionRequestManager; } + NotificationPermissionRequestManager* notificationPermissionRequestManager(); + + void pageDidScroll(); +#if USE(TILED_BACKING_STORE) + void pageDidRequestScroll(const WebCore::IntPoint&); + void setFixedVisibleContentRect(const WebCore::IntRect&); + void setResizesToContentsUsingLayoutSize(const WebCore::IntSize&); + void resizeToContentsIfNeeded(); + void setViewportSize(const WebCore::IntSize&); + WebCore::IntSize viewportSize() const { return m_viewportSize; } +#endif + + WebContextMenu* contextMenu(); + + bool hasLocalDataForURL(const WebCore::KURL&); + String cachedResponseMIMETypeForURL(const WebCore::KURL&); + String cachedSuggestedFilenameForURL(const WebCore::KURL&); + PassRefPtr<WebCore::SharedBuffer> cachedResponseDataForURL(const WebCore::KURL&); + + static bool canHandleRequest(const WebCore::ResourceRequest&); + + class SandboxExtensionTracker { + public: + ~SandboxExtensionTracker(); + + void invalidate(); + + void beginLoad(WebFrame*, const SandboxExtension::Handle& handle); + void willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension); + void didStartProvisionalLoad(WebFrame*); + void didCommitProvisionalLoad(WebFrame*); + void didFailProvisionalLoad(WebFrame*); + + private: + void setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension>); + + RefPtr<SandboxExtension> m_pendingProvisionalSandboxExtension; + RefPtr<SandboxExtension> m_provisionalSandboxExtension; + RefPtr<SandboxExtension> m_committedSandboxExtension; + }; + + SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; } + +#if PLATFORM(QT) + void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); + void confirmComposition(const String& text, int64_t selectionStart, int64_t selectionLength); + void cancelComposition(); +#endif + +#if PLATFORM(MAC) + void registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elemenToken, const CoreIPC::DataReference& windowToken); + WKAccessibilityWebPageObject* accessibilityRemoteObject(); + WebCore::IntPoint accessibilityPosition() const { return m_accessibilityPosition; } + + void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput); + + void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, EditorState& newState); + void confirmComposition(EditorState& newState); + void cancelComposition(EditorState& newState); + void insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState); + void getMarkedRange(uint64_t& location, uint64_t& length); + void getSelectedRange(uint64_t& location, uint64_t& length); + void getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString&); + void characterIndexForPoint(const WebCore::IntPoint point, uint64_t& result); + void firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect); + void executeKeypressCommands(const Vector<WebCore::KeypressCommand>&, bool& handled, EditorState& newState); + void writeSelectionToPasteboard(const WTF::String& pasteboardName, const WTF::Vector<WTF::String>& pasteboardTypes, bool& result); + void readSelectionFromPasteboard(const WTF::String& pasteboardName, bool& result); + void shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent&, bool& result); + void acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent&, bool& result); + bool performNonEditingBehaviorForSelector(const String&); + +#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&); + + void gestureWillBegin(const WebCore::IntPoint&, bool& canBeginPanning); + void gestureDidScroll(const WebCore::IntSize&); + void gestureDidEnd(); +#endif + + void setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length); + bool hasCompositionForTesting(); + void confirmCompositionForTesting(const String& compositionString); + + // 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) + void performDictionaryLookupForSelection(DictionaryPopupInfo::Type, WebCore::Frame*, const WebCore::VisibleSelection&); + + bool isSpeaking(); + void speak(const String&); + void stopSpeaking(); + + bool isSmartInsertDeleteEnabled() const { return m_isSmartInsertDeleteEnabled; } +#endif + + void replaceSelectionWithText(WebCore::Frame*, const String&); + void clearSelection(); +#if PLATFORM(WIN) + void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap&, uint32_t flags); +#elif PLATFORM(QT) || PLATFORM(GTK) + void performDragControllerAction(uint64_t action, WebCore::DragData); +#else + void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags, const SandboxExtension::Handle&); +#endif + void dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation); + + void willPerformLoadDragDestinationAction(); + + void beginPrinting(uint64_t frameID, const PrintInfo&); + void endPrinting(); + void computePagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID); +#if PLATFORM(MAC) || PLATFORM(WIN) + void drawRectToPDF(uint64_t frameID, const PrintInfo&, const WebCore::IntRect&, uint64_t callbackID); + void drawPagesToPDF(uint64_t frameID, const PrintInfo&, uint32_t first, uint32_t count, uint64_t callbackID); +#endif + + bool mainFrameHasCustomRepresentation() const; + + void didChangeScrollOffsetForMainFrame(); + + void mainFrameDidLayout(); + + bool canRunBeforeUnloadConfirmPanel() const { return m_canRunBeforeUnloadConfirmPanel; } + void setCanRunBeforeUnloadConfirmPanel(bool canRunBeforeUnloadConfirmPanel) { m_canRunBeforeUnloadConfirmPanel = canRunBeforeUnloadConfirmPanel; } + + bool canRunModal() const { return m_canRunModal; } + void setCanRunModal(bool canRunModal) { m_canRunModal = canRunModal; } + + void runModal(); + + void setDeviceScaleFactor(float); + float deviceScaleFactor() const; + + void setMemoryCacheMessagesEnabled(bool); + + void forceRepaintWithoutCallback(); + + void unmarkAllMisspellings(); + void unmarkAllBadGrammar(); + +#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD) + void handleCorrectionPanelResult(const String&); +#endif + + // For testing purpose. + void simulateMouseDown(int button, WebCore::IntPoint, int clickCount, WKEventModifiers, double time); + void simulateMouseUp(int button, WebCore::IntPoint, int clickCount, WKEventModifiers, double time); + void simulateMouseMotion(WebCore::IntPoint, double time); + String viewportConfigurationAsText(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight); + + void contextMenuShowing() { m_isShowingContextMenu = true; } + +#if PLATFORM(QT) + void registerApplicationScheme(const String& scheme); + void applicationSchemeReply(const QtNetworkReplyData&); + void receivedApplicationSchemeRequest(const QNetworkRequest&, QtNetworkReply*); +#endif + void wheelEvent(const WebWheelEvent&); +#if ENABLE(GESTURE_EVENTS) + void gestureEvent(const WebGestureEvent&); +#endif + +private: + WebPage(uint64_t pageID, const WebPageCreationParameters&); + + virtual Type type() const { return APIType; } + + void platformInitialize(); + + void didReceiveWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + void didReceiveSyncWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + +#if !PLATFORM(MAC) + static const char* interpretKeyEvent(const WebCore::KeyboardEvent*); +#endif + bool performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&); + +#if PLATFORM(MAC) + bool executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>&, WebCore::KeyboardEvent*); +#endif + + 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&); + void loadURLRequest(const WebCore::ResourceRequest&, const SandboxExtension::Handle&); + void loadHTMLString(const String& htmlString, const String& baseURL); + void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL); + void loadPlainTextString(const String&); + void linkClicked(const String& url, const WebMouseEvent&); + void reload(bool reloadFromOrigin); + void goForward(uint64_t, const SandboxExtension::Handle&); + void goBack(uint64_t, const SandboxExtension::Handle&); + void goToBackForwardItem(uint64_t, const SandboxExtension::Handle&); + void tryRestoreScrollPosition(); + void setActive(bool); + void setFocused(bool); + void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&); + void setWindowResizerSize(const WebCore::IntSize&); + void setIsInWindow(bool); + void validateCommand(const String&, uint64_t); + void executeEditCommand(const String&); + + void mouseEvent(const WebMouseEvent&); + void mouseEventSyncForTesting(const WebMouseEvent&, bool&); + void wheelEventSyncForTesting(const WebWheelEvent&, bool&); + void keyEvent(const WebKeyboardEvent&); + void keyEventSyncForTesting(const WebKeyboardEvent&, bool&); +#if ENABLE(TOUCH_EVENTS) + void touchEvent(const WebTouchEvent&); + void touchEventSyncForTesting(const WebTouchEvent&, bool& handled); +#endif + void contextMenuHidden() { m_isShowingContextMenu = false; } + + static void scroll(WebCore::Page*, WebCore::ScrollDirection, WebCore::ScrollGranularity); + static void logicalScroll(WebCore::Page*, WebCore::ScrollLogicalDirection, WebCore::ScrollGranularity); + + uint64_t restoreSession(const SessionState&); + void restoreSessionAndNavigateToCurrentItem(const SessionState&, const SandboxExtension::Handle&); + + void didRemoveBackForwardItem(uint64_t); + + void setDrawsBackground(bool); + void setDrawsTransparentBackground(bool); + + void viewWillStartLiveResize(); + void viewWillEndLiveResize(); + + void getContentsAsString(uint64_t callbackID); + void getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID); + void getResourceDataFromFrame(uint64_t frameID, const String& resourceURL, 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 forceRepaint(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 performDictionaryLookupAtLocation(const WebCore::FloatPoint&); + void performDictionaryLookupForRange(DictionaryPopupInfo::Type, WebCore::Frame*, WebCore::Range*, NSDictionary *options); + + 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); + +#if PLATFORM(GTK) + void failedToShowPopupMenu(); +#endif + + void didChooseFilesForOpenPanel(const Vector<String>&); + void didCancelForOpenPanel(); +#if ENABLE(WEB_PROCESS_SANDBOX) + void extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle&); +#endif + + void didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed); + void didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed); + + void advanceToNextMisspelling(bool startBeforeSelection); + void changeSpellingToWord(const String& word); +#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 + + void setCanStartMediaTimerFired(); + + static bool platformCanHandleRequest(const WebCore::ResourceRequest&); + + OwnPtr<WebCore::Page> m_page; + RefPtr<WebFrame> m_mainFrame; + RefPtr<InjectedBundleBackForwardList> m_backForwardList; + + RefPtr<WebPageGroupProxy> m_pageGroup; + + String m_userAgent; + + WebCore::IntSize m_viewSize; + OwnPtr<DrawingArea> m_drawingArea; + bool m_useFixedLayout; + + 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<WKAccessibilityWebPageObject> m_mockAccessibilityElement; + + WebCore::KeyboardEvent* m_keyboardEventBeingInterpreted; + +#elif PLATFORM(WIN) + // Our view's window (in the UI process). + HWND m_nativeWindow; + + RefPtr<WebCore::Node> m_gestureTargetNode; +#endif + + RunLoop::Timer<WebPage> m_setCanStartMediaTimer; + + HashMap<uint64_t, RefPtr<WebUndoStep> > m_undoStepMap; + + WebCore::IntSize m_windowResizerSize; + + InjectedBundlePageContextMenuClient m_contextMenuClient; + InjectedBundlePageEditorClient m_editorClient; + InjectedBundlePageFormClient m_formClient; + InjectedBundlePageLoaderClient m_loaderClient; + InjectedBundlePagePolicyClient m_policyClient; + InjectedBundlePageResourceLoadClient m_resourceLoadClient; + InjectedBundlePageUIClient m_uiClient; +#if ENABLE(FULLSCREEN_API) + InjectedBundlePageFullScreenClient m_fullScreenClient; +#endif + +#if USE(TILED_BACKING_STORE) + WebCore::IntSize m_resizesToContentsLayoutSize; + WebCore::IntSize m_viewportSize; +#endif + + FindController m_findController; + RefPtr<PageOverlay> m_pageOverlay; + + RefPtr<WebPage> m_underlayPage; + +#if ENABLE(INSPECTOR) + RefPtr<WebInspector> m_inspector; +#endif +#if ENABLE(FULLSCREEN_API) + RefPtr<WebFullScreenManager> m_fullScreenManager; +#endif + RefPtr<WebPopupMenu> m_activePopupMenu; + RefPtr<WebContextMenu> m_contextMenu; + RefPtr<WebOpenPanelResultListener> m_activeOpenPanelResultListener; + GeolocationPermissionRequestManager m_geolocationPermissionRequestManager; + RefPtr<NotificationPermissionRequestManager> m_notificationPermissionRequestManager; + + OwnPtr<WebCore::PrintContext> m_printContext; + + SandboxExtensionTracker m_sandboxExtensionTracker; + uint64_t m_pageID; + + RefPtr<SandboxExtension> m_pendingDropSandboxExtension; + + bool m_canRunBeforeUnloadConfirmPanel; + + bool m_canRunModal; + bool m_isRunningModal; + + bool m_cachedMainFrameIsPinnedToLeftSide; + bool m_cachedMainFrameIsPinnedToRightSide; + + unsigned m_cachedPageCount; + + bool m_isShowingContextMenu; + +#if PLATFORM(WIN) + bool m_gestureReachedScrollingLimit; +#endif +#if PLATFORM(QT) + HashMap<String, QtNetworkReply*> m_applicationSchemeReplies; +#endif +}; + +} // 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 000000000..5a3bb450e --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in @@ -0,0 +1,248 @@ +# 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 -> WebPage { + SetActive(bool active) + SetFocused(bool focused) + SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event) + SetIsInWindow(bool isInWindow) + + SetDrawsBackground(bool drawsBackground) + SetDrawsTransparentBackground(bool drawsTransparentBackground) + + ViewWillStartLiveResize() + ViewWillEndLiveResize() + + KeyEvent(WebKit::WebKeyboardEvent event) + KeyEventSyncForTesting(WebKit::WebKeyboardEvent event) -> (bool handled) + MouseEvent(WebKit::WebMouseEvent event) + MouseEventSyncForTesting(WebKit::WebMouseEvent event) -> (bool handled) + WheelEventSyncForTesting(WebKit::WebWheelEvent event) -> (bool handled) +#if ENABLE(TOUCH_EVENTS) + TouchEvent(WebKit::WebTouchEvent event) + TouchEventSyncForTesting(WebKit::WebTouchEvent event) -> (bool handled) +#endif + + ContextMenuHidden() + + ScrollBy(uint32_t scrollDirection, uint32_t scrollGranularity) + CenterSelectionInVisibleArea() + + GoBack(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + GoForward(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + GoToBackForwardItem(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + TryRestoreScrollPosition() + 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) + LinkClicked(WTF::String url, WebKit::WebMouseEvent event) + Reload(bool reloadFromOrigin) + StopLoading() + +#if PLATFORM(QT) + ApplicationSchemeReply(WebKit::QtNetworkReplyData reply) + RegisterApplicationScheme(WTF::String scheme) +#endif + + StopLoadingFrame(uint64_t frameID) + + RestoreSession(WebKit::SessionState state) + RestoreSessionAndNavigateToCurrentItem(WebKit::SessionState state, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + + DidRemoveBackForwardItem(uint64_t backForwardItemID) + + DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID) + + ClearSelection() + + # Callbacks. + GetContentsAsString(uint64_t callbackID) + GetMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID) + GetResourceDataFromFrame(uint64_t frameID, WTF::String resourceURL, 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) + ForceRepaint(uint64_t callbackID) + +#if PLATFORM(MAC) + # Dictionary support. + PerformDictionaryLookupAtLocation(WebCore::FloatPoint point) +#endif + + PreferencesDidChange(WebKit::WebPreferencesStore store) + + SetUserAgent(WTF::String userAgent) + SetCustomTextEncodingName(WTF::String encodingName) + +#if USE(TILED_BACKING_STORE) + SetFixedVisibleContentRect(WebCore::IntRect rect) + SetViewportSize(WebCore::IntSize size) +#endif + + Close() + TryClose() + + ValidateCommand(WTF::String name, uint64_t callbackID) + 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) + WindowScreenDidChange(uint64_t displayID) + + ScalePage(double scale, WebCore::IntPoint origin) + + SetUseFixedLayout(bool fixed) + SetFixedLayoutSize(WebCore::IntSize size) + + SetPaginationMode(uint32_t mode); + SetPageLength(double pageLength); + SetGapBetweenPages(double gap); + + # Find. + FindString(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) + HideFindUI() + CountStringMatches(WTF::String string, uint32_t findOptions, unsigned maxMatchCount) + + # Drag and drop. +#if PLATFORM(WIN) + PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, HashMap<UINT,Vector<String>> dataMap, uint32_t flags) +#endif +#if PLATFORM(QT) || PLATFORM(GTK) + PerformDragControllerAction(uint64_t action, WebCore::DragData dragData) +#endif +#if !PLATFORM(WIN) && !PLATFORM(QT) && !PLATFORM(GTK) + PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags, WebKit::SandboxExtension::Handle sandboxExtensionHandle) +#endif + DragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation) + + # Popup menu. + DidChangeSelectedIndexForActivePopupMenu(int32_t newIndex); + SetTextForActivePopupMenu(int32_t index); +#if PLATFORM(GTK) + FailedToShowPopupMenu(); +#endif + + # Context menu. + DidSelectItemFromActiveContextMenu(WebKit::WebContextMenuItemData menuItem); + + # Open panel. + DidChooseFilesForOpenPanel(Vector<WTF::String> fileURLs) + DidCancelForOpenPanel() +#if ENABLE(WEB_PROCESS_SANDBOX) + ExtendSandboxForFileFromOpenPanel(WebKit::SandboxExtension::Handle sandboxExtensionHandle) +#endif + + # Spelling and grammar. + AdvanceToNextMisspelling(bool startBeforeSelection) + ChangeSpellingToWord(WTF::String word) +#if PLATFORM(MAC) + UppercaseWord(); + LowercaseWord(); + CapitalizeWord(); + + SetSmartInsertDeleteEnabled(bool isSmartInsertDeleteEnabled); +#endif + + # Geolocation + DidReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) + + # Notification + DidReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed) + + SetWindowResizerSize(WebCore::IntSize intersectsView) + + # Printing. + BeginPrinting(uint64_t frameID, WebKit::PrintInfo printInfo) + EndPrinting(); + ComputePagesForPrinting(uint64_t frameID, WebKit::PrintInfo printInfo, uint64_t callbackID) +#if PLATFORM(MAC) || PLATFORM(WIN) + DrawRectToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, WebCore::IntRect rect, uint64_t callbackID) + DrawPagesToPDF(uint64_t frameID, WebKit::PrintInfo printInfo, uint32_t first, uint32_t count, uint64_t callbackID) +#endif + + SetMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled) + + // 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) + + SetCanRunBeforeUnloadConfirmPanel(bool canRunBeforeUnloadConfirmPanel) + SetCanRunModal(bool canRunModal) + +#if PLATFORM(QT) + SetComposition(WTF::String text, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) + ConfirmComposition(WTF::String text, int64_t selectionStart, int64_t selectionLength) + CancelComposition() +#endif + +#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) + RegisterUIProcessAccessibilityTokens(CoreIPC::DataReference elemenToken, CoreIPC::DataReference windowToken) + WriteSelectionToPasteboard(WTF::String pasteboardName, WTF::Vector<WTF::String> pasteboardTypes) -> (bool result) + ReadSelectionFromPasteboard(WTF::String pasteboardName) -> (bool result) + + # Text input. + SetComposition(WTF::String text, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (WebKit::EditorState newState) + ConfirmComposition() -> (WebKit::EditorState newState) + CancelComposition() -> (WebKit::EditorState newState) + InsertText(WTF::String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (bool handled, WebKit::EditorState newState) + GetMarkedRange() -> (uint64_t location, uint64_t length) + GetSelectedRange() -> (uint64_t location, uint64_t length) + GetAttributedSubstringFromRange(uint64_t location, uint64_t length) -> (WebKit::AttributedString result) + CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result) + FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect) + ExecuteKeypressCommands(Vector<WebCore::KeypressCommand> savedCommands) -> (bool handled, WebKit::EditorState newState) + ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result) + AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -> (bool result) +#endif +#if PLATFORM(WIN) + // FIXME: Unify with Mac counterparts. + 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) + + GestureWillBegin(WebCore::IntPoint point) -> (bool canBeginPanning) + GestureDidScroll(WebCore::IntSize size) + GestureDidEnd() +#endif +#if PLATFORM(QT) + FindZoomableAreaForPoint(WebCore::IntPoint point) +#endif + +#if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD) + HandleCorrectionPanelResult(String result) +#endif +} diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.cpp new file mode 100644 index 000000000..3bd20c8a6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.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 "config.h" +#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 000000000..91e6c5cfd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.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 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; } + bool isVisibleToHistoryClient() const { return m_data.visibleToHistoryClient; } + +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/WebUndoStep.cpp b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.cpp new file mode 100644 index 000000000..7b41c5aa6 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.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 "config.h" +#include "WebUndoStep.h" + +namespace WebKit { + +static uint64_t generateUndoStep() +{ + static uint64_t uniqueEntryID = 1; + return uniqueEntryID++; +} + +PassRefPtr<WebUndoStep> WebUndoStep::create(PassRefPtr<WebCore::UndoStep> step) +{ + return adoptRef(new WebUndoStep(step, generateUndoStep())); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.h new file mode 100644 index 000000000..745377a3c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/WebUndoStep.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 WebUndoStep_h +#define WebUndoStep_h + +#include <WebCore/UndoStep.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebKit { + +class WebUndoStep : public RefCounted<WebUndoStep> { +public: + static PassRefPtr<WebUndoStep> create(PassRefPtr<WebCore::UndoStep>); + + WebCore::UndoStep* step() const { return m_step.get(); } + uint64_t stepID() const { return m_stepID; } + +private: + WebUndoStep(PassRefPtr<WebCore::UndoStep> step, uint64_t stepID) + : m_step(step) + , m_stepID(stepID) + { + } + + RefPtr<WebCore::UndoStep> m_step; + uint64_t m_stepID; +}; + +} // namespace WebKit + +#endif // WebEditCommand_h diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp new file mode 100644 index 000000000..8b135fd06 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp @@ -0,0 +1,278 @@ +/* + * 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 "config.h" +#include "LayerTreeHostCA.h" + +#include "DrawingAreaImpl.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayerCA.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformCALayer.h> +#include <WebCore/Settings.h> + +using namespace WebCore; + +namespace WebKit { + +LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage) + : LayerTreeHost(webPage) + , m_layerFlushSchedulingEnabled(true) + , m_isValid(true) + , m_notifyAfterScheduledLayerFlush(false) +{ +} + +void LayerTreeHostCA::initialize() +{ + // Create a root layer. + m_rootLayer = GraphicsLayer::create(this); +#ifndef NDEBUG + m_rootLayer->setName("LayerTreeHost root layer"); +#endif + m_rootLayer->setDrawsContent(false); + m_rootLayer->setSize(m_webPage->size()); + static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true); + + m_nonCompositedContentLayer = GraphicsLayer::create(this); + static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false); +#ifndef NDEBUG + m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); +#endif + m_nonCompositedContentLayer->setDrawsContent(true); + m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); + m_nonCompositedContentLayer->setSize(m_webPage->size()); + if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled()) + m_nonCompositedContentLayer->setAcceleratesDrawing(true); + + m_rootLayer->addChild(m_nonCompositedContentLayer.get()); + + if (m_webPage->hasPageOverlay()) + createPageOverlayLayer(); + + platformInitialize(m_layerTreeContext); + + setLayerFlushSchedulingEnabled(!m_webPage->drawingArea() || !m_webPage->drawingArea()->layerTreeStateIsFrozen()); + scheduleLayerFlush(); +} + +LayerTreeHostCA::~LayerTreeHostCA() +{ + ASSERT(!m_isValid); + ASSERT(!m_rootLayer); +} + +const LayerTreeContext& LayerTreeHostCA::layerTreeContext() +{ + return m_layerTreeContext; +} + +void LayerTreeHostCA::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush) +{ + m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush; +} + +void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer) +{ + m_nonCompositedContentLayer->removeAllChildren(); + + // Add the accelerated layer tree hierarchy. + if (graphicsLayer) + m_nonCompositedContentLayer->addChild(graphicsLayer); +} + +void LayerTreeHostCA::invalidate() +{ + ASSERT(m_isValid); + m_rootLayer = nullptr; + m_isValid = false; +} + +void LayerTreeHostCA::setNonCompositedContentsNeedDisplay(const IntRect& rect) +{ + m_nonCompositedContentLayer->setNeedsDisplayInRect(rect); + if (m_pageOverlayLayer) + m_pageOverlayLayer->setNeedsDisplayInRect(rect); + + scheduleLayerFlush(); +} + +void LayerTreeHostCA::scrollNonCompositedContents(const IntRect& scrollRect, const IntSize& scrollOffset) +{ + setNonCompositedContentsNeedDisplay(scrollRect); +} + +void LayerTreeHostCA::sizeDidChange(const IntSize& newSize) +{ + m_rootLayer->setSize(newSize); + + // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed + // for those newly exposed areas. + FloatSize oldSize = m_nonCompositedContentLayer->size(); + m_nonCompositedContentLayer->setSize(newSize); + + if (newSize.width() > oldSize.width()) { + float height = std::min(static_cast<float>(newSize.height()), oldSize.height()); + m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height)); + } + + if (newSize.height() > oldSize.height()) + m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height())); + + if (m_pageOverlayLayer) + m_pageOverlayLayer->setSize(newSize); + + scheduleLayerFlush(); + flushPendingLayerChanges(); +} + +void LayerTreeHostCA::deviceScaleFactorDidChange() +{ + // Other layers learn of the scale factor change via WebPage::setDeviceScaleFactor. + m_nonCompositedContentLayer->deviceOrPageScaleFactorChanged(); +} + +void LayerTreeHostCA::forceRepaint() +{ + scheduleLayerFlush(); + flushPendingLayerChanges(); +} + +void LayerTreeHostCA::didInstallPageOverlay() +{ + createPageOverlayLayer(); + scheduleLayerFlush(); +} + +void LayerTreeHostCA::didUninstallPageOverlay() +{ + destroyPageOverlayLayer(); + scheduleLayerFlush(); +} + +void LayerTreeHostCA::setPageOverlayNeedsDisplay(const IntRect& rect) +{ + ASSERT(m_pageOverlayLayer); + m_pageOverlayLayer->setNeedsDisplayInRect(rect); + scheduleLayerFlush(); +} + +void LayerTreeHostCA::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) +{ +} + +void LayerTreeHostCA::notifySyncRequired(const WebCore::GraphicsLayer*) +{ +} + +void LayerTreeHostCA::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& graphicsContext, GraphicsLayerPaintingPhase, const IntRect& clipRect) +{ + if (graphicsLayer == m_nonCompositedContentLayer) { + m_webPage->drawRect(graphicsContext, clipRect); + return; + } + + if (graphicsLayer == m_pageOverlayLayer) { + m_webPage->drawPageOverlay(graphicsContext, clipRect); + return; + } +} + +bool LayerTreeHostCA::showDebugBorders() const +{ + return m_webPage->corePage()->settings()->showDebugBorders(); +} + +bool LayerTreeHostCA::showRepaintCounter() const +{ + return m_webPage->corePage()->settings()->showRepaintCounter(); +} + +float LayerTreeHostCA::deviceScaleFactor() const +{ + return m_webPage->corePage()->deviceScaleFactor(); +} + +void LayerTreeHostCA::performScheduledLayerFlush() +{ + { + RefPtr<LayerTreeHostCA> protect(this); + m_webPage->layoutIfNeeded(); + + if (!m_isValid) + return; + } + + if (!flushPendingLayerChanges()) + return; + + didPerformScheduledLayerFlush(); +} + +void LayerTreeHostCA::didPerformScheduledLayerFlush() +{ + if (m_notifyAfterScheduledLayerFlush) { + // Let the drawing area know that we've done a flush of the layer changes. + static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers(); + m_notifyAfterScheduledLayerFlush = false; + } +} + +bool LayerTreeHostCA::flushPendingLayerChanges() +{ + m_rootLayer->syncCompositingStateForThisLayerOnly(); + m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly(); + if (m_pageOverlayLayer) + m_pageOverlayLayer->syncCompositingStateForThisLayerOnly(); + + return m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); +} + +void LayerTreeHostCA::createPageOverlayLayer() +{ + ASSERT(!m_pageOverlayLayer); + + m_pageOverlayLayer = GraphicsLayer::create(this); +#ifndef NDEBUG + m_pageOverlayLayer->setName("LayerTreeHost page overlay content"); +#endif + + m_pageOverlayLayer->setDrawsContent(true); + m_pageOverlayLayer->setSize(m_webPage->size()); + + m_rootLayer->addChild(m_pageOverlayLayer.get()); +} + +void LayerTreeHostCA::destroyPageOverlayLayer() +{ + ASSERT(m_pageOverlayLayer); + m_pageOverlayLayer->removeFromParent(); + m_pageOverlayLayer = nullptr; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h new file mode 100644 index 000000000..0566e9733 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h @@ -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. + */ + +#ifndef LayerTreeHostCA_h +#define LayerTreeHostCA_h + +#include "LayerTreeContext.h" +#include "LayerTreeHost.h" +#include <WebCore/GraphicsLayerClient.h> +#include <wtf/OwnPtr.h> + +namespace WebKit { + +class LayerTreeHostCA : public LayerTreeHost, WebCore::GraphicsLayerClient { +public: + virtual ~LayerTreeHostCA(); + +protected: + explicit LayerTreeHostCA(WebPage*); + + WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); } + + void initialize(); + void performScheduledLayerFlush(); + + // LayerTreeHost. + virtual void invalidate(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + virtual void deviceScaleFactorDidChange(); + virtual void forceRepaint(); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + + // LayerTreeHostCA + virtual void didPerformScheduledLayerFlush(); + + bool m_layerFlushSchedulingEnabled; + +private: + // LayerTreeHost. + virtual const LayerTreeContext& layerTreeContext(); + virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool); + + virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&); + virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); + + virtual void didInstallPageOverlay(); + virtual void didUninstallPageOverlay(); + virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&); + + // GraphicsLayerClient + virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time); + virtual void notifySyncRequired(const WebCore::GraphicsLayer*); + virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect); + virtual bool showDebugBorders() const; + virtual bool showRepaintCounter() const; + virtual float deviceScaleFactor() const; + virtual void didCommitChangesForLayer(const WebCore::GraphicsLayer*) const { } + + // LayerTreeHostCA + virtual void platformInitialize(LayerTreeContext&) = 0; + + bool flushPendingLayerChanges(); + + void createPageOverlayLayer(); + void destroyPageOverlayLayer(); + + // The context for this layer tree. + LayerTreeContext m_layerTreeContext; + + // Whether the layer tree host is valid or not. + bool m_isValid; + + // Whether we should let the drawing area know the next time we've flushed + // layer tree changes. + bool m_notifyAfterScheduledLayerFlush; + + // The root layer. + OwnPtr<WebCore::GraphicsLayer> m_rootLayer; + + // The layer which contains all non-composited content. + OwnPtr<WebCore::GraphicsLayer> m_nonCompositedContentLayer; + + // The page overlay layer. Will be null if there's no page overlay. + OwnPtr<WebCore::GraphicsLayer> m_pageOverlayLayer; +}; + +} // namespace WebKit + +#endif // LayerTreeHostCA_h diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h new file mode 100644 index 000000000..06759e25d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h @@ -0,0 +1,68 @@ +/* + * 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 LayerTreeHostCAMac_h +#define LayerTreeHostCAMac_h + +#include "LayerTreeHostCA.h" +#include <WebCore/LayerFlushScheduler.h> +#include <WebCore/LayerFlushSchedulerClient.h> +#include <wtf/RetainPtr.h> + +typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef; + +namespace WebKit { + +class LayerTreeHostCAMac : public LayerTreeHostCA, public WebCore::LayerFlushSchedulerClient { +public: + static PassRefPtr<LayerTreeHostCAMac> create(WebPage*); + virtual ~LayerTreeHostCAMac(); + +private: + explicit LayerTreeHostCAMac(WebPage*); + + // LayerTreeHost. + virtual void scheduleLayerFlush(); + virtual void setLayerFlushSchedulingEnabled(bool); + virtual void invalidate(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + virtual void forceRepaint(); + virtual void pauseRendering(); + virtual void resumeRendering(); + + // LayerTreeHostCA + virtual void platformInitialize(LayerTreeContext&); + virtual void didPerformScheduledLayerFlush(); + + // LayerFlushSchedulerClient + virtual bool flushLayers(); + + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; + WebCore::LayerFlushScheduler m_layerFlushScheduler; +}; + +} // namespace WebKit + +#endif // LayerTreeHostCAMac_h diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm new file mode 100644 index 000000000..5ff8ad13b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm @@ -0,0 +1,136 @@ +/* + * 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 "config.h" +#import "LayerTreeHostCAMac.h" + +#import "WebProcess.h" +#import <QuartzCore/CATransaction.h> +#import <WebCore/GraphicsLayer.h> +#import <WebKitSystemInterface.h> + +using namespace WebCore; + +@interface CATransaction (Details) ++ (void)synchronize; +@end + +namespace WebKit { + +PassRefPtr<LayerTreeHostCAMac> LayerTreeHostCAMac::create(WebPage* webPage) +{ + RefPtr<LayerTreeHostCAMac> host = adoptRef(new LayerTreeHostCAMac(webPage)); + host->initialize(); + return host.release(); +} + +LayerTreeHostCAMac::LayerTreeHostCAMac(WebPage* webPage) + : LayerTreeHostCA(webPage) + , m_layerFlushScheduler(this) +{ +} + +LayerTreeHostCAMac::~LayerTreeHostCAMac() +{ + ASSERT(!m_remoteLayerClient); +} + +void LayerTreeHostCAMac::platformInitialize(LayerTreeContext& layerTreeContext) +{ + mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); + m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort); + + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), rootLayer()->platformLayer()); + + layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); +} + +void LayerTreeHostCAMac::scheduleLayerFlush() +{ + m_layerFlushScheduler.schedule(); +} + +void LayerTreeHostCAMac::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled) +{ + if (layerFlushingEnabled) + m_layerFlushScheduler.resume(); + else + m_layerFlushScheduler.suspend(); +} + +void LayerTreeHostCAMac::invalidate() +{ + m_layerFlushScheduler.invalidate(); + + WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get()); + m_remoteLayerClient = nullptr; + + LayerTreeHostCA::invalidate(); +} + +void LayerTreeHostCAMac::sizeDidChange(const IntSize& newSize) +{ + LayerTreeHostCA::sizeDidChange(newSize); + [CATransaction flush]; + [CATransaction synchronize]; +} + +void LayerTreeHostCAMac::forceRepaint() +{ + LayerTreeHostCA::forceRepaint(); + [CATransaction flush]; + [CATransaction synchronize]; +} + +void LayerTreeHostCAMac::pauseRendering() +{ + CALayer* root = rootLayer()->platformLayer(); + [root setValue:(id)kCFBooleanTrue forKey:@"NSCAViewRenderPaused"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidPauseNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]]; +} + +void LayerTreeHostCAMac::resumeRendering() +{ + CALayer* root = rootLayer()->platformLayer(); + [root setValue:(id)kCFBooleanFalse forKey:@"NSCAViewRenderPaused"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidResumeNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]]; +} + +bool LayerTreeHostCAMac::flushLayers() +{ + // This gets called outside of the normal event loop so wrap in an autorelease pool + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + performScheduledLayerFlush(); + [pool drain]; + + return true; +} + +void LayerTreeHostCAMac::didPerformScheduledLayerFlush() +{ + LayerTreeHostCA::didPerformScheduledLayerFlush(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp new file mode 100644 index 000000000..ef3c16a11 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp @@ -0,0 +1,263 @@ +/* + * 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 "config.h" +#include "LayerTreeHostCAWin.h" + +#if HAVE(WKQCA) + +#include "DrawingAreaImpl.h" +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include "WKCACFViewWindow.h" +#include "WebPage.h" +#include <WebCore/GraphicsLayerCA.h> +#include <WebCore/LayerChangesFlusher.h> +#include <WebCore/PlatformCALayer.h> +#include <WebCore/WebCoreInstanceHandle.h> +#include <WebKitQuartzCoreAdditions/WKCACFImage.h> +#include <WebKitQuartzCoreAdditions/WKCACFView.h> +#include <wtf/CurrentTime.h> +#include <wtf/MainThread.h> + +#ifdef DEBUG_ALL +#pragma comment(lib, "WebKitQuartzCoreAdditions_debug") +#else +#pragma comment(lib, "WebKitQuartzCoreAdditions") +#endif + +using namespace WebCore; + +namespace WebKit { + +bool LayerTreeHostCAWin::supportsAcceleratedCompositing() +{ + static bool initialized; + static bool supportsAcceleratedCompositing; + if (initialized) + return supportsAcceleratedCompositing; + initialized = true; + + RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow)); + WKCACFViewWindow dummyWindow(view.get(), 0, 0); + CGRect fakeBounds = CGRectMake(0, 0, 10, 10); + WKCACFViewUpdate(view.get(), dummyWindow.window(), &fakeBounds); + + supportsAcceleratedCompositing = WKCACFViewCanDraw(view.get()); + + WKCACFViewUpdate(view.get(), 0, 0); + + return supportsAcceleratedCompositing; +} + +PassRefPtr<LayerTreeHostCAWin> LayerTreeHostCAWin::create(WebPage* webPage) +{ + RefPtr<LayerTreeHostCAWin> host = adoptRef(new LayerTreeHostCAWin(webPage)); + host->initialize(); + return host.release(); +} + +LayerTreeHostCAWin::LayerTreeHostCAWin(WebPage* webPage) + : LayerTreeHostCA(webPage) + , m_isFlushingLayerChanges(false) +{ +} + +LayerTreeHostCAWin::~LayerTreeHostCAWin() +{ +} + +void LayerTreeHostCAWin::platformInitialize(LayerTreeContext& context) +{ + m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationWindow)); + WKCACFViewSetContextUserData(m_view.get(), static_cast<AbstractCACFLayerTreeHost*>(this)); + WKCACFViewSetLayer(m_view.get(), rootLayer()->platformLayer()); + WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this); + + // Passing WS_DISABLED makes the window invisible to mouse events, which lets WKView's normal + // event handling mechanism work even when this window is obscuring the entire WKView HWND. + // Note that m_webPage->nativeWindow() is owned by the UI process, so this creates a cross- + // process window hierarchy (and thus implicitly attaches the input queues of the UI and web + // processes' main threads). + m_window = adoptPtr(new WKCACFViewWindow(m_view.get(), m_webPage->nativeWindow(), WS_DISABLED)); + + CGRect bounds = m_webPage->bounds(); + WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds); + + context.window = m_window->window(); +} + +void LayerTreeHostCAWin::invalidate() +{ + LayerChangesFlusher::shared().cancelPendingFlush(this); + + WKCACFViewSetContextUserData(m_view.get(), 0); + WKCACFViewSetLayer(m_view.get(), 0); + WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0); + + // The UI process will destroy m_window's HWND when it gets the message to switch out of + // accelerated compositing mode. We don't want to destroy the HWND before then or we will get a + // flash of white before the UI process has a chance to display the non-composited content. + // Since the HWND needs to outlive us, we leak m_window here and tell it to clean itself up + // when its HWND is destroyed. + WKCACFViewWindow* window = m_window.leakPtr(); + window->setDeletesSelfWhenWindowDestroyed(true); + + LayerTreeHostCA::invalidate(); +} + +void LayerTreeHostCAWin::scheduleLayerFlush() +{ + if (!m_layerFlushSchedulingEnabled) + return; + + LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this); +} + +void LayerTreeHostCAWin::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled) +{ + if (m_layerFlushSchedulingEnabled == layerFlushingEnabled) + return; + + m_layerFlushSchedulingEnabled = layerFlushingEnabled; + + if (m_layerFlushSchedulingEnabled) { + scheduleLayerFlush(); + return; + } + + LayerChangesFlusher::shared().cancelPendingFlush(this); +} + +void LayerTreeHostCAWin::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry) +{ + m_geometriesUpdater.addPendingUpdate(geometry); +} + +void LayerTreeHostCAWin::sizeDidChange(const IntSize& newSize) +{ + LayerTreeHostCA::sizeDidChange(newSize); + CGRect bounds = CGRectMake(0, 0, newSize.width(), newSize.height()); + WKCACFViewUpdate(m_view.get(), m_window->window(), &bounds); + WKCACFViewFlushContext(m_view.get()); +} + +void LayerTreeHostCAWin::forceRepaint() +{ + LayerTreeHostCA::forceRepaint(); + WKCACFViewFlushContext(m_view.get()); +} + +void LayerTreeHostCAWin::contextDidChangeCallback(WKCACFViewRef view, void* info) +{ + // This should only be called on a background thread when no changes have actually + // been committed to the context, eg. when a video frame has been added to an image + // queue, so return without triggering animations etc. + if (!isMainThread()) + return; + + LayerTreeHostCAWin* host = static_cast<LayerTreeHostCAWin*>(info); + ASSERT_ARG(view, view == host->m_view); + host->contextDidChange(); +} + +void LayerTreeHostCAWin::contextDidChange() +{ + // Send currentTime to the pending animations. This function is called by CACF in a callback + // which occurs after the drawInContext calls. So currentTime is very close to the time + // the animations actually start + double currentTime = WTF::currentTime(); + + HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end(); + for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it) + (*it)->animationStarted(currentTime); + + m_pendingAnimatedLayers.clear(); + + // Update child window geometries now so that they stay mostly in sync with the accelerated content. + // FIXME: We should really be doing this when the changes we just flushed appear on screen. <http://webkit.org/b/61867> + // We also bring the child windows (i.e., plugins) to the top of the z-order to ensure they are above m_window. + // FIXME: We could do this just once per window when it is first shown. Maybe that would be more efficient? + m_geometriesUpdater.updateGeometries(BringToTop); +} + +PlatformCALayer* LayerTreeHostCAWin::rootLayer() const +{ + return static_cast<GraphicsLayerCA*>(LayerTreeHostCA::rootLayer())->platformCALayer(); +} + +void LayerTreeHostCAWin::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer) +{ + m_pendingAnimatedLayers.add(layer); +} + +void LayerTreeHostCAWin::layerTreeDidChange() +{ + if (m_isFlushingLayerChanges) { + // The layer tree is changing as a result of flushing GraphicsLayer changes to their + // underlying PlatformCALayers. We'll flush those changes to the context as part of that + // process, so there's no need to schedule another flush here. + return; + } + + // The layer tree is changing as a result of someone modifying a PlatformCALayer that doesn't + // have a corresponding GraphicsLayer. Schedule a flush since we won't schedule one through the + // normal GraphicsLayer mechanisms. + LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this); +} + +void LayerTreeHostCAWin::flushPendingLayerChangesNow() +{ + RefPtr<LayerTreeHostCA> protector(this); + + m_isFlushingLayerChanges = true; + + // Flush changes stored up in GraphicsLayers to their underlying PlatformCALayers, if + // requested. + performScheduledLayerFlush(); + + // Flush changes stored up in PlatformCALayers to the context so they will be rendered. + WKCACFViewFlushContext(m_view.get()); + + m_isFlushingLayerChanges = false; +} + +void LayerTreeHostCAWin::setRootCompositingLayer(GraphicsLayer* graphicsLayer) +{ + // Don't flush any changes when we don't have a root layer. This will prevent flashes of white + // when switching out of compositing mode. + setLayerFlushSchedulingEnabled(graphicsLayer); + + // Resubmit all existing animations. CACF does not remember running animations + // When the layer tree is removed and then added back to the hierarchy + if (graphicsLayer) + static_cast<GraphicsLayerCA*>(graphicsLayer)->platformCALayer()->ensureAnimationsSubmitted(); + + LayerTreeHostCA::setRootCompositingLayer(graphicsLayer); +} + +} // namespace WebKit + +#endif // HAVE(WKQCA) diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h new file mode 100644 index 000000000..d9d59678a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h @@ -0,0 +1,87 @@ +/* + * 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 LayerTreeHostCAWin_h +#define LayerTreeHostCAWin_h + +#include "HeaderDetection.h" + +#if HAVE(WKQCA) + +#include "CoalescedWindowGeometriesUpdater.h" +#include "LayerTreeHostCA.h" +#include <WebCore/AbstractCACFLayerTreeHost.h> +#include <wtf/HashSet.h> +#include <wtf/RetainPtr.h> + +typedef struct _WKCACFView* WKCACFViewRef; + +namespace WebKit { + +class WKCACFViewWindow; + +class LayerTreeHostCAWin : public LayerTreeHostCA, private WebCore::AbstractCACFLayerTreeHost { +public: + static bool supportsAcceleratedCompositing(); + + static PassRefPtr<LayerTreeHostCAWin> create(WebPage*); + virtual ~LayerTreeHostCAWin(); + +private: + explicit LayerTreeHostCAWin(WebPage*); + + static void contextDidChangeCallback(WKCACFViewRef, void* info); + void contextDidChange(); + + // LayerTreeHost + virtual void invalidate(); + virtual void forceRepaint(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + virtual void scheduleLayerFlush(); + virtual void setLayerFlushSchedulingEnabled(bool); + virtual void scheduleChildWindowGeometryUpdate(const WindowGeometry&); + + // LayerTreeHostCA + virtual void platformInitialize(LayerTreeContext&); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + + // AbstractCACFLayerTreeHost + virtual WebCore::PlatformCALayer* rootLayer() const; + virtual void addPendingAnimatedLayer(PassRefPtr<WebCore::PlatformCALayer>); + virtual void layerTreeDidChange(); + virtual void flushPendingLayerChangesNow(); + + OwnPtr<WKCACFViewWindow> m_window; + RetainPtr<WKCACFViewRef> m_view; + HashSet<RefPtr<WebCore::PlatformCALayer> > m_pendingAnimatedLayers; + bool m_isFlushingLayerChanges; + CoalescedWindowGeometriesUpdater m_geometriesUpdater; +}; + +} // namespace WebKit + +#endif // HAVE(WKQCA) + +#endif // LayerTreeHostCAWin_h diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp new file mode 100644 index 000000000..0ce37c449 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.cpp @@ -0,0 +1,164 @@ +/* + * 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 "config.h" +#include "WKCACFViewWindow.h" + +#if HAVE(WKQCA) + +#include <WebCore/WebCoreInstanceHandle.h> +#include <WebKitQuartzCoreAdditions/WKCACFView.h> + +using namespace WebCore; + +namespace WebKit { + +static LPCWSTR windowClassName = L"WKCACFViewWindowClass"; + +WKCACFViewWindow::WKCACFViewWindow(WKCACFViewRef view, HWND parentWindow, DWORD additionalStyles) + : m_window(0) + , m_view(view) + , m_deletesSelfWhenWindowDestroyed(false) +{ + ASSERT_ARG(view, view); + + registerClass(); + + UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | additionalStyles; + if (parentWindow) + style |= WS_CHILD; + else + style |= WS_POPUP; + + m_window = ::CreateWindowExW(0, windowClassName, L"WKCACFViewWindow", style, 0, 0, 0, 0, parentWindow, 0, instanceHandle(), this); + ASSERT_WITH_MESSAGE(m_window, "::CreateWindowExW failed with error %lu", ::GetLastError()); +} + +WKCACFViewWindow::~WKCACFViewWindow() +{ + if (!m_window) + return; + + ASSERT(!m_deletesSelfWhenWindowDestroyed); + ::DestroyWindow(m_window); +} + +LRESULT WKCACFViewWindow::onCustomDestroy(WPARAM, LPARAM) +{ + ::DestroyWindow(m_window); + return 0; +} + +LRESULT WKCACFViewWindow::onDestroy(WPARAM, LPARAM) +{ + WKCACFViewUpdate(m_view.get(), 0, 0); + return 0; +} + +LRESULT WKCACFViewWindow::onEraseBackground(WPARAM, LPARAM) +{ + // Tell Windows not to erase us. + return 1; +} + +LRESULT WKCACFViewWindow::onNCDestroy(WPARAM, LPARAM) +{ + m_window = 0; + + if (!m_deletesSelfWhenWindowDestroyed) + return 0; + + delete this; + return 0; +} + +LRESULT WKCACFViewWindow::onPaint(WPARAM, LPARAM) +{ + WKCACFViewDraw(m_view.get()); + ::ValidateRect(m_window, 0); + return 0; +} + +LRESULT WKCACFViewWindow::onPrintClient(WPARAM wParam, LPARAM lParam) +{ + if (!(lParam & PRF_CLIENT)) + return 0; + + WKCACFViewDrawIntoDC(m_view.get(), reinterpret_cast<HDC>(wParam)); + return 0; +} + +void WKCACFViewWindow::registerClass() +{ + static bool didRegister; + if (didRegister) + return; + didRegister = true; + + WNDCLASSW wndClass = {0}; + wndClass.lpfnWndProc = staticWndProc; + wndClass.hInstance = instanceHandle(); + wndClass.lpszClassName = windowClassName; + + ::RegisterClassW(&wndClass); +} + +LRESULT WKCACFViewWindow::staticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WKCACFViewWindow* window = reinterpret_cast<WKCACFViewWindow*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); + if (!window) { + if (message != WM_CREATE) + return ::DefWindowProcW(hWnd, message, wParam, lParam); + CREATESTRUCT* createStruct = reinterpret_cast<CREATESTRUCT*>(lParam); + window = static_cast<WKCACFViewWindow*>(createStruct->lpCreateParams); + ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(window)); + } + + return window->wndProc(message, wParam, lParam); +} + +LRESULT WKCACFViewWindow::wndProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case customDestroyMessage: + return onCustomDestroy(wParam, lParam); + case WM_DESTROY: + return onDestroy(wParam, lParam); + case WM_ERASEBKGND: + return onEraseBackground(wParam, lParam); + case WM_NCDESTROY: + return onNCDestroy(wParam, lParam); + case WM_PAINT: + return onPaint(wParam, lParam); + case WM_PRINTCLIENT: + return onPrintClient(wParam, lParam); + default: + return ::DefWindowProcW(m_window, message, wParam, lParam); + } +} + +} // namespace WebKit + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h new file mode 100644 index 000000000..391146a4c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/win/WKCACFViewWindow.h @@ -0,0 +1,74 @@ +/* + * 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 WKCACFViewWindow_h +#define WKCACFViewWindow_h + +#include "HeaderDetection.h" + +#if HAVE(WKQCA) + +#include <wtf/Noncopyable.h> +#include <wtf/RetainPtr.h> + +typedef struct _WKCACFView* WKCACFViewRef; + +namespace WebKit { + +// FIXME: Move this class down to WebCore. (Maybe it can even replace some of WKCACFViewLayerTreeHost.) +class WKCACFViewWindow { + WTF_MAKE_NONCOPYABLE(WKCACFViewWindow); +public: + // WKCACFViewWindow will destroy its HWND when this message is received. + static const UINT customDestroyMessage = WM_USER + 1; + + WKCACFViewWindow(WKCACFViewRef, HWND parentWindow, DWORD additionalStyles); + ~WKCACFViewWindow(); + + void setDeletesSelfWhenWindowDestroyed(bool deletes) { m_deletesSelfWhenWindowDestroyed = deletes; } + + HWND window() const { return m_window; } + +private: + LRESULT onCustomDestroy(WPARAM, LPARAM); + LRESULT onDestroy(WPARAM, LPARAM); + LRESULT onEraseBackground(WPARAM, LPARAM); + LRESULT onNCDestroy(WPARAM, LPARAM); + LRESULT onPaint(WPARAM, LPARAM); + LRESULT onPrintClient(WPARAM, LPARAM); + static void registerClass(); + static LRESULT CALLBACK staticWndProc(HWND, UINT, WPARAM, LPARAM); + LRESULT wndProc(UINT, WPARAM, LPARAM); + + HWND m_window; + RetainPtr<WKCACFViewRef> m_view; + bool m_deletesSelfWhenWindowDestroyed; +}; + +} // namespace WebKit + +#endif // HAVE(WKQCA) + +#endif // WKCACFViewWindow_h diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp new file mode 100644 index 000000000..755b4268c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/efl/WebInspectorEfl.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <WebCore/NotImplemented.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + notImplemented(); + return String(); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp new file mode 100644 index 000000000..669442014 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/efl/WebPageEfl.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPage.h" + +#include "NotImplemented.h" +#include "WebEvent.h" +#include "WindowsKeyboardCodes.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> + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ + notImplemented(); +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ + notImplemented(); +} + +static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); +} + +bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent) +{ + notImplemented(); + return false; +} + +bool WebPage::platformHasLocalDataForURL(const KURL&) +{ + notImplemented(); + return false; +} + +String WebPage::cachedResponseMIMETypeForURL(const KURL&) +{ + notImplemented(); + return String(); +} + +bool WebPage::platformCanHandleRequest(const ResourceRequest&) +{ + notImplemented(); + return true; +} + +String WebPage::cachedSuggestedFilenameForURL(const KURL&) +{ + notImplemented(); + return String(); +} + +PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&) +{ + notImplemented(); + return 0; +} + +const char* WebPage::interpretKeyEvent(const KeyboardEvent* evt) +{ + notImplemented(); + return 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp new file mode 100644 index 000000000..313ad3fe7 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/gtk/ChunkedUpdateDrawingAreaGtk.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ChunkedUpdateDrawingArea.h" + +#include "RefPtrCairo.h" +#include "UpdateChunk.h" +#include "WebPage.h" + +#include <WebCore/GraphicsContext.h> +#include <WebCore/IntRect.h> + +using namespace WebCore; + +namespace WebKit { + +void ChunkedUpdateDrawingArea::paintIntoUpdateChunk(UpdateChunk* updateChunk) +{ + ASSERT(!updateChunk->isEmpty()); + + RefPtr<cairo_surface_t> image = updateChunk->createImage(); + RefPtr<cairo_t> cr = cairo_create(image.get()); + GraphicsContext gc(cr.get()); + gc.save(); + IntRect rect = updateChunk->rect(); + gc.translate(-rect.x(), -rect.y()); + m_webPage->drawRect(gc, updateChunk->rect()); + gc.restore(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp new file mode 100644 index 000000000..e00e437bd --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp @@ -0,0 +1,45 @@ +/* + * 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 "config.h" +#include "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <WebCore/NotImplemented.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + notImplemented(); + return String(); +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp new file mode 100644 index 000000000..a25e1f7b3 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPage.h" + +#include "NotImplemented.h" +#include "WebEvent.h" +#include "WindowsKeyboardCodes.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> + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ + notImplemented(); +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ + notImplemented(); +} + +static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(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: + scroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollUp : ScrollDown, ScrollByPage); + break; + case VK_LEFT: + scroll(m_page.get(), ScrollLeft, ScrollByLine); + break; + case VK_RIGHT: + scroll(m_page.get(), ScrollRight, ScrollByLine); + break; + case VK_UP: + scroll(m_page.get(), ScrollUp, ScrollByLine); + break; + case VK_DOWN: + scroll(m_page.get(), ScrollDown, ScrollByLine); + break; + case VK_HOME: + scroll(m_page.get(), ScrollUp, ScrollByDocument); + break; + case VK_END: + scroll(m_page.get(), ScrollDown, ScrollByDocument); + break; + case VK_PRIOR: + scroll(m_page.get(), ScrollUp, ScrollByPage); + break; + case VK_NEXT: + scroll(m_page.get(), ScrollDown, ScrollByPage); + break; + default: + return false; + } + + return true; +} + +bool WebPage::platformHasLocalDataForURL(const KURL&) +{ + notImplemented(); + return false; +} + +String WebPage::cachedResponseMIMETypeForURL(const KURL&) +{ + notImplemented(); + return String(); +} + +bool WebPage::platformCanHandleRequest(const ResourceRequest&) +{ + notImplemented(); + return true; +} + +String WebPage::cachedSuggestedFilenameForURL(const KURL&) +{ + notImplemented(); + return String(); +} + +PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&) +{ + notImplemented(); + return 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h new file mode 100644 index 000000000..92620bec2 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h @@ -0,0 +1,70 @@ +/* + * 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 TiledCoreAnimationDrawingArea_h +#define TiledCoreAnimationDrawingArea_h + +#include "DrawingArea.h" +#include <WebCore/LayerFlushScheduler.h> +#include <WebCore/LayerFlushSchedulerClient.h> +#include <wtf/RetainPtr.h> + +OBJC_CLASS CALayer; +OBJC_CLASS WKContentLayer; + +typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef; + +namespace WebKit { + +class TiledCoreAnimationDrawingArea : public DrawingArea, private WebCore::LayerFlushSchedulerClient { +public: + static PassOwnPtr<TiledCoreAnimationDrawingArea> create(WebPage*, const WebPageCreationParameters&); + virtual ~TiledCoreAnimationDrawingArea(); + +private: + TiledCoreAnimationDrawingArea(WebPage*, const WebPageCreationParameters&); + + // DrawingArea + virtual void setNeedsDisplay(const WebCore::IntRect&) OVERRIDE; + virtual void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) OVERRIDE; + + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) OVERRIDE; + virtual void scheduleCompositingLayerSync() OVERRIDE; + + // WebCore::LayerFlushSchedulerClient + virtual bool flushLayers() OVERRIDE; + + // Message handlers. + virtual void updateGeometry(const WebCore::IntSize& viewSize) OVERRIDE; + + WebCore::LayerFlushScheduler m_layerFlushScheduler; + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; + + RetainPtr<CALayer> m_rootLayer; +}; + +} // namespace WebKit + +#endif // TiledCoreAnimationDrawingArea_h diff --git a/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm new file mode 100644 index 000000000..a1da6bde5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm @@ -0,0 +1,152 @@ +/* + * 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 "config.h" +#import "TiledCoreAnimationDrawingArea.h" + +#import "DrawingAreaProxyMessages.h" +#import "EventDispatcher.h" +#import "LayerTreeContext.h" +#import "WebPage.h" +#import "WebProcess.h" +#import <QuartzCore/QuartzCore.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/GraphicsContext.h> +#import <WebCore/Page.h> +#import <WebCore/ScrollingCoordinator.h> +#import <WebCore/Settings.h> +#import <WebKitSystemInterface.h> + +@interface CATransaction (Details) ++ (void)synchronize; +@end + +using namespace WebCore; + +namespace WebKit { + +PassOwnPtr<TiledCoreAnimationDrawingArea> TiledCoreAnimationDrawingArea::create(WebPage* webPage, const WebPageCreationParameters& parameters) +{ + return adoptPtr(new TiledCoreAnimationDrawingArea(webPage, parameters)); +} + +TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea(WebPage* webPage, const WebPageCreationParameters& parameters) + : DrawingArea(DrawingAreaTypeTiledCoreAnimation, webPage) + , m_layerFlushScheduler(this) +{ + Page* page = webPage->corePage(); + + // FIXME: It's weird that we're mucking around with the settings here. + page->settings()->setForceCompositingMode(true); + +#if ENABLE(THREADED_SCROLLING) + page->settings()->setScrollingCoordinatorEnabled(true); + + WebProcess::shared().eventDispatcher().addScrollingCoordinatorForPage(webPage); +#endif + + m_rootLayer = [CALayer layer]; + + CGRect rootLayerFrame = m_webPage->bounds(); + m_rootLayer.get().frame = rootLayerFrame; + m_rootLayer.get().opaque = YES; + m_rootLayer.get().geometryFlipped = YES; + + mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); + m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort); + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer.get()); + + LayerTreeContext layerTreeContext; + layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); + m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(0, layerTreeContext)); +} + +TiledCoreAnimationDrawingArea::~TiledCoreAnimationDrawingArea() +{ +#if ENABLE(THREADED_SCROLLING) + WebProcess::shared().eventDispatcher().removeScrollingCoordinatorForPage(m_webPage); +#endif + + m_layerFlushScheduler.invalidate(); +} + +void TiledCoreAnimationDrawingArea::setNeedsDisplay(const IntRect& rect) +{ +} + +void TiledCoreAnimationDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollOffset) +{ +} + +void TiledCoreAnimationDrawingArea::setRootCompositingLayer(GraphicsLayer* graphicsLayer) +{ + if (!graphicsLayer) { + m_rootLayer.get().sublayers = nil; + return; + } + + m_rootLayer.get().sublayers = [NSArray arrayWithObject:graphicsLayer->platformLayer()]; +} + +void TiledCoreAnimationDrawingArea::scheduleCompositingLayerSync() +{ + m_layerFlushScheduler.schedule(); + // FIXME: Implement +} + +bool TiledCoreAnimationDrawingArea::flushLayers() +{ + // This gets called outside of the normal event loop so wrap in an autorelease pool + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + m_webPage->layoutIfNeeded(); + + bool returnValue = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); + + [pool drain]; + return returnValue; +} + + +void TiledCoreAnimationDrawingArea::updateGeometry(const IntSize& viewSize) +{ + m_webPage->setSize(viewSize); + m_webPage->layoutIfNeeded(); + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + + m_rootLayer.get().frame = CGRectMake(0, 0, viewSize.width(), viewSize.height()); + + [CATransaction commit]; + + [CATransaction flush]; + [CATransaction synchronize]; + + m_webPage->send(Messages::DrawingAreaProxy::DidUpdateGeometry()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.h b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.h new file mode 100644 index 000000000..2772ad0e1 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.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 WKAccessibilityWebPageObject_h +#define WKAccessibilityWebPageObject_h + +namespace WebKit { +class WebPage; +} + +@interface WKAccessibilityWebPageObject : 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 // WKAccessibilityWebPageObject_h diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm new file mode 100644 index 000000000..6ed37ea10 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WKAccessibilityWebPageObject.mm @@ -0,0 +1,194 @@ +/* + * 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 "config.h" +#import "WKAccessibilityWebPageObject.h" + +#import "WebFrame.h" +#import "WebPage.h" +#import <WebCore/AXObjectCache.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/Page.h> +#import <WebCore/ScrollView.h> +#import <WebCore/Scrollbar.h> +#import <WebKitSystemInterface.h> + +using namespace WebCore; +using namespace WebKit; + +@implementation WKAccessibilityWebPageObject + +- (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 +{ + WKUnregisterUniqueIdForElement(self); + [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 nil; +} + +- (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 *)[[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* frameView = m_page ? m_page->mainFrameView() : 0; + if (frameView) { + point.y += frameView->scrollPosition().y(); + point.x += frameView->scrollPosition().x(); + } + + return [[self accessibilityRootObjectWrapper] accessibilityHitTest:point]; +} + +- (id)accessibilityFocusedUIElement +{ + return [[self accessibilityRootObjectWrapper] accessibilityFocusedUIElement]; +} + + +@end diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm new file mode 100644 index 000000000..d64bf9cf5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebInspectorMac.mm @@ -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. + */ + +#import "config.h" +#import "WebInspector.h" + +#import <wtf/text/WTFString.h> + +namespace WebKit { + +static String& globalInspectorLocalizedStringsURL() +{ + DEFINE_STATIC_LOCAL(String, inspectorLocalizedStringsURL, ()); + return inspectorLocalizedStringsURL; +} + +void WebInspector::setLocalizedStringsPath(const String& path) +{ + if (!path.isEmpty()) + globalInspectorLocalizedStringsURL() = [[NSURL fileURLWithPath:path] absoluteString]; + else + globalInspectorLocalizedStringsURL() = String(); +} + +String WebInspector::localizedStringsURL() const +{ + return globalInspectorLocalizedStringsURL(); +} + +} // 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 000000000..bfee90207 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm @@ -0,0 +1,710 @@ +/* + * 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. + */ + +#import "config.h" +#import "WebPage.h" + +#import "AttributedString.h" +#import "DataReference.h" +#import "EditorState.h" +#import "PluginView.h" +#import "WKAccessibilityWebPageObject.h" +#import "WebCoreArgumentCoders.h" +#import "WebEvent.h" +#import "WebEventConversion.h" +#import "WebFrame.h" +#import "WebPageProxyMessages.h" +#import "WebProcess.h" +#import <WebCore/AXObjectCache.h> +#import <WebCore/FocusController.h> +#import <WebCore/Frame.h> +#import <WebCore/FrameView.h> +#import <WebCore/HitTestResult.h> +#import <WebCore/HTMLConverter.h> +#import <WebCore/KeyboardEvent.h> +#import <WebCore/Page.h> +#import <WebCore/PlatformKeyboardEvent.h> +#import <WebCore/ResourceHandle.h> +#import <WebCore/RenderObject.h> +#import <WebCore/RenderStyle.h> +#import <WebCore/ScrollView.h> +#import <WebCore/TextIterator.h> +#import <WebCore/WindowsKeyboardCodes.h> +#import <WebCore/visible_units.h> +#import <WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +static PassRefPtr<Range> convertToRange(Frame*, NSRange); + +void WebPage::platformInitialize() +{ +#if USE(CFNETWORK) + m_page->addSchedulePair(SchedulePair::create([[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopCommonModes)); +#else + m_page->addSchedulePair(SchedulePair::create([NSRunLoop currentRunLoop], kCFRunLoopCommonModes)); +#endif + + WKAccessibilityWebPageObject* mockAccessibilityElement = [[[WKAccessibilityWebPageObject 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::RegisterWebProcessAccessibilityToken(dataToken)); + m_mockAccessibilityElement = mockAccessibilityElement; +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ +} + +typedef HashMap<String, String> SelectorNameMap; + +// Map selectors into Editor command names. +// This is not needed for any selectors that have the same name as the Editor command. +static const SelectorNameMap* createSelectorExceptionMap() +{ + SelectorNameMap* map = new HashMap<String, String>; + + map->add("insertNewlineIgnoringFieldEditor:", "InsertNewline"); + map->add("insertParagraphSeparator:", "InsertNewline"); + map->add("insertTabIgnoringFieldEditor:", "InsertTab"); + map->add("pageDown:", "MovePageDown"); + map->add("pageDownAndModifySelection:", "MovePageDownAndModifySelection"); + map->add("pageUp:", "MovePageUp"); + map->add("pageUpAndModifySelection:", "MovePageUpAndModifySelection"); + + return map; +} + +static String commandNameForSelectorName(const String& selectorName) +{ + // Check the exception map first. + static const SelectorNameMap* exceptionMap = createSelectorExceptionMap(); + SelectorNameMap::const_iterator it = exceptionMap->find(selectorName); + if (it != exceptionMap->end()) + return it->second; + + // Remove the trailing colon. + // No need to capitalize the command name since Editor command names are not case sensitive. + size_t selectorNameLength = selectorName.length(); + if (selectorNameLength < 2 || selectorName[selectorNameLength - 1] != ':') + return String(); + return selectorName.left(selectorNameLength - 1); +} + +static Frame* frameForEvent(KeyboardEvent* event) +{ + Node* node = event->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + return frame; +} + +bool WebPage::executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>& commands, KeyboardEvent* event) +{ + Frame* frame = frameForEvent(event); + ASSERT(frame->page() == corePage()); + + bool eventWasHandled = false; + for (size_t i = 0; i < commands.size(); ++i) { + if (commands[i].commandName == "insertText:") { + ASSERT(!frame->editor()->hasComposition()); + + if (!frame->editor()->canEdit()) + continue; + + // An insertText: might be handled by other responders in the chain if we don't handle it. + // One example is space bar that results in scrolling down the page. + eventWasHandled |= frame->editor()->insertText(commands[i].text, event); + } else { + Editor::Command command = frame->editor()->command(commandNameForSelectorName(commands[i].commandName)); + if (command.isSupported()) { + bool commandExecutedByEditor = command.execute(event); + eventWasHandled |= commandExecutedByEditor; + if (!commandExecutedByEditor) { + bool performedNonEditingBehavior = event->keyEvent()->type() == PlatformEvent::RawKeyDown && performNonEditingBehaviorForSelector(commands[i].commandName); + eventWasHandled |= performedNonEditingBehavior; + } + } else { + bool commandWasHandledByUIProcess = false; + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::ExecuteSavedCommandBySelector(commands[i].commandName), + Messages::WebPageProxy::ExecuteSavedCommandBySelector::Reply(commandWasHandledByUIProcess), m_pageID); + eventWasHandled |= commandWasHandledByUIProcess; + } + } + } + return eventWasHandled; +} + +bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event, bool saveCommands) +{ + ASSERT(!saveCommands || event->keypressCommands().isEmpty()); // Save commands once for each event. + + Frame* frame = frameForEvent(event); + + const PlatformKeyboardEvent* platformEvent = event->keyEvent(); + if (!platformEvent) + return false; + Vector<KeypressCommand>& commands = event->keypressCommands(); + + if ([platformEvent->macEvent() type] == NSFlagsChanged) + return false; + + bool eventWasHandled = false; + + if (saveCommands) { + KeyboardEvent* oldEvent = m_keyboardEventBeingInterpreted; + m_keyboardEventBeingInterpreted = event; + bool sendResult = WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretQueuedKeyEvent(editorState()), + Messages::WebPageProxy::InterpretQueuedKeyEvent::Reply(eventWasHandled, commands), m_pageID); + m_keyboardEventBeingInterpreted = oldEvent; + if (!sendResult) + return false; + + // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline. + // IM-like actions are handled immediately (so the return value from UI process is true), but there are saved commands that + // should be handled like normal text input after DOM event dispatch. + if (!event->keypressCommands().isEmpty()) + return false; + } else { + // Are there commands that could 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 < commands.size(); ++i) { + if (frame->editor()->command(commandNameForSelectorName(commands[i].commandName)).isTextInsertion()) + haveTextInsertionCommands = true; + } + // If there are no text insertion commands, default keydown handler is the right time to execute the commands. + // Keypress (Char event) handler is the latest opportunity to execute. + if (!haveTextInsertionCommands || platformEvent->type() == PlatformEvent::Char) { + eventWasHandled = executeKeypressCommandsInternal(event->keypressCommands(), event); + event->keypressCommands().clear(); + } + } + 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::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + if (frame->selection()->isContentEditable()) { + RefPtr<Range> replacementRange; + if (replacementRangeStart != NSNotFound) { + replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart)); + frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); + } + + frame->editor()->setComposition(text, underlines, selectionStart, selectionEnd); + } + + newState = editorState(); +} + +void WebPage::confirmComposition(EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + frame->editor()->confirmComposition(); + + newState = editorState(); +} + +void WebPage::cancelComposition(EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + frame->editor()->cancelComposition(); + + newState = editorState(); +} + +void WebPage::insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + RefPtr<Range> replacementRange; + if (replacementRangeStart != NSNotFound) { + replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart)); + frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); + } + + if (!frame->editor()->hasComposition()) { + // An insertText: might be handled by other responders in the chain if we don't handle it. + // One example is space bar that results in scrolling down the page. + handled = frame->editor()->insertText(text, m_keyboardEventBeingInterpreted); + } else { + handled = true; + frame->editor()->confirmComposition(text); + } + + newState = editorState(); +} + +void WebPage::getMarkedRange(uint64_t& location, uint64_t& length) +{ + location = NSNotFound; + length = 0; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + RefPtr<Range> range = frame->editor()->compositionRange(); + size_t locationSize; + size_t lengthSize; + if (range && TextIterator::getLocationAndLengthFromRange(frame->selection()->rootEditableElementOrDocumentElement(), range.get(), locationSize, lengthSize)) { + location = static_cast<uint64_t>(locationSize); + length = static_cast<uint64_t>(lengthSize); + } +} + +void WebPage::getSelectedRange(uint64_t& location, uint64_t& length) +{ + location = NSNotFound; + length = 0; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + size_t locationSize; + size_t lengthSize; + RefPtr<Range> range = frame->selection()->toNormalizedRange(); + if (range && TextIterator::getLocationAndLengthFromRange(frame->selection()->rootEditableElementOrDocumentElement(), range.get(), locationSize, lengthSize)) { + location = static_cast<uint64_t>(locationSize); + length = static_cast<uint64_t>(lengthSize); + } +} + +void WebPage::getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString& result) +{ + NSRange nsRange = NSMakeRange(location, length - location); + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + if (frame->selection()->isNone() || !frame->selection()->isContentEditable() || frame->selection()->isInPasswordField()) + return; + + RefPtr<Range> range = convertToRange(frame, nsRange); + if (!range) + return; + + result.string = [WebHTMLConverter editingAttributedStringFromRange:range.get()]; + NSAttributedString* attributedString = result.string.get(); + + // [WebHTMLConverter editingAttributedStringFromRange:] insists on inserting a trailing + // whitespace at the end of the string which breaks the ATOK input method. <rdar://problem/5400551> + // To work around this we truncate the resultant string to the correct length. + if ([attributedString length] > nsRange.length) { + ASSERT([attributedString length] == nsRange.length + 1); + ASSERT([[attributedString string] characterAtIndex:nsRange.length] == '\n' || [[attributedString string] characterAtIndex:nsRange.length] == ' '); + result.string = [attributedString attributedSubstringFromRange:NSMakeRange(0, nsRange.length)]; + } +} + +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(); + + RefPtr<Range> range = frame->rangeForPoint(result.point()); + if (!range) + return; + + size_t location; + size_t length; + if (TextIterator::getLocationAndLengthFromRange(frame->selection()->rootEditableElementOrDocumentElement(), range.get(), location, length)) + index = static_cast<uint64_t>(location); +} + +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. + return TextIterator::rangeFromLocationAndLength(frame->selection()->rootEditableElementOrDocumentElement(), 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) + return; + + ASSERT(range->startContainer()); + ASSERT(range->endContainer()); + + IntRect rect = frame->editor()->firstRectForRange(range.get()); + resultRect = frame->view()->contentsToWindow(rect); +} + +void WebPage::executeKeypressCommands(const Vector<WebCore::KeypressCommand>& commands, bool& handled, EditorState& newState) +{ + handled = executeKeypressCommandsInternal(commands, m_keyboardEventBeingInterpreted); + newState = editorState(); +} + +static bool isPositionInRange(const VisiblePosition& position, Range* range) +{ + RefPtr<Range> positionRange = makeRange(position, position); + + ExceptionCode ec = 0; + range->compareBoundaryPoints(Range::START_TO_START, positionRange.get(), ec); + if (ec) + return false; + + if (!range->isPointInRange(positionRange->startContainer(), positionRange->startOffset(), ec)) + return false; + if (ec) + return false; + + return true; +} + +static bool shouldUseSelection(const VisiblePosition& position, const VisibleSelection& selection) +{ + if (!selection.isRange()) + return false; + + RefPtr<Range> selectedRange = selection.toNormalizedRange(); + if (!selectedRange) + return false; + + return isPositionInRange(position, selectedRange.get()); +} + +void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint) +{ + Frame* frame = m_page->mainFrame(); + if (!frame) + return; + + // Find the frame the point is over. + IntPoint point = roundedIntPoint(floatPoint); + HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(point, false); + frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame(); + + IntPoint translatedPoint = frame->view()->windowToContents(point); + + // Don't do anything if there is no character at the point. + if (!frame->rangeForPoint(translatedPoint)) + return; + + VisiblePosition position = frame->visiblePositionForPoint(translatedPoint); + VisibleSelection selection = m_page->focusController()->focusedOrMainFrame()->selection()->selection(); + if (shouldUseSelection(position, selection)) { + performDictionaryLookupForSelection(DictionaryPopupInfo::HotKey, frame, selection); + return; + } + + NSDictionary *options = nil; + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + // As context, we are going to use the surrounding paragraph of text. + VisiblePosition paragraphStart = startOfParagraph(position); + VisiblePosition paragraphEnd = endOfParagraph(position); + + NSRange rangeToPass = NSMakeRange(TextIterator::rangeLength(makeRange(paragraphStart, position).get()), 0); + + RefPtr<Range> fullCharacterRange = makeRange(paragraphStart, paragraphEnd); + String fullPlainTextString = plainText(fullCharacterRange.get()); + + NSRange extractedRange = WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, &options); + + RefPtr<Range> finalRange = TextIterator::subrange(fullCharacterRange.get(), extractedRange.location, extractedRange.length); + if (!finalRange) + return; +#else + RefPtr<Range> finalRange = makeRange(startOfWord(position), endOfWord(position)); + if (!finalRange) + return; +#endif + + performDictionaryLookupForRange(DictionaryPopupInfo::HotKey, frame, finalRange.get(), options); +} + +void WebPage::performDictionaryLookupForSelection(DictionaryPopupInfo::Type type, Frame* frame, const VisibleSelection& selection) +{ + RefPtr<Range> selectedRange = selection.toNormalizedRange(); + if (!selectedRange) + return; + + NSDictionary *options = nil; + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + VisiblePosition selectionStart = selection.visibleStart(); + VisiblePosition selectionEnd = selection.visibleEnd(); + + // As context, we are going to use the surrounding paragraphs of text. + VisiblePosition paragraphStart = startOfParagraph(selectionStart); + VisiblePosition paragraphEnd = endOfParagraph(selectionEnd); + + int lengthToSelectionStart = TextIterator::rangeLength(makeRange(paragraphStart, selectionStart).get()); + int lengthToSelectionEnd = TextIterator::rangeLength(makeRange(paragraphStart, selectionEnd).get()); + NSRange rangeToPass = NSMakeRange(lengthToSelectionStart, lengthToSelectionEnd - lengthToSelectionStart); + + String fullPlainTextString = plainText(makeRange(paragraphStart, paragraphEnd).get()); + + // Since we already have the range we want, we just need to grab the returned options. + WKExtractWordDefinitionTokenRangeFromContextualString(fullPlainTextString, rangeToPass, &options); +#endif + + performDictionaryLookupForRange(type, frame, selectedRange.get(), options); +} + +void WebPage::performDictionaryLookupForRange(DictionaryPopupInfo::Type type, Frame* frame, Range* range, NSDictionary *options) +{ + String rangeText = range->text(); + if (rangeText.stripWhiteSpace().isEmpty()) + return; + + RenderObject* renderer = range->startContainer()->renderer(); + RenderStyle* style = renderer->style(); + NSFont *font = style->font().primaryFont()->getNSFont(); + + // We won't be able to get an NSFont in the case that a Web Font is being used, so use + // the default system font at the same size instead. + if (!font) + font = [NSFont systemFontOfSize:style->font().primaryFont()->platformData().size()]; + + CFDictionaryRef fontDescriptorAttributes = (CFDictionaryRef)[[font fontDescriptor] fontAttributes]; + if (!fontDescriptorAttributes) + return; + + Vector<FloatQuad> quads; + range->textQuads(quads); + if (quads.isEmpty()) + return; + + IntRect rangeRect = frame->view()->contentsToWindow(quads[0].enclosingBoundingBox()); + + DictionaryPopupInfo dictionaryPopupInfo; + dictionaryPopupInfo.type = type; + dictionaryPopupInfo.origin = FloatPoint(rangeRect.x(), rangeRect.y() + style->fontMetrics().ascent()); + dictionaryPopupInfo.fontInfo.fontAttributeDictionary = fontDescriptorAttributes; +#if !defined(BUILDING_ON_SNOW_LEOPARD) + dictionaryPopupInfo.options = (CFDictionaryRef)options; +#endif + + send(Messages::WebPageProxy::DidPerformDictionaryLookup(rangeText, dictionaryPopupInfo)); +} + +bool WebPage::performNonEditingBehaviorForSelector(const String& selector) +{ + // FIXME: All these selectors have corresponding Editor commands, but the commands only work in editable content. + // Should such non-editing behaviors be implemented in Editor or EventHandler::defaultArrowEventHandler() perhaps? + if (selector == "moveUp:") + scroll(m_page.get(), ScrollUp, ScrollByLine); + else if (selector == "moveToBeginningOfParagraph:") + scroll(m_page.get(), ScrollUp, ScrollByPage); + else if (selector == "moveToBeginningOfDocument:") { + scroll(m_page.get(), ScrollUp, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (selector == "moveDown:") + scroll(m_page.get(), ScrollDown, ScrollByLine); + else if (selector == "moveToEndOfParagraph:") + scroll(m_page.get(), ScrollDown, ScrollByPage); + else if (selector == "moveToEndOfDocument:") { + scroll(m_page.get(), ScrollDown, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (selector == "moveLeft:") + scroll(m_page.get(), ScrollLeft, ScrollByLine); + else if (selector == "moveWordLeft:") + scroll(m_page.get(), ScrollLeft, ScrollByPage); + else if (selector == "moveToLeftEndOfLine:") + m_page->goBack(); + else if (selector == "moveRight:") + scroll(m_page.get(), ScrollRight, ScrollByLine); + else if (selector == "moveWordRight:") + scroll(m_page.get(), ScrollRight, ScrollByPage); + else if (selector == "moveToRightEndOfLine:") + m_page->goForward(); + else + return false; + + return true; +} + +bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&) +{ + return false; +} + +void WebPage::registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elementToken, const CoreIPC::DataReference& windowToken) +{ + NSData* elementTokenData = [NSData dataWithBytes:elementToken.data() length:elementToken.size()]; + NSData* windowTokenData = [NSData dataWithBytes:windowToken.data() length:windowToken.size()]; + id remoteElement = WKAXRemoteElementForToken(elementTokenData); + id remoteWindow = WKAXRemoteElementForToken(windowTokenData); + WKAXSetWindowForRemoteElement(remoteWindow, remoteElement); + + [accessibilityRemoteObject() setRemoteParent:remoteElement]; +} + +void WebPage::writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes, bool& result) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || frame->selection()->isNone()) { + result = false; + return; + } + frame->editor()->writeSelectionToPasteboard(pasteboardName, pasteboardTypes); + result = true; +} + +void WebPage::readSelectionFromPasteboard(const String& pasteboardName, bool& result) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || frame->selection()->isNone()) { + result = false; + return; + } + frame->editor()->readSelectionFromPasteboard(pasteboardName); + result = true; +} + +WKAccessibilityWebPageObject* 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; +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = ResourceHandle::currentStorageSession()) + cachedResponse = WKCachedResponseForRequest(storageSession, request); + else +#endif + cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request]; + [request release]; + + return cachedResponse; +} + +static NSCachedURLResponse *cachedResponseForURL(WebPage* webPage, const KURL& url) +{ + RetainPtr<NSMutableURLRequest> request(AdoptNS, [[NSMutableURLRequest alloc] initWithURL:url]); + [request.get() setValue:(NSString *)webPage->userAgent() forHTTPHeaderField:@"User-Agent"]; + +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = ResourceHandle::currentStorageSession()) + return WKCachedResponseForRequest(storageSession, request.get()); +#endif + + return [[NSURLCache sharedURLCache] cachedResponseForRequest:request.get()]; +} + +String WebPage::cachedSuggestedFilenameForURL(const KURL& url) +{ + return [[cachedResponseForURL(this, url) response] suggestedFilename]; +} + +String WebPage::cachedResponseMIMETypeForURL(const KURL& url) +{ + return [[cachedResponseForURL(this, url) response] MIMEType]; +} + +PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL& url) +{ + return SharedBuffer::wrapNSData([cachedResponseForURL(this, url) data]); +} + +bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request) +{ + if ([NSURLConnection canHandleRequest:request.nsURLRequest()]) + return true; + + // FIXME: Return true if this scheme is any one WebKit2 knows how to handle. + return request.url().protocolIs("applewebdata"); +} + +void WebPage::shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent& event, bool& result) +{ + result = false; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + HitTestResult hitResult = frame->eventHandler()->hitTestResultAtPoint(event.position(), true); + if (hitResult.isSelected()) + result = frame->eventHandler()->eventMayStartDrag(platform(event)); +} + +void WebPage::acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent& event, bool& result) +{ + result = false; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + HitTestResult hitResult = frame->eventHandler()->hitTestResultAtPoint(event.position(), true); + frame->eventHandler()->setActivationEventNumber(eventNumber); + if (hitResult.isSelected()) + result = frame->eventHandler()->eventMayStartDrag(platform(event)); + else + result = !!hitResult.scrollbar(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp new file mode 100644 index 000000000..266a3a95d --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.cpp @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerTreeHostQt.h" + +#include "DrawingAreaImpl.h" +#include "GraphicsContext.h" +#include "LayerTreeHostProxyMessages.h" +#include "MessageID.h" +#include "WebGraphicsLayer.h" +#include "WebPage.h" +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/Page.h> +#include <WebCore/Settings.h> + +using namespace WebCore; + +namespace WebKit { + +PassRefPtr<LayerTreeHostQt> LayerTreeHostQt::create(WebPage* webPage) +{ + return adoptRef(new LayerTreeHostQt(webPage)); +} + +LayerTreeHostQt::~LayerTreeHostQt() +{ +} + +LayerTreeHostQt::LayerTreeHostQt(WebPage* webPage) + : LayerTreeHost(webPage) + , m_notifyAfterScheduledLayerFlush(false) + , m_isValid(true) +#if USE(TILED_BACKING_STORE) + , m_waitingForUIProcess(false) + , m_isSuspended(false) +#endif + , m_shouldSyncFrame(false) + , m_shouldSyncRootLayer(true) + , m_layerFlushTimer(this, &LayerTreeHostQt::layerFlushTimerFired) + , m_layerFlushSchedulingEnabled(true) + , m_shouldRecreateBackingStore(false) +{ + // Create a root layer. + m_rootLayer = GraphicsLayer::create(this); + WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get()); + webRootLayer->setRootLayer(true); +#ifndef NDEBUG + m_rootLayer->setName("LayerTreeHostQt root layer"); +#endif + m_rootLayer->setDrawsContent(false); + m_rootLayer->setSize(m_webPage->size()); + m_layerTreeContext.webLayerID = toWebGraphicsLayer(webRootLayer)->id(); + + m_nonCompositedContentLayer = GraphicsLayer::create(this); +#if USE(TILED_BACKING_STORE) + toWebGraphicsLayer(m_rootLayer.get())->setLayerTreeTileClient(this); +#endif +#ifndef NDEBUG + m_nonCompositedContentLayer->setName("LayerTreeHostQt non-composited content"); +#endif + m_nonCompositedContentLayer->setDrawsContent(true); + m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); + m_nonCompositedContentLayer->setSize(m_webPage->size()); + + m_rootLayer->addChild(m_nonCompositedContentLayer.get()); + + if (m_webPage->hasPageOverlay()) + createPageOverlayLayer(); + + scheduleLayerFlush(); +} + +void LayerTreeHostQt::setLayerFlushSchedulingEnabled(bool layerFlushingEnabled) +{ + if (m_layerFlushSchedulingEnabled == layerFlushingEnabled) + return; + + m_layerFlushSchedulingEnabled = layerFlushingEnabled; + + if (m_layerFlushSchedulingEnabled) { + scheduleLayerFlush(); + return; + } + + cancelPendingLayerFlush(); +} + +void LayerTreeHostQt::scheduleLayerFlush() +{ + if (!m_layerFlushSchedulingEnabled) + return; + + if (!m_layerFlushTimer.isActive()) + m_layerFlushTimer.startOneShot(0); +} + +void LayerTreeHostQt::cancelPendingLayerFlush() +{ + m_layerFlushTimer.stop(); +} + +void LayerTreeHostQt::setShouldNotifyAfterNextScheduledLayerFlush(bool notifyAfterScheduledLayerFlush) +{ + m_notifyAfterScheduledLayerFlush = notifyAfterScheduledLayerFlush; +} + +void LayerTreeHostQt::setRootCompositingLayer(WebCore::GraphicsLayer* graphicsLayer) +{ + m_nonCompositedContentLayer->removeAllChildren(); + + // Add the accelerated layer tree hierarchy. + if (graphicsLayer) + m_nonCompositedContentLayer->addChild(graphicsLayer); +} + +void LayerTreeHostQt::invalidate() +{ + cancelPendingLayerFlush(); + + ASSERT(m_isValid); + m_rootLayer = nullptr; + m_isValid = false; +} + +void LayerTreeHostQt::setNonCompositedContentsNeedDisplay(const WebCore::IntRect& rect) +{ + m_nonCompositedContentLayer->setNeedsDisplayInRect(rect); + if (m_pageOverlayLayer) + m_pageOverlayLayer->setNeedsDisplayInRect(rect); + + scheduleLayerFlush(); +} + +void LayerTreeHostQt::scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) +{ + setNonCompositedContentsNeedDisplay(scrollRect); +} + +void LayerTreeHostQt::forceRepaint() +{ + scheduleLayerFlush(); +} + +void LayerTreeHostQt::sizeDidChange(const WebCore::IntSize& newSize) +{ + m_rootLayer->setSize(newSize); + + // If the newSize exposes new areas of the non-composited content a setNeedsDisplay is needed + // for those newly exposed areas. + FloatSize oldSize = m_nonCompositedContentLayer->size(); + m_nonCompositedContentLayer->setSize(newSize); + + if (newSize.width() > oldSize.width()) { + float height = std::min(static_cast<float>(newSize.height()), oldSize.height()); + m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(oldSize.width(), 0, newSize.width() - oldSize.width(), height)); + } + + if (newSize.height() > oldSize.height()) + m_nonCompositedContentLayer->setNeedsDisplayInRect(FloatRect(0, oldSize.height(), newSize.width(), newSize.height() - oldSize.height())); + + if (m_pageOverlayLayer) + m_pageOverlayLayer->setSize(newSize); + + scheduleLayerFlush(); +} + +void LayerTreeHostQt::didInstallPageOverlay() +{ + createPageOverlayLayer(); + scheduleLayerFlush(); +} + +void LayerTreeHostQt::didUninstallPageOverlay() +{ + destroyPageOverlayLayer(); + scheduleLayerFlush(); +} + +void LayerTreeHostQt::setPageOverlayNeedsDisplay(const WebCore::IntRect& rect) +{ + ASSERT(m_pageOverlayLayer); + m_pageOverlayLayer->setNeedsDisplayInRect(rect); + scheduleLayerFlush(); +} + +bool LayerTreeHostQt::flushPendingLayerChanges() +{ + recreateBackingStoreIfNeeded(); + + bool didSync = m_webPage->corePage()->mainFrame()->view()->syncCompositingStateIncludingSubframes(); + m_nonCompositedContentLayer->syncCompositingStateForThisLayerOnly(); + if (m_pageOverlayLayer) + m_pageOverlayLayer->syncCompositingStateForThisLayerOnly(); + + m_rootLayer->syncCompositingStateForThisLayerOnly(); + return didSync; +} + +void LayerTreeHostQt::didSyncCompositingStateForLayer(const WebLayerInfo& info) +{ + m_shouldSyncFrame = true; + m_webPage->send(Messages::LayerTreeHostProxy::SyncCompositingLayerState(info)); +} + +void LayerTreeHostQt::didDeleteLayer(WebLayerID id) +{ + m_shouldSyncFrame = true; + m_webPage->send(Messages::LayerTreeHostProxy::DeleteCompositingLayer(id)); +} + +void LayerTreeHostQt::performScheduledLayerFlush() +{ + m_webPage->layoutIfNeeded(); + + if (!m_isValid) + return; + +#if USE(TILED_BACKING_STORE) + if (m_isSuspended || m_waitingForUIProcess) + return; +#endif + + m_shouldSyncFrame = false; + flushPendingLayerChanges(); + if (!m_shouldSyncFrame) + return; + + if (m_shouldSyncRootLayer) { + m_webPage->send(Messages::LayerTreeHostProxy::SetRootCompositingLayer(toWebGraphicsLayer(m_rootLayer.get())->id())); + m_shouldSyncRootLayer = false; + } + + m_webPage->send(Messages::LayerTreeHostProxy::DidRenderFrame()); + + if (!m_notifyAfterScheduledLayerFlush) + return; + + // Let the drawing area know that we've done a flush of the layer changes. + static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers(); + m_notifyAfterScheduledLayerFlush = false; +} + +void LayerTreeHostQt::layerFlushTimerFired(Timer<LayerTreeHostQt>*) +{ + performScheduledLayerFlush(); +} + +void LayerTreeHostQt::createPageOverlayLayer() +{ + ASSERT(!m_pageOverlayLayer); + + m_pageOverlayLayer = GraphicsLayer::create(this); +#ifndef NDEBUG + m_pageOverlayLayer->setName("LayerTreeHostQt page overlay content"); +#endif + + m_pageOverlayLayer->setDrawsContent(true); + m_pageOverlayLayer->setSize(m_webPage->size()); + + m_rootLayer->addChild(m_pageOverlayLayer.get()); +} + +void LayerTreeHostQt::destroyPageOverlayLayer() +{ + ASSERT(m_pageOverlayLayer); + m_pageOverlayLayer->removeFromParent(); + m_pageOverlayLayer = nullptr; +} + +int64_t LayerTreeHostQt::adoptImageBackingStore(Image* image) +{ + if (!image) + return InvalidWebLayerID; + QPixmap* pixmap = image->nativeImageForCurrentFrame(); + + if (!pixmap) + return InvalidWebLayerID; + + int64_t key = pixmap->cacheKey(); + HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key); + + if (it != m_directlyCompositedImageRefCounts.end()) { + ++(it->second); + return key; + } + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), image->currentFrameHasAlpha() ? ShareableBitmap::SupportsAlpha : 0); + { + OwnPtr<WebCore::GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntPoint::zero()); + } + + ShareableBitmap::Handle handle; + bitmap->createHandle(handle); + m_webPage->send(Messages::LayerTreeHostProxy::CreateDirectlyCompositedImage(key, handle)); + m_directlyCompositedImageRefCounts.add(key, 1); + return key; +} + +void LayerTreeHostQt::releaseImageBackingStore(int64_t key) +{ + if (!key) + return; + HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key); + if (it == m_directlyCompositedImageRefCounts.end()) + return; + + it->second--; + + if (it->second) + return; + + m_directlyCompositedImageRefCounts.remove(it); + m_webPage->send(Messages::LayerTreeHostProxy::DestroyDirectlyCompositedImage(key)); +} + + +void LayerTreeHostQt::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) +{ +} + +void LayerTreeHostQt::notifySyncRequired(const WebCore::GraphicsLayer*) +{ +} + +void LayerTreeHostQt::paintContents(const WebCore::GraphicsLayer* graphicsLayer, WebCore::GraphicsContext& graphicsContext, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect) +{ + if (graphicsLayer == m_nonCompositedContentLayer) { + m_webPage->drawRect(graphicsContext, clipRect); + return; + } + + if (graphicsLayer == m_pageOverlayLayer) { + // Overlays contain transparent contents and won't clear the context as part of their rendering, so we do it here. + graphicsContext.clearRect(clipRect); + m_webPage->drawPageOverlay(graphicsContext, clipRect); + return; + } +} + +bool LayerTreeHostQt::showDebugBorders() const +{ + return m_webPage->corePage()->settings()->showDebugBorders(); +} + +bool LayerTreeHostQt::showRepaintCounter() const +{ + return m_webPage->corePage()->settings()->showRepaintCounter(); +} + +bool LayerTreeHost::supportsAcceleratedCompositing() +{ + return true; +} + +#if USE(TILED_BACKING_STORE) +void LayerTreeHostQt::createTile(WebLayerID layerID, int tileID, const UpdateInfo& updateInfo) +{ + m_webPage->send(Messages::LayerTreeHostProxy::CreateTileForLayer(layerID, tileID, updateInfo)); +} + +void LayerTreeHostQt::updateTile(WebLayerID layerID, int tileID, const UpdateInfo& updateInfo) +{ + m_webPage->send(Messages::LayerTreeHostProxy::UpdateTileForLayer(layerID, tileID, updateInfo)); +} +void LayerTreeHostQt::removeTile(WebLayerID layerID, int tileID) +{ + m_webPage->send(Messages::LayerTreeHostProxy::RemoveTileForLayer(layerID, tileID)); +} + +void LayerTreeHostQt::setVisibleContentRectForLayer(int layerID, const WebCore::IntRect& rect) +{ + WebGraphicsLayer* layer = WebGraphicsLayer::layerByID(layerID); + if (!layer) + return; + FloatRect visibleRect(rect); + layer->setVisibleContentRect(rect); +} + +void LayerTreeHostQt::setVisibleContentRectAndScale(const IntRect& rect, float scale) +{ + WebGraphicsLayer* layer = toWebGraphicsLayer(m_rootLayer.get()); + if (!layer) + return; + layer->setContentsScale(scale); + toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRect(rect); +} + +void LayerTreeHostQt::setVisibleContentRectTrajectoryVector(const FloatPoint& trajectoryVector) +{ + toWebGraphicsLayer(m_nonCompositedContentLayer.get())->setVisibleContentRectTrajectoryVector(trajectoryVector); +} + +void LayerTreeHostQt::renderNextFrame() +{ + m_waitingForUIProcess = false; + scheduleLayerFlush(); +} + +bool LayerTreeHostQt::layerTreeTileUpdatesAllowed() const +{ + return !m_isSuspended && !m_waitingForUIProcess; +} + +void LayerTreeHostQt::purgeBackingStores() +{ + m_shouldRecreateBackingStore = true; + WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get()); + webRootLayer->purgeBackingStores(); + + ASSERT(!m_directlyCompositedImageRefCounts.size()); +} + +void LayerTreeHostQt::recreateBackingStoreIfNeeded() +{ + if (!m_shouldRecreateBackingStore) + return; + + m_shouldRecreateBackingStore = false; + WebGraphicsLayer* webRootLayer = toWebGraphicsLayer(m_rootLayer.get()); + webRootLayer->recreateBackingStoreIfNeeded(); +} +#endif + +} // namespace WebKit +#else +#include "LayerTreeHost.h" + +using namespace WebCore; + +namespace WebKit { + +bool LayerTreeHost::supportsAcceleratedCompositing() +{ + return false; +} + +} // namespace WebKit +#endif diff --git a/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h new file mode 100644 index 000000000..8527c528b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/LayerTreeHostQt.h @@ -0,0 +1,129 @@ +/* + Copyright (C) 2011 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 LayerTreeHostQt_h +#define LayerTreeHostQt_h + +#include "LayerTreeContext.h" +#include "LayerTreeHost.h" +#include "Timer.h" +#include "WebGraphicsLayer.h" +#include <WebCore/GraphicsLayerClient.h> +#include <wtf/OwnPtr.h> + +namespace WebKit { + +class UpdateInfo; +class WebPage; + +class LayerTreeHostQt : public LayerTreeHost, WebCore::GraphicsLayerClient +#if USE(TILED_BACKING_STORE) + , public WebLayerTreeTileClient +#endif +{ +public: + static PassRefPtr<LayerTreeHostQt> create(WebPage*); + virtual ~LayerTreeHostQt(); + + static bool supportsAcceleratedCompositing(); + + virtual const LayerTreeContext& layerTreeContext() { return m_layerTreeContext; } + virtual void setLayerFlushSchedulingEnabled(bool); + virtual void scheduleLayerFlush(); + virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool); + virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); + virtual void invalidate(); + + virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&); + virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); + virtual void forceRepaint(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + + virtual void didInstallPageOverlay(); + virtual void didUninstallPageOverlay(); + virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&); + + virtual void pauseRendering() { m_isSuspended = true; } + virtual void resumeRendering() { m_isSuspended = false; scheduleLayerFlush(); } + virtual void deviceScaleFactorDidChange() { } + virtual int64_t adoptImageBackingStore(Image*); + virtual void releaseImageBackingStore(int64_t); + +#if USE(TILED_BACKING_STORE) + virtual void createTile(WebLayerID, int tileID, const UpdateInfo&); + virtual void updateTile(WebLayerID, int tileID, const UpdateInfo&); + virtual void removeTile(WebLayerID, int tileID); + virtual void setVisibleContentRectForLayer(int layerID, const WebCore::IntRect&); + virtual void renderNextFrame(); + virtual void purgeBackingStores(); + virtual bool layerTreeTileUpdatesAllowed() const; + virtual void setVisibleContentRectAndScale(const IntRect&, float scale); + virtual void setVisibleContentRectTrajectoryVector(const FloatPoint&); + virtual void didSyncCompositingStateForLayer(const WebLayerInfo&); + virtual void didDeleteLayer(WebLayerID); +#endif + +protected: + explicit LayerTreeHostQt(WebPage*); + +private: + // GraphicsLayerClient + virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time); + virtual void notifySyncRequired(const WebCore::GraphicsLayer*); + virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect); + virtual bool showDebugBorders() const; + virtual bool showRepaintCounter() const; + + // LayerTreeHostQt + void createPageOverlayLayer(); + void destroyPageOverlayLayer(); + bool flushPendingLayerChanges(); + void cancelPendingLayerFlush(); + void performScheduledLayerFlush(); + void sendLayersToUI(); + void recreateBackingStoreIfNeeded(); + + OwnPtr<WebCore::GraphicsLayer> m_rootLayer; + + // The layer which contains all non-composited content. + OwnPtr<WebCore::GraphicsLayer> m_nonCompositedContentLayer; + + // The page overlay layer. Will be null if there's no page overlay. + OwnPtr<WebCore::GraphicsLayer> m_pageOverlayLayer; + + HashMap<int64_t, int> m_directlyCompositedImageRefCounts; + + bool m_notifyAfterScheduledLayerFlush; + bool m_isValid; +#if USE(TILED_BACKING_STORE) + bool m_waitingForUIProcess; + bool m_isSuspended; +#endif + LayerTreeContext m_layerTreeContext; + bool m_shouldSyncFrame; + bool m_shouldSyncRootLayer; + void layerFlushTimerFired(WebCore::Timer<LayerTreeHostQt>*); + WebCore::Timer<LayerTreeHostQt> m_layerFlushTimer; + bool m_layerFlushSchedulingEnabled; + bool m_shouldRecreateBackingStore; +}; + +} + +#endif // LayerTreeHostQt_h diff --git a/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.cpp new file mode 100644 index 000000000..1a3b598a3 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/WebInspectorQt.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 "config.h" +#include "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include <WebCore/NotImplemented.h> +#include <wtf/text/WTFString.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 000000000..55080d03c --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/qt/WebPageQt.cpp @@ -0,0 +1,418 @@ +/* + * 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 "config.h" +#include "WebPage.h" + +#include "NotImplemented.h" +#include "WebEditorClient.h" +#include "WebEvent.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/Range.h> +#include <WebCore/Settings.h> +#include <WebCore/Text.h> +#include <WebCore/TextIterator.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() +{ + Settings* settings = m_page->settings(); + + // If accelerated compositing is enabled, we want to be in force-compositing mode, so that we don't switch between composited/non-composited state. + settings->setForceCompositingMode(true); +} + +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 KURL&) +{ + notImplemented(); + return false; +} + +String WebPage::cachedResponseMIMETypeForURL(const KURL&) +{ + notImplemented(); + return String(); +} + +bool WebPage::platformCanHandleRequest(const ResourceRequest&) +{ + notImplemented(); + return true; +} + +String WebPage::cachedSuggestedFilenameForURL(const KURL&) +{ + notImplemented(); + return String(); +} + +PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL&) +{ + notImplemented(); + return 0; +} + +static Frame* targetFrameForEditing(WebPage* page) +{ + Frame* targetFrame = page->corePage()->focusController()->focusedOrMainFrame(); + + if (!targetFrame || !targetFrame->editor()) + return 0; + + Editor* editor = targetFrame->editor(); + if (!editor->canEdit()) + return 0; + + if (editor->hasComposition()) { + // We should verify the parent node of this IME composition node are + // editable because JavaScript may delete a parent node of the composition + // node. In this case, WebKit crashes while deleting texts from the parent + // node, which doesn't exist any longer. + if (PassRefPtr<Range> range = editor->compositionRange()) { + Node* node = range->startContainer(); + if (!node || !node->isContentEditable()) + return 0; + } + } + return targetFrame; +} + +void WebPage::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength) +{ + Frame* targetFrame = targetFrameForEditing(this); + if (!targetFrame) + return; + + Editor* editor = targetFrame->editor(); + editor->confirmComposition(compositionString); + + RefPtr<Range> selectionRange; + if (selectionStart != -1) { + Element* scope = targetFrame->selection()->rootEditableElement(); + selectionRange = TextIterator::rangeFromLocationAndLength(scope, selectionStart, selectionLength); + ASSERT_WITH_MESSAGE(selectionRange, "Invalid selection: [%lld:%lld] in text of length %d", static_cast<long long>(selectionStart), static_cast<long long>(selectionLength), scope->innerText().length()); + } + + if (selectionRange) { + VisibleSelection selection(selectionRange.get(), SEL_DEFAULT_AFFINITY); + targetFrame->selection()->setSelection(selection); + } + + // FIXME: static_cast<WebEditorClient*>(editor->client())->sendSelectionChangedMessage(); +} + +void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementStart, uint64_t replacementLength) +{ + Frame* targetFrame = targetFrameForEditing(this); + if (!targetFrame) + return; + + Element* scope = targetFrame->selection()->rootEditableElement(); + + if (targetFrame->selection()->isContentEditable()) { + if (replacementLength > 0) { + // The layout needs to be uptodate before setting a selection + targetFrame->document()->updateLayout(); + + RefPtr<Range> replacementRange = TextIterator::rangeFromLocationAndLength(scope, replacementStart, replacementLength); + + targetFrame->editor()->setIgnoreCompositionSelectionChange(true); + targetFrame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); + targetFrame->editor()->setIgnoreCompositionSelectionChange(false); + } + + targetFrame->editor()->setComposition(text, underlines, selectionStart, selectionEnd); + + // FIXME: static_cast<WebEditorClient*>(targetFrame->editor()->client())->sendSelectionChangedMessage(); + } +} + +void WebPage::cancelComposition() +{ + Frame* frame = targetFrameForEditing(this); + + frame->editor()->cancelComposition(); + + // FIXME: static_cast<WebEditorClient*>(targetFrame->editor()->client())->sendSelectionChangedMessage(); +} + +void WebPage::registerApplicationScheme(const String& scheme) +{ + QtNetworkAccessManager* qnam = qobject_cast<QtNetworkAccessManager*>(WebProcess::shared().networkAccessManager()); + if (!qnam) + return; + qnam->registerApplicationScheme(this, QString(scheme)); +} + +void WebPage::receivedApplicationSchemeRequest(const QNetworkRequest& request, QtNetworkReply* reply) +{ + QtNetworkRequestData requestData(request, reply); + m_applicationSchemeReplies.add(requestData.m_replyUuid, reply); + send(Messages::WebPageProxy::ResolveApplicationSchemeRequest(requestData)); +} + +void WebPage::applicationSchemeReply(const QtNetworkReplyData& replyData) +{ + if (!m_applicationSchemeReplies.contains(replyData.m_replyUuid)) + return; + + QtNetworkReply* networkReply = m_applicationSchemeReplies.take(replyData.m_replyUuid); + networkReply->setReplyData(replyData); + networkReply->finalize(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp new file mode 100644 index 000000000..4feb001fa --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/DrawingAreaImplWin.cpp @@ -0,0 +1,64 @@ +/* + * 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 "config.h" +#include "DrawingAreaImpl.h" + +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WindowGeometry.h" +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +void DrawingAreaImpl::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry) +{ +#if USE(ACCELERATED_COMPOSITING) + if (m_layerTreeHost) { + m_layerTreeHost->scheduleChildWindowGeometryUpdate(geometry); + return; + } +#endif + + // FIXME: This should be a Messages::DrawingAreaProxy, and DrawingAreaProxy should pass the + // data off to the WebPageProxy. + m_webPage->send(Messages::WebPageProxy::ScheduleChildWindowGeometryUpdate(geometry)); +} + +PassOwnPtr<GraphicsContext> DrawingAreaImpl::createGraphicsContext(ShareableBitmap* bitmap) +{ + HDC bitmapDC = bitmap->windowsContext(); + // FIXME: We should really be checking m_webPage->draws[Transparent]Background() to determine + // whether to have an alpha channel or not. But currently we always render into a non-layered + // window, so the alpha channel doesn't matter anyway. + return adoptPtr(new GraphicsContext(bitmapDC, false)); +} + +} // namespace WebKit + diff --git a/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp new file mode 100644 index 000000000..57c04bbf0 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp @@ -0,0 +1,44 @@ +/* + * 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 "config.h" +#include "LayerTreeHost.h" + +#if USE(CA) +#include "LayerTreeHostCAWin.h" +#endif + +namespace WebKit { + +bool LayerTreeHost::supportsAcceleratedCompositing() +{ +#if USE(CA) && HAVE(WKQCA) + return LayerTreeHostCAWin::supportsAcceleratedCompositing(); +#else + return false; +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.cpp new file mode 100644 index 000000000..5ada45d41 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/WebInspectorWin.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 "config.h" +#include "WebInspector.h" + +#if ENABLE(INSPECTOR) + +#include "WebKitBundle.h" +#include <wtf/RetainPtr.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +String WebInspector::localizedStringsURL() const +{ + RetainPtr<CFURLRef> localizedStringsURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle(), 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 000000000..19f760f6a --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp @@ -0,0 +1,468 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPage.h" + +#include "FontSmoothingLevel.h" +#include "WebCoreArgumentCoders.h" +#include "WebEvent.h" +#include "WebPageProxyMessages.h" +#include "WebPreferencesStore.h" +#include "WebProcess.h" +#include <WebCore/FocusController.h> +#include <WebCore/FontRenderingMode.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> +#include <WebCore/HitTestRequest.h> +#include <WebCore/HitTestResult.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/RenderView.h> +#include <WebCore/ResourceHandle.h> +#include <WebCore/Settings.h> +#if USE(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() +{ +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store) +{ + FontSmoothingLevel fontSmoothingLevel = static_cast<FontSmoothingLevel>(store.getUInt32ValueForKey(WebPreferencesKey::fontSmoothingLevelKey())); + +#if USE(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; +} + +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.isSystemKey()) + return false; + if (keyboardEvent.shiftKey()) + m_page->goForward(); + else + m_page->goBack(); + break; + case VK_LEFT: + if (keyboardEvent.isSystemKey()) + m_page->goBack(); + else + scroll(m_page.get(), ScrollLeft, ScrollByLine); + break; + case VK_RIGHT: + if (keyboardEvent.isSystemKey()) + m_page->goForward(); + else + scroll(m_page.get(), ScrollRight, ScrollByLine); + break; + case VK_UP: + if (keyboardEvent.isSystemKey()) + return false; + scroll(m_page.get(), ScrollUp, ScrollByLine); + break; + case VK_DOWN: + if (keyboardEvent.isSystemKey()) + return false; + scroll(m_page.get(), ScrollDown, ScrollByLine); + break; + case VK_HOME: + if (keyboardEvent.isSystemKey()) + return false; + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument); + break; + case VK_END: + if (keyboardEvent.isSystemKey()) + return false; + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument); + break; + case VK_PRIOR: + if (keyboardEvent.isSystemKey()) + return false; + logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); + break; + case VK_NEXT: + if (keyboardEvent.isSystemKey()) + return false; + logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); + break; + default: + return false; + } + + return true; +} + +#if USE(CFNETWORK) +static RetainPtr<CFCachedURLResponseRef> cachedResponseForURL(WebPage* webPage, const KURL& url) +{ + RetainPtr<CFURLRef> cfURL(AdoptCF, url.createCFURL()); + RetainPtr<CFMutableURLRequestRef> request(AdoptCF, CFURLRequestCreateMutable(0, cfURL.get(), kCFURLRequestCachePolicyReloadIgnoringCache, 60, 0)); +#if USE(CFURLSTORAGESESSIONS) + wkSetRequestStorageSession(ResourceHandle::currentStorageSession(), request.get()); +#endif + + RetainPtr<CFStringRef> userAgent(AdoptCF, webPage->userAgent().createCFString()); + CFURLRequestSetHTTPHeaderFieldValue(request.get(), CFSTR("User-Agent"), userAgent.get()); + + RetainPtr<CFURLCacheRef> cache; +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef currentStorageSession = ResourceHandle::currentStorageSession()) + cache.adoptCF(wkCopyURLCache(currentStorageSession)); + else +#endif + cache.adoptCF(CFURLCacheCopySharedURLCache()); + + RetainPtr<CFCachedURLResponseRef> response(AdoptCF, CFURLCacheCopyResponseForRequest(cache.get(), request.get())); + return response; +} +#endif + +bool WebPage::platformHasLocalDataForURL(const KURL& url) +{ +#if USE(CFNETWORK) + return cachedResponseForURL(this, url); +#else + return false; +#endif +} + +String WebPage::cachedResponseMIMETypeForURL(const KURL& url) +{ +#if USE(CFNETWORK) + RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url); + CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse.get()); + return response ? CFURLResponseGetMIMEType(response) : String(); +#else + return String(); +#endif +} + +String WebPage::cachedSuggestedFilenameForURL(const KURL& url) +{ +#if USE(CFNETWORK) + RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url); + CFURLResponseRef response = CFCachedURLResponseGetWrappedResponse(cachedResponse.get()); + if (!response) + return String(); + RetainPtr<CFStringRef> suggestedFilename(AdoptCF, CFURLResponseCopySuggestedFilename(response)); + + return suggestedFilename.get(); +#else + return String(); +#endif +} + +PassRefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const KURL& url) +{ +#if USE(CFNETWORK) + RetainPtr<CFCachedURLResponseRef> cachedResponse = cachedResponseForURL(this, url); + CFDataRef data = CFCachedURLResponseGetReceiverData(cachedResponse.get()); + if (!data) + return 0; + + return SharedBuffer::wrapCFData(data); +#else + return 0; +#endif +} + +bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest& request) +{ +#if USE(CFNETWORK) + 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(); +} + +void WebPage::gestureWillBegin(const WebCore::IntPoint& point, bool& canBeginPanning) +{ + m_gestureReachedScrollingLimit = false; + + bool hitScrollbar = false; + + HitTestRequest request(HitTestRequest::ReadOnly); + for (Frame* childFrame = m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) { + ScrollView* scollView = childFrame->view(); + if (!scollView) + break; + + RenderView* renderView = childFrame->document()->renderView(); + if (!renderView) + break; + + RenderLayer* layer = renderView->layer(); + if (!layer) + break; + + HitTestResult result = scollView->windowToContents(point); + layer->hitTest(request, result); + m_gestureTargetNode = result.innerNode(); + + if (!hitScrollbar) + hitScrollbar = result.scrollbar(); + } + + if (hitScrollbar) { + canBeginPanning = false; + return; + } + + if (!m_gestureTargetNode) { + canBeginPanning = false; + return; + } + + for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) { + if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) { + canBeginPanning = true; + return; + } + } + + canBeginPanning = false; +} + +static bool scrollbarAtTopOrBottomOfDocument(Scrollbar* scrollbar) +{ + ASSERT_ARG(scrollbar, scrollbar); + return !scrollbar->currentPos() || scrollbar->currentPos() >= scrollbar->maximum(); +} + +void WebPage::gestureDidScroll(const IntSize& size) +{ + ASSERT_ARG(size, !size.isZero()); + + if (!m_gestureTargetNode || !m_gestureTargetNode->renderer() || !m_gestureTargetNode->renderer()->enclosingLayer()) + return; + + Scrollbar* verticalScrollbar = 0; + if (Frame* frame = m_page->mainFrame()) { + if (ScrollView* view = frame->view()) + verticalScrollbar = view->verticalScrollbar(); + } + + m_gestureTargetNode->renderer()->enclosingLayer()->scrollByRecursively(size.width(), size.height()); + bool gestureReachedScrollingLimit = verticalScrollbar && scrollbarAtTopOrBottomOfDocument(verticalScrollbar); + + // FIXME: We really only want to update this state if the state was updated via scrolling the main frame, + // not scrolling something in a main frame when the main frame had already reached its scrolling limit. + + if (gestureReachedScrollingLimit == m_gestureReachedScrollingLimit) + return; + + send(Messages::WebPageProxy::SetGestureReachedScrollingLimit(gestureReachedScrollingLimit)); + m_gestureReachedScrollingLimit = gestureReachedScrollingLimit; +} + +void WebPage::gestureDidEnd() +{ + m_gestureTargetNode = nullptr; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebProcess.cpp b/Source/WebKit2/WebProcess/WebProcess.cpp new file mode 100644 index 000000000..9fdca9051 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcess.cpp @@ -0,0 +1,1020 @@ +/* + * 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 "config.h" +#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 "StatisticsData.h" +#include "WebApplicationCacheManager.h" +#include "WebContextMessages.h" +#include "WebCookieManager.h" +#include "WebCoreArgumentCoders.h" +#include "WebDatabaseManager.h" +#include "WebFrame.h" +#include "WebGeolocationManagerMessages.h" +#include "WebKeyValueStorageManager.h" +#include "WebMediaCacheManager.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 "WebResourceCacheManager.h" +#include <JavaScriptCore/JSLock.h> +#include <JavaScriptCore/MemoryStatistics.h> +#include <WebCore/AXObjectCache.h> +#include <WebCore/ApplicationCacheStorage.h> +#include <WebCore/CrossOriginPreflightResultCache.h> +#include <WebCore/Font.h> +#include <WebCore/FontCache.h> +#include <WebCore/Frame.h> +#include <WebCore/GCController.h> +#include <WebCore/GlyphPageTreeNode.h> +#include <WebCore/IconDatabase.h> +#include <WebCore/JSDOMWindow.h> +#include <WebCore/Language.h> +#include <WebCore/Logging.h> +#include <WebCore/MemoryCache.h> +#include <WebCore/MemoryPressureHandler.h> +#include <WebCore/Page.h> +#include <WebCore/PageCache.h> +#include <WebCore/PageGroup.h> +#include <WebCore/ResourceHandle.h> +#include <WebCore/SchemeRegistry.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/Settings.h> +#include <WebCore/StorageTracker.h> +#include <wtf/HashCountedSet.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RandomNumber.h> + +#if !OS(WINDOWS) +#include <unistd.h> +#endif + +#if !ENABLE(PLUGIN_PROCESS) +#include "NetscapePluginModule.h" +#endif + +using namespace JSC; +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; +} + +static const double shutdownTimeout = 60; + +WebProcess::WebProcess() + : ChildProcess(shutdownTimeout) + , m_inDidClose(false) + , m_hasSetCacheModel(false) + , m_cacheModel(CacheModelDocumentViewer) +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + , m_compositingRenderServerPort(MACH_PORT_NULL) +#endif + , m_fullKeyboardAccessEnabled(false) +#if PLATFORM(QT) + , m_networkAccessManager(0) +#endif + , m_textCheckerState() + , m_geolocationManager(this) +#if ENABLE(NOTIFICATIONS) + , m_notificationManager(this) +#endif + , m_iconDatabaseProxy(this) +#if ENABLE(PLUGIN_PROCESS) + , m_disablePluginProcessMessageTimeout(false) +#endif +{ +#if USE(PLATFORM_STRATEGIES) + // Initialize our platform strategies. + WebPlatformStrategies::initialize(); +#endif // USE(PLATFORM_STRATEGIES) + + WebCore::initializeLoggingChannelsIfNecessary(); +} + +void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop) +{ + ASSERT(!m_connection); + + m_connection = WebConnectionToUIProcess::create(this, serverIdentifier, runLoop); + + m_connection->connection()->addQueueClient(&m_eventDispatcher); + m_connection->connection()->addQueueClient(this); + + m_connection->connection()->open(); + m_runLoop = runLoop; + + startRandomCrashThreadIfRequested(); +} + +void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments) +{ + ASSERT(m_pageMap.isEmpty()); + + platformInitializeWebProcess(parameters, arguments); + + memoryPressureHandler().install(); + + 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(SQL_DATABASE) + // Make sure the WebDatabaseManager is initialized so that the Database directory is set. + WebDatabaseManager::initialize(parameters.databaseDirectory); +#endif + +#if ENABLE(ICONDATABASE) + m_iconDatabaseProxy.setEnabled(parameters.iconDatabaseEnabled); +#endif + + StorageTracker::initializeTracker(parameters.localStorageDirectory, &WebKeyValueStorageManager::shared()); + m_localStorageDirectory = parameters.localStorageDirectory; + + if (!parameters.applicationCacheDirectory.isEmpty()) + cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory); + + setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks); + setCacheModel(static_cast<uint32_t>(parameters.cacheModel)); + + if (!parameters.languageCode.isEmpty()) + overrideDefaultLanguage(parameters.languageCode); + + m_textCheckerState = parameters.textCheckerState; + + m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled; + + 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]); + + setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval); + + for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i) + m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]); + +#if PLATFORM(MAC) + m_presenterApplicationPid = parameters.presenterApplicationPid; +#endif + + if (parameters.shouldAlwaysUseComplexTextCodePath) + setAlwaysUsesComplexTextCodePath(true); + + if (parameters.shouldUseFontSmoothing) + setShouldUseFontSmoothing(true); + +#if USE(CFURLSTORAGESESSIONS) + WebCore::ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier); +#endif + +#if ENABLE(PLUGIN_PROCESS) + m_disablePluginProcessMessageTimeout = parameters.disablePluginProcessMessageTimeout; +#endif +} + +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 +{ + SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme); +} + +void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval) +{ + ResourceRequest::setDefaultTimeoutInterval(timeoutInterval); +} + +void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) +{ + WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto); +} + +void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing) +{ + WebCore::Font::setShouldUseSmoothing(useFontSmoothing); +} + +void WebProcess::languageChanged(const String& language) const +{ + overrideDefaultLanguage(language); +} + +void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) +{ + m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled; +} + +void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle) +{ + RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); + if (!sharedMemory) + return; + + m_visitedLinkTable.setSharedMemory(sharedMemory.release()); +} + +void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes) +{ + // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. + for (size_t i = 0; i < linkHashes.size(); ++i) { + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end(); + for (; it != end; ++it) + Page::visitedStateChanged(PageGroup::pageGroup(it->second->identifier()), linkHashes[i]); + } + + pageCache()->markPagesForVistedLinkStyleRecalc(); +} + +void WebProcess::allVisitedLinkStateChanged() +{ + // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end(); + for (; it != end; ++it) + Page::allVisitedStateChanged(PageGroup::pageGroup(it->second->identifier())); + + pageCache()->markPagesForVistedLinkStyleRecalc(); +} + +bool WebProcess::isLinkVisited(LinkHash linkHash) const +{ + return m_visitedLinkTable.isLinkVisited(linkHash); +} + +void WebProcess::addVisitedLink(WebCore::LinkHash linkHash) +{ + if (isLinkVisited(linkHash)) + return; + 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::focusedWebPage() const +{ + HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) { + WebPage* page = (*it).second.get(); + if (page->windowIsFocused()) + return page; + } + return 0; +} + +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); + + // Balanced by an enableTermination in removeWebPage. + disableTermination(); + } + + ASSERT(result.first->second); +} + +void WebProcess::removeWebPage(uint64_t pageID) +{ + ASSERT(m_pageMap.contains(pageID)); + + m_pageMap.remove(pageID); + + enableTermination(); +} + +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(); +} + +bool WebProcess::shouldTerminate() +{ + // Keep running forever if we're running in the same process. + if (!isSeparateProcess()) + return false; + + ASSERT(m_pageMap.isEmpty()); + ASSERT(!DownloadManager::shared().isDownloading()); + + // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved. + bool shouldTerminate = false; + if (connection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0) + && !shouldTerminate) + return false; + + return true; +} + +void WebProcess::terminate() +{ +#ifndef NDEBUG + gcController().garbageCollectNow(); + memoryCache()->setDisabled(true); +#endif + + // Invalidate our connection. + m_connection->invalidate(); + m_connection = nullptr; + + platformTerminate(); + m_runLoop->stop(); +} + +void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply) +{ + uint64_t pageID = arguments->destinationID(); + if (!pageID) + return; + + WebPage* page = webPage(pageID); + if (!page) + return; + + page->didReceiveSyncMessage(connection, messageID, arguments, reply); +} + +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::MessageClassWebApplicationCacheManager>()) { + WebApplicationCacheManager::shared().didReceiveMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassWebCookieManager>()) { + WebCookieManager::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::MessageClassWebIconDatabaseProxy>()) { + m_iconDatabaseProxy.didReceiveMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManager>()) { + WebKeyValueStorageManager::shared().didReceiveMessage(connection, messageID, arguments); + return; + } + + if (messageID.is<CoreIPC::MessageClassWebMediaCacheManager>()) { + WebMediaCacheManager::shared().didReceiveMessage(connection, messageID, arguments); + return; + } + +#if ENABLE(NOTIFICATIONS) + if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) { + m_notificationManager.didReceiveMessage(connection, messageID, arguments); + return; + } +#endif + + if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) { + WebResourceCacheManager::shared().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. +} + +void WebProcess::syncMessageSendTimedOut(CoreIPC::Connection*) +{ +} + +void WebProcess::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage) +{ + if (messageID.is<CoreIPC::MessageClassWebProcess>()) { + didReceiveWebProcessMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage); + return; + } +} + +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; + + 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(); +} + +static bool canPluginHandleResponse(const ResourceResponse& response) +{ + String pluginPath; + + if (!WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPluginPath(response.mimeType(), response.url().string()), Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) + return false; + + return !pluginPath.isEmpty(); +} + +bool WebProcess::shouldUseCustomRepresentationForResponse(const ResourceResponse& response) const +{ + if (!m_mimeTypesWithCustomRepresentations.contains(response.mimeType())) + return false; + + // If a plug-in exists that claims to support this response, it should take precedence over the custom representation. + return !canPluginHandleResponse(response); +} + +void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear) +{ + platformClearResourceCaches(resourceCachesToClear); + + // 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); + + memoryCache()->evictResources(); + + // Empty the cross-origin preflight cache. + CrossOriginPreflightResultCache::shared().empty(); +} + +void WebProcess::clearApplicationCache() +{ + // Empty the application cache. + cacheStorage().empty(); +} + +#if !ENABLE(PLUGIN_PROCESS) +void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID) +{ + LocalTerminationDisabler terminationDisabler(*this); + + HashSet<String> sitesSet; + + for (size_t i = 0; i < pluginPaths.size(); ++i) { + RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); + if (!netscapePluginModule) + continue; + + Vector<String> sites = netscapePluginModule->sitesWithData(); + for (size_t i = 0; i < sites.size(); ++i) + sitesSet.add(sites[i]); + } + + Vector<String> sites; + copyToVector(sitesSet, sites); + + connection()->send(Messages::WebContext::DidGetSitesWithPluginData(sites, callbackID), 0); +} + +void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +{ + LocalTerminationDisabler terminationDisabler(*this); + + for (size_t i = 0; i < pluginPaths.size(); ++i) { + RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); + if (!netscapePluginModule) + continue; + + if (sites.isEmpty()) { + // Clear everything. + netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds); + continue; + } + + for (size_t i = 0; i < sites.size(); ++i) + netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds); + } + + connection()->send(Messages::WebContext::DidClearPluginSiteData(callbackID), 0); +} +#endif + +static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map) +{ + TypeCountSet::const_iterator end = countedSet->end(); + for (TypeCountSet::const_iterator it = countedSet->begin(); it != end; ++it) + map.set(it->first, it->second); +} + +static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t> >& result) +{ + DEFINE_STATIC_LOCAL(String, imagesString, ("Images")); + DEFINE_STATIC_LOCAL(String, cssString, ("CSS")); + DEFINE_STATIC_LOCAL(String, xslString, ("XSL")); + DEFINE_STATIC_LOCAL(String, javaScriptString, ("JavaScript")); + + MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics(); + + HashMap<String, uint64_t> counts; + counts.set(imagesString, memoryCacheStatistics.images.count); + counts.set(cssString, memoryCacheStatistics.cssStyleSheets.count); + counts.set(xslString, memoryCacheStatistics.xslStyleSheets.count); + counts.set(javaScriptString, memoryCacheStatistics.scripts.count); + result.append(counts); + + HashMap<String, uint64_t> sizes; + sizes.set(imagesString, memoryCacheStatistics.images.size); + sizes.set(cssString, memoryCacheStatistics.cssStyleSheets.size); + sizes.set(xslString, memoryCacheStatistics.xslStyleSheets.size); + sizes.set(javaScriptString, memoryCacheStatistics.scripts.size); + result.append(sizes); + + HashMap<String, uint64_t> liveSizes; + liveSizes.set(imagesString, memoryCacheStatistics.images.liveSize); + liveSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.liveSize); + liveSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.liveSize); + liveSizes.set(javaScriptString, memoryCacheStatistics.scripts.liveSize); + result.append(liveSizes); + + HashMap<String, uint64_t> decodedSizes; + decodedSizes.set(imagesString, memoryCacheStatistics.images.decodedSize); + decodedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.decodedSize); + decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize); + decodedSizes.set(javaScriptString, memoryCacheStatistics.scripts.decodedSize); + result.append(decodedSizes); + + HashMap<String, uint64_t> purgeableSizes; + purgeableSizes.set(imagesString, memoryCacheStatistics.images.purgeableSize); + purgeableSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgeableSize); + purgeableSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgeableSize); + purgeableSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgeableSize); + result.append(purgeableSizes); + + HashMap<String, uint64_t> purgedSizes; + purgedSizes.set(imagesString, memoryCacheStatistics.images.purgedSize); + purgedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgedSize); + purgedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgedSize); + purgedSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgedSize); + result.append(purgedSizes); +} + +void WebProcess::getWebCoreStatistics(uint64_t callbackID) +{ + StatisticsData data; + + // Gather JavaScript statistics. + { + JSLock lock(SilenceAssertionsOnly); + data.statisticsNumbers.set("JavaScriptObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.objectCount()); + data.statisticsNumbers.set("JavaScriptGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount()); + data.statisticsNumbers.set("JavaScriptProtectedObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount()); + data.statisticsNumbers.set("JavaScriptProtectedGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount()); + + OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts()); + fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts); + + OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts()); + fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts); + + uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size(); + data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize); + data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize); + } + + WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); + data.statisticsNumbers.set("FastMallocReservedVMBytes", fastMallocStatistics.reservedVMBytes); + data.statisticsNumbers.set("FastMallocCommittedVMBytes", fastMallocStatistics.committedVMBytes); + data.statisticsNumbers.set("FastMallocFreeListBytes", fastMallocStatistics.freeListBytes); + + // Gather icon statistics. + data.statisticsNumbers.set("IconPageURLMappingCount", iconDatabase().pageURLMappingCount()); + data.statisticsNumbers.set("IconRetainedPageURLCount", iconDatabase().retainedPageURLCount()); + data.statisticsNumbers.set("IconRecordCount", iconDatabase().iconRecordCount()); + data.statisticsNumbers.set("IconsWithDataCount", iconDatabase().iconRecordCountWithData()); + + // Gather font statistics. + data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount()); + data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount()); + + // Gather glyph page statistics. +#if !(PLATFORM(QT) && !HAVE(QRAWFONT)) // Qt doesn't use the glyph page tree currently. See: bug 63467. + data.statisticsNumbers.set("GlyphPageCount", GlyphPageTreeNode::treeGlyphPageCount()); +#endif + + // Get WebCore memory cache statistics + getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics); + + connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0); +} + +void WebProcess::garbageCollectJavaScriptObjects() +{ + gcController().garbageCollectNow(); +} + +#if ENABLE(PLUGIN_PROCESS) +void WebProcess::pluginProcessCrashed(const String& pluginPath) +{ + m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath); +} +#endif + +void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request) +{ + WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0; + + ResourceRequest requestWithOriginalURL = request; + if (initiatingPage) + initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL); + + DownloadManager::shared().startDownload(downloadID, initiatingPage, requestWithOriginalURL); +} + +void WebProcess::cancelDownload(uint64_t downloadID) +{ + DownloadManager::shared().cancelDownload(downloadID); +} + +#if PLATFORM(QT) +void WebProcess::startTransfer(uint64_t downloadID, const String& destination) +{ + DownloadManager::shared().startTransfer(downloadID, destination); +} +#endif + +void WebProcess::setEnhancedAccessibility(bool flag) +{ + WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag); +} + +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) +{ + bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled; + bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled; + + m_textCheckerState = textCheckerState; + + if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff) + return; + + HashMap<uint64_t, RefPtr<WebPage> >::iterator end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage> >::iterator it = m_pageMap.begin(); it != end; ++it) { + WebPage* page = (*it).second.get(); + if (continuousSpellCheckingTurnedOff) + page->unmarkAllMisspellings(); + if (grammarCheckingTurnedOff) + page->unmarkAllBadGrammar(); + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebProcess.h b/Source/WebKit2/WebProcess/WebProcess.h new file mode 100644 index 000000000..b6fff7f2f --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcess.h @@ -0,0 +1,279 @@ +/* + * 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 "EventDispatcher.h" +#include "ResourceCachesToClear.h" +#include "SandboxExtension.h" +#include "SharedMemory.h" +#include "TextCheckerState.h" +#include "VisitedLinkTable.h" +#include "WebConnectionToUIProcess.h" +#include "WebGeolocationManager.h" +#include "WebIconDatabaseProxy.h" +#include "WebPageGroupProxy.h" +#include <WebCore/LinkHash.h> +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> + +#if PLATFORM(QT) +class QNetworkAccessManager; +#endif + +#if ENABLE(NOTIFICATIONS) +#include "WebNotificationManager.h" +#endif + +#if ENABLE(PLUGIN_PROCESS) +#include "PluginProcessConnectionManager.h" +#endif + +namespace WebCore { + class IntSize; + class PageGroup; + class ResourceRequest; + class ResourceResponse; +} + +namespace WebKit { + +class InjectedBundle; +class WebFrame; +class WebPage; +struct WebPageCreationParameters; +struct WebPageGroupData; +struct WebPreferencesStore; +struct WebProcessCreationParameters; + +class WebProcess : public ChildProcess, private CoreIPC::Connection::QueueClient { +public: + static WebProcess& shared(); + + void initialize(CoreIPC::Connection::Identifier, RunLoop*); + + CoreIPC::Connection* connection() const { return m_connection->connection(); } + RunLoop* runLoop() const { return m_runLoop; } + + WebConnectionToUIProcess* webConnectionToUIProcess() const { return m_connection.get(); } + + WebPage* webPage(uint64_t pageID) const; + void createWebPage(uint64_t pageID, const WebPageCreationParameters&); + void removeWebPage(uint64_t pageID); + WebPage* focusedWebPage() const; + + InjectedBundle* injectedBundle() const { return m_injectedBundle.get(); } + + bool isSeparateProcess() const; + +#if PLATFORM(MAC) + void initializeShim(); + +#if USE(ACCELERATED_COMPOSITING) + mach_port_t compositingRenderServerPort() const { return m_compositingRenderServerPort; } +#endif +#endif + + void addVisitedLink(WebCore::LinkHash); + bool isLinkVisited(WebCore::LinkHash) const; + + bool fullKeyboardAccessEnabled() const { return m_fullKeyboardAccessEnabled; } + + WebFrame* webFrame(uint64_t) const; + void addWebFrame(uint64_t, WebFrame*); + void removeWebFrame(uint64_t); + + WebPageGroupProxy* webPageGroup(uint64_t pageGroupID); + WebPageGroupProxy* webPageGroup(const WebPageGroupData&); +#if PLATFORM(MAC) + pid_t presenterApplicationPid() const { return m_presenterApplicationPid; } +#endif + +#if PLATFORM(QT) + QNetworkAccessManager* networkAccessManager() { return m_networkAccessManager; } +#endif + + bool shouldUseCustomRepresentationForResponse(const WebCore::ResourceResponse&) const; + + // Text Checking + const TextCheckerState& textCheckerState() const { return m_textCheckerState; } + + // Geolocation + WebGeolocationManager& geolocationManager() { return m_geolocationManager; } + +#if ENABLE(NOTIFICATIONS) + WebNotificationManager& notificationManager() { return m_notificationManager; } +#endif + + void clearResourceCaches(ResourceCachesToClear = AllResourceCaches); + + const String& localStorageDirectory() const { return m_localStorageDirectory; } + +#if ENABLE(PLUGIN_PROCESS) + PluginProcessConnectionManager& pluginProcessConnectionManager() { return m_pluginProcessConnectionManager; } + bool disablePluginProcessMessageTimeout() const { return m_disablePluginProcessMessageTimeout; } +#endif + + EventDispatcher& eventDispatcher() { return m_eventDispatcher; } + +private: + WebProcess(); + + void initializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*); + void platformInitializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*); + void platformTerminate(); + void setShouldTrackVisitedLinks(bool); + void registerURLSchemeAsEmptyDocument(const String&); + void registerURLSchemeAsSecure(const String&) const; + void setDomainRelaxationForbiddenForURLScheme(const String&) const; + void setDefaultRequestTimeoutInterval(double); + void setAlwaysUsesComplexTextCodePath(bool); + void setShouldUseFontSmoothing(bool); + void languageChanged(const String&) const; + void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled); +#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 platformClearResourceCaches(ResourceCachesToClear); + void clearApplicationCache(); + + void setEnhancedAccessibility(bool); + +#if !ENABLE(PLUGIN_PROCESS) + void getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID); + void clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID); +#endif + +#if ENABLE(PLUGIN_PROCESS) + void pluginProcessCrashed(const String& pluginPath); +#endif + + 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); +#if PLATFORM(QT) + void startTransfer(uint64_t downloadID, const String& destination); +#endif + + void setTextCheckerState(const TextCheckerState&); + + void getWebCoreStatistics(uint64_t callbackID); + void garbageCollectJavaScriptObjects(); + + // ChildProcess + virtual bool shouldTerminate(); + virtual void terminate(); + + // CoreIPC::Connection::Client + friend class WebConnectionToUIProcess; + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); +#if PLATFORM(WIN) + virtual Vector<HWND> windowsToReceiveSentMessagesWhileWaitingForSyncReply(); +#endif + + // CoreIPC::Connection::QueueClient + virtual void didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, bool& didHandleMessage) OVERRIDE; + + // Implemented in generated WebProcessMessageReceiver.cpp + void didReceiveWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + void didReceiveWebProcessMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, bool& didHandleMessage); + + RefPtr<WebConnectionToUIProcess> m_connection; + + HashMap<uint64_t, RefPtr<WebPage> > m_pageMap; + HashMap<uint64_t, RefPtr<WebPageGroupProxy> > m_pageGroupMap; + RefPtr<InjectedBundle> m_injectedBundle; + + EventDispatcher m_eventDispatcher; + + 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 + + bool m_fullKeyboardAccessEnabled; + +#if PLATFORM(QT) + QNetworkAccessManager* m_networkAccessManager; +#endif + + HashMap<uint64_t, WebFrame*> m_frameMap; + + HashSet<String, CaseFoldingHash> m_mimeTypesWithCustomRepresentations; + + TextCheckerState m_textCheckerState; + WebGeolocationManager m_geolocationManager; +#if ENABLE(NOTIFICATIONS) + WebNotificationManager m_notificationManager; +#endif + WebIconDatabaseProxy m_iconDatabaseProxy; + + String m_localStorageDirectory; + + RefPtr<SandboxExtension> m_applicationCachePathExtension; + +#if ENABLE(PLUGIN_PROCESS) + PluginProcessConnectionManager m_pluginProcessConnectionManager; + bool m_disablePluginProcessMessageTimeout; +#endif + +}; + +} // 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 000000000..b991f44c5 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebProcess.messages.in @@ -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. + +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) + SetDefaultRequestTimeoutInterval(double timeoutInterval) + SetAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) + SetShouldUseFontSmoothing(bool useFontSmoothing) + LanguageChanged(WTF::String language) + FullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) +#if PLATFORM(WIN) + SetShouldPaintNativeControls(bool shouldPaintNativeControls) +#endif + + # Plug-ins. + +#if !ENABLE(PLUGIN_PROCESS) + GetSitesWithPluginData(Vector<WTF::String> pluginPaths, uint64_t callbackID) + ClearPluginSiteData(Vector<WTF::String> pluginPaths, Vector<WTF::String> sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +#endif + +#if ENABLE(PLUGIN_PROCESS) + PluginProcessCrashed(String pluginProcess) DispatchOnConnectionQueue +#endif + + 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. + DownloadRequest(uint64_t downloadID, uint64_t initiatingPageID, WebCore::ResourceRequest request) + CancelDownload(uint64_t downloadID) +#if PLATFORM(QT) + StartTransfer(uint64_t downloadID, WTF::String destination) +#endif + + SetTextCheckerState(WebKit::TextCheckerState textCheckerState) + + SetEnhancedAccessibility(bool flag) + + GetWebCoreStatistics(uint64_t callbackID) + GarbageCollectJavaScriptObjects() +} diff --git a/Source/WebKit2/WebProcess/WebProcessMain.h b/Source/WebKit2/WebProcess/WebProcessMain.h new file mode 100644 index 000000000..a287d6387 --- /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 000000000..80c707806 --- /dev/null +++ b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb @@ -0,0 +1,214 @@ +(version 1) +(deny default (with partial-symbolication)) +(allow ipc-posix-shm system-audit system-socket file-read-metadata) + +(import "system.sb") +(import "com.apple.corefoundation.sb") + +;; Distributed notifications, local pasteboard client +(corefoundation) + +;; Utility functions for home directory relative path filters +(define (home-regex home-relative-regex) + (regex (string-append "^" (regex-quote (param "HOME_DIR")) home-relative-regex))) + +(define (home-subpath home-relative-subpath) + (subpath (string-append (param "HOME_DIR") home-relative-subpath))) + +(define (home-literal home-relative-literal) + (literal (string-append (param "HOME_DIR") home-relative-literal))) + +;; Read-only preferences and data +(allow file-read* + ;; Basic system paths + (subpath "/Library/Dictionaries") + (subpath "/Library/Fonts") + (subpath "/Library/Frameworks") + (subpath "/private/var/db/mds") + (subpath "/private/var/db/DetachedSignatures") + (regex #"^/private/etc/(hosts|group|passwd)$") + + ;; FIXME: This should be removed when <rdar://problem/10479685> is fixed. + (subpath "/Library/Keychains") + + ;; System and user preferences + (literal "/Library/Preferences/.GlobalPreferences.plist") + (literal "/Library/Preferences/com.apple.crypto.plist") + (literal "/Library/Preferences/com.apple.security.plist") + (literal "/Library/Preferences/com.apple.security.common.plist") + (literal "/Library/Preferences/com.apple.security.revocation.plist") + (regex #"^/Library/Managed Preferences/[^/]+/com\.apple\.networkConnect\.plist$") + (home-literal "/Library/Preferences/.GlobalPreferences.plist") + (home-regex "/Library/Preferences/ByHost/\.GlobalPreferences\.") + (home-regex "/Library/Preferences/ByHost/com\.apple\.networkConnect\.") + (home-literal "/Library/Preferences/com.apple.ATS.plist") + (home-literal "/Library/Preferences/com.apple.DownloadAssessment.plist") + (home-literal "/Library/Preferences/com.apple.HIToolbox.plist") + (home-literal "/Library/Preferences/com.apple.LaunchServices.plist") + (home-literal "/Library/Preferences/com.apple.WebFoundation.plist") + (home-literal "/Library/Preferences/com.apple.security.plist") + (home-literal "/Library/Preferences/com.apple.security.revocation.plist") + (home-literal "/Library/Application Support/SyncServices/Local/ClientsWithChanges/com.apple.Keychain") + (home-regex "/Library/Preferences/com\.apple\.driver\.(AppleBluetoothMultitouch\.mouse|AppleBluetoothMultitouch\.trackpad|AppleHIDMouse)\.plist$") + + ;; On-disk WebKit2 framework location, to account for debug installations + ;; outside of /System/Library/Frameworks + (subpath (param "WEBKIT2_FRAMEWORK_DIR")) + + ;; FIXME: This should be removed when <rdar://problem/8957845> is fixed. + (home-subpath "/Library/Fonts") + + ;; FIXME: These should be removed when <rdar://problem/9217757> is fixed. + (home-subpath "/Library/Audio/Plug-Ins/Components") + (home-subpath "/Library/Preferences/QuickTime Preferences") + (home-literal "/Library/Caches/com.apple.coreaudio.components.plist") + (subpath "/Library/Audio/Plug-Ins/Components") + (subpath "/Library/Audio/Plug-Ins/HAL") + (subpath "/Library/Video/Plug-Ins") + (subpath "/Library/QuickTime") + + ;; FIXME: This should be removed when <rdar://problem/9276253> is fixed. + (home-subpath "/Library/Keyboard Layouts") + + ;; FIXME: This should be removed when <rdar://problem/9276268> is fixed. + (home-subpath "/Library/Input Methods") + + (home-subpath "/Library/Dictionaries")) + +;; This should be updated when <rdar://problem/9355830> is fixed. +;; Read-only extensions from UIProcess +(if (defined? 'extension-class) + (allow file-read* (extension "com.apple.app-sandbox.read"))) + +;; Read-write extensions from UIProcess +(allow file-read* file-write* (extension)) + +;; Writable preferences and temporary files +(allow file* + (home-subpath "/Library/Caches/com.apple.WebProcess") + (home-regex "/Library/Preferences/ByHost/com\.apple\.HIToolbox\.") + (home-regex "/Library/Preferences/com\.apple\.WebProcess\.") + + ;; FIXME: This should be removed when <rdar://problem/10479685> is fixed. + (home-subpath "/Library/Keychains")) + +;; Non-user Security mds caches +(allow file* + (subpath "/private/var/db/mds/system")) + +;; Darwin temporary files and Security mds caches, if present +(if (positive? (string-length (param "DARWIN_USER_CACHE_DIR"))) + (allow file* (subpath (string-append (param "DARWIN_USER_CACHE_DIR") "/mds")))) +(if (positive? (string-length (param "DARWIN_USER_TEMP_DIR"))) + (allow file* (subpath (param "DARWIN_USER_TEMP_DIR")))) + +;; Database directory. +(if (positive? (string-length (param "WEBKIT_DATABASE_DIR"))) + (allow file* (subpath (param "WEBKIT_DATABASE_DIR")))) + +;; LocalStorage directory. +(if (positive? (string-length (param "WEBKIT_LOCALSTORAGE_DIR"))) + (allow file* (subpath (param "WEBKIT_LOCALSTORAGE_DIR")))) + +;; ApplicationCache directory. +(if (positive? (string-length (param "WEBKIT_APPLICATION_CACHE_DIR"))) + (allow file* (subpath (param "WEBKIT_APPLICATION_CACHE_DIR")))) + +;; The Web Inspector directory. +(if (positive? (string-length (param "WEBKIT_WEB_INSPECTOR_DIR"))) + (allow file-read* (subpath (param "WEBKIT_WEB_INSPECTOR_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")))) + +;; IOKit user clients +(allow iokit-open + (iokit-connection "IOAccelerator") + (iokit-user-client-class "IOAccelerationUserClient") + (iokit-user-client-class "IOFramebufferSharedUserClient") + (iokit-user-client-class "AppleGraphicsControlClient") + (iokit-user-client-class "AppleSNBFBUserClient") + (iokit-user-client-class "AGPMClient") + (iokit-user-client-class "IOHIDParamUserClient") + (iokit-user-client-class "RootDomainUserClient") + (iokit-user-client-class "IOSurfaceRootUserClient") + (iokit-user-client-class "IOSurfaceSendRight") + (iokit-user-client-class "IOAudioControlUserClient") + (iokit-user-client-class "IOAudioEngineUserClient")) + +;; 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.SystemConfiguration.PPPController") + (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.networkd") + (global-name "com.apple.dock.server") + (global-name "com.apple.ocspd") + (global-name "com.apple.pasteboard.1") + (global-name "com.apple.system.opendirectoryd.api") + (global-name "com.apple.window_proxies") + (global-name "com.apple.windowserver.active") + (global-name "com.apple.cfnetwork.AuthBrokerAgent") + (global-name "com.apple.PowerManagement.control") + + ;; FIXME: This should be removed when <rdar://problem/9276393> is fixed. + (global-name "com.apple.metadata.mds")) + +(allow system-socket (socket-domain AF_ROUTE)) +(allow system-socket (require-all (socket-domain AF_SYSTEM) (socket-protocol 2))) ; SYSPROTO_CONTROL +(allow network-outbound + ;; Kernel controls + (control-name "com.apple.network.statistics") + (control-name "com.apple.netsrc") + + ;; Local mDNSResponder for DNS, arbitrary outbound TCP + (literal "/private/var/run/mDNSResponder") + (remote tcp)) + +;; FIXME: Once <rdar://problem/8900275> has been fixed, these rules can be removed. +(allow mach-lookup (global-name "com.apple.pubsub.ipc")) +(allow network-outbound (regex #"^/private/tmp/launch-[^/]+/Render")) +(allow file-read* + (home-literal "/Library/Preferences/com.apple.Safari.RSS.plist") + (home-literal "/Library/Preferences/com.apple.Syndication.plist")) + +;; FIXME should be removed when <rdar://problem/9347205> + related radar in Safari is fixed +(allow mach-lookup + (global-name "org.h5l.kcm") + (global-name "com.apple.system.logger") + (global-name "com.apple.system.notification_center")) +(allow network-outbound + (remote udp)) +(allow file-read* + (literal (string-append (param "HOME_DIR") "/Library/Preferences/com.apple.Kerberos.plist")) + (literal (string-append (param "HOME_DIR") "/Library/Preferences/com.apple.GSS.plist")) + (literal (string-append (param "HOME_DIR") "/Library/Preferences/edu.mit.Kerberos")) + (literal "/Library/Preferences/com.apple.Kerberos.plist") + (literal "/Library/Preferences/com.apple.GSS.plist") + (literal "/Library/Preferences/edu.mit.Kerberos") + (literal "/private/etc/krb5.conf") + (literal "/private/etc/services") + (literal "/private/etc/host")) + +(deny file-read* file-write* (with no-log) + ;; FIXME: Should be removed after <rdar://problem/9422957> is fixed. + (home-literal "/Library/Caches/Cache.db") + + ;; FIXME: Should be removed after <rdar://problem/10463881> is fixed. + (home-literal "/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2") + (home-literal "/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2-journal")) diff --git a/Source/WebKit2/WebProcess/efl/WebProcessEfl.cpp b/Source/WebKit2/WebProcess/efl/WebProcessEfl.cpp new file mode 100644 index 000000000..ce6926fb4 --- /dev/null +++ b/Source/WebKit2/WebProcess/efl/WebProcessEfl.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY MOTOROLA INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcess.h" + +#include "WebProcessCreationParameters.h" +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +void WebProcess::platformSetCacheModel(CacheModel) +{ + notImplemented(); +} + +void WebProcess::platformClearResourceCaches(ResourceCachesToClear) +{ + notImplemented(); +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*) +{ + notImplemented(); +} + +void WebProcess::platformTerminate() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp b/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp new file mode 100644 index 000000000..f8b3cd240 --- /dev/null +++ b/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessMainEfl.h" + +#include "WKBase.h" +#include <Ecore.h> +#include <WebCore/ResourceHandle.h> +#include <WebKit2/RunLoop.h> +#include <WebKit2/WebProcess.h> +#include <runtime/InitializeThreading.h> +#include <unistd.h> +#include <wtf/MainThread.h> + +namespace WebKit { + +WK_EXPORT int WebProcessMainEfl(int argc, char* argv[]) +{ + // WebProcess should be launched with an option. + if (argc != 2) + return 1; + + if (!eina_init()) + return 1; + + if (!ecore_init()) { + // Could not init ecore. + eina_shutdown(); + return 1; + } + +#if ENABLE(GLIB_SUPPORT) + g_type_init(); +#endif + + JSC::initializeThreading(); + WTF::initializeMainThread(); + + RunLoop::initializeMainRunLoop(); + +#if USE(SOUP) + SoupSession* session = WebCore::ResourceHandle::defaultSession(); + const char* httpProxy = g_getenv("http_proxy"); + if (httpProxy) { + SoupURI* proxyUri = soup_uri_new(httpProxy); + g_object_set(session, SOUP_SESSION_PROXY_URI, proxyUri, NULL); + soup_uri_free(proxyUri); + } + + soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER); + soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER); +#endif + + int socket = atoi(argv[1]); + WebProcess::shared().initialize(socket, RunLoop::main()); + RunLoop::run(); + + return 0; + +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.h b/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.h new file mode 100644 index 000000000..34d474344 --- /dev/null +++ b/Source/WebKit2/WebProcess/efl/WebProcessMainEfl.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebProcessMainEfl_h +#define WebProcessMainEfl_h + +#include <WebKit2/WKBase.h> + +namespace WebKit { + +#ifdef __cplusplus +extern "C" { +WK_EXPORT int WebProcessMainEfl(int argc, char* argv[]); +} // extern "C" +#endif // __cplusplus + +} // namespace WebKit + +#endif // WebProcessMainEfl_h diff --git a/Source/WebKit2/WebProcess/gtk/WebAuthDialog.cpp b/Source/WebKit2/WebProcess/gtk/WebAuthDialog.cpp new file mode 100644 index 000000000..f3c3eab9c --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebAuthDialog.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * 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 "WebAuthDialog.h" + +#include <WebCore/GtkAuthenticationDialog.h> + +typedef struct { + GObject parent; +} WebAuthDialog; + +typedef struct { + GObjectClass parent; +} WebAuthDialogClass; + +static void webAuthDialogSessionFeatureInit(SoupSessionFeatureInterface*, gpointer); + +G_DEFINE_TYPE_WITH_CODE(WebAuthDialog, web_auth_dialog, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(SOUP_TYPE_SESSION_FEATURE, + webAuthDialogSessionFeatureInit)) + +static void web_auth_dialog_class_init(WebAuthDialogClass*) +{ +} + +static void web_auth_dialog_init(WebAuthDialog*) +{ +} + +static void sessionAuthenticate(SoupSession* session, SoupMessage* message, SoupAuth* auth, gboolean, gpointer) +{ + WebCore::GtkAuthenticationDialog* authDialog = new WebCore::GtkAuthenticationDialog(0, session, message, auth); + authDialog->show(); +} + +static void attach(SoupSessionFeature*, SoupSession* session) +{ + g_signal_connect(session, "authenticate", G_CALLBACK(sessionAuthenticate), 0); +} + +static void detach(SoupSessionFeature*, SoupSession* session) +{ + g_signal_handlers_disconnect_by_func(session, reinterpret_cast<gpointer>(sessionAuthenticate), 0); +} + +static void webAuthDialogSessionFeatureInit(SoupSessionFeatureInterface* feature, gpointer) +{ + feature->attach = attach; + feature->detach = detach; +} diff --git a/Source/WebKit2/WebProcess/gtk/WebAuthDialog.h b/Source/WebKit2/WebProcess/gtk/WebAuthDialog.h new file mode 100644 index 000000000..9eafea10c --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebAuthDialog.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * 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 WebAuthDialog_h +#define WebAuthDialog_h + +#include <glib-object.h> + +#define WEB_TYPE_AUTH_DIALOG (web_auth_dialog_get_type()) + +GType web_auth_dialog_get_type(); + +#endif // WebAuthDialog_h diff --git a/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp b/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp new file mode 100644 index 000000000..f4566d3cb --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebProcessGtk.cpp @@ -0,0 +1,124 @@ +/* + * 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 "config.h" +#include "WebProcess.h" + +#define LIBSOUP_USE_UNSTABLE_REQUEST_API + +#include "WebProcessCreationParameters.h" +#include <WebCore/FileSystem.h> +#include <WebCore/MemoryCache.h> +#include <WebCore/NotImplemented.h> +#include <WebCore/PageCache.h> +#include <WebCore/ResourceHandle.h> +#include <libsoup/soup-cache.h> +#include <wtf/gobject/GOwnPtr.h> +#include <wtf/gobject/GRefPtr.h> + +#if !OS(WINDOWS) +#include <unistd.h> +#endif + +namespace WebKit { + +static uint64_t getCacheDiskFreeSize(SoupCache* cache) +{ + if (!cache) + return 0; + + GOwnPtr<char> cacheDir; + g_object_get(G_OBJECT(cache), "cache-dir", &cacheDir.outPtr(), NULL); + if (!cacheDir) + return 0; + + return WebCore::getVolumeFreeSizeForPath(cacheDir.get()); +} + +static uint64_t getMemorySize() +{ + static uint64_t kDefaultMemorySize = 512; +#if !OS(WINDOWS) + long pageSize = sysconf(_SC_PAGESIZE); + if (pageSize == -1) + return kDefaultMemorySize; + + long physPages = sysconf(_SC_PHYS_PAGES); + if (physPages == -1) + return kDefaultMemorySize; + + return ((pageSize / 1024) * physPages) / 1024; +#else + // Fallback to default for other platforms. + return kDefaultMemorySize; +#endif +} + +void WebProcess::platformSetCacheModel(CacheModel cacheModel) +{ + unsigned cacheTotalCapacity = 0; + unsigned cacheMinDeadCapacity = 0; + unsigned cacheMaxDeadCapacity = 0; + double deadDecodedDataDeletionInterval = 0; + unsigned pageCacheCapacity = 0; + + unsigned long urlCacheMemoryCapacity = 0; + unsigned long urlCacheDiskCapacity = 0; + + SoupSession* session = WebCore::ResourceHandle::defaultSession(); + SoupCache* cache = reinterpret_cast<SoupCache*>(soup_session_get_feature(session, SOUP_TYPE_CACHE)); + uint64_t diskFreeSize = getCacheDiskFreeSize(cache); + + uint64_t memSize = getMemorySize(); + calculateCacheSizes(cacheModel, memSize, diskFreeSize, + cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, + pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity); + + WebCore::memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); + WebCore::memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); + WebCore::pageCache()->setCapacity(pageCacheCapacity); + + if (cache) { + if (urlCacheDiskCapacity > soup_cache_get_max_size(cache)) + soup_cache_set_max_size(cache, urlCacheDiskCapacity); + } +} + +void WebProcess::platformClearResourceCaches(ResourceCachesToClear) +{ + notImplemented(); +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters&, CoreIPC::ArgumentDecoder*) +{ + notImplemented(); +} + +void WebProcess::platformTerminate() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp b/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp new file mode 100644 index 000000000..fb9698eda --- /dev/null +++ b/Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp @@ -0,0 +1,72 @@ +/* + * 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 "config.h" +#include "WebProcessMainGtk.h" + +#include "WebAuthDialog.h" +#include "WKBase.h" +#include <WebCore/GtkAuthenticationDialog.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/MainThread.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(); + SoupSession* session = WebCore::ResourceHandle::defaultSession(); + + soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER); + soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER); + soup_session_add_feature_by_type(session, WEB_TYPE_AUTH_DIALOG); + + 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 000000000..828af830e --- /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/CoreIPCClientRunLoop.h b/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.h new file mode 100644 index 000000000..28f3f4797 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +namespace WebKit { + +typedef void (*FunctionWithContext)(void* context); + +// Call the function on a thread where it's safe to send a synchronous CoreIPC message. +// We can't use WTF's callOnMainThreadAndWait because it doesn't support enough run loop modes. +void callOnCoreIPCClientRunLoopAndWait(FunctionWithContext, void* context); + +} diff --git a/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.mm b/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.mm new file mode 100644 index 000000000..cb50465f9 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/CoreIPCClientRunLoop.mm @@ -0,0 +1,80 @@ +/* + * 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 "config.h" +#import "CoreIPCClientRunLoop.h" + +#import <WebCore/ResourceHandle.h> +#import <wtf/RetainPtr.h> + +using namespace WebCore; + +@interface WKFunctionAdapter : NSObject +{ +@public + WebKit::FunctionWithContext function; + void* context; +} +- (void)perform; +@end + +@implementation WKFunctionAdapter + +- (void)perform +{ + function(context); +} + +@end + +namespace WebKit { + +static CFArrayRef createCoreIPCRunLoopModesArray() +{ + // Ideally we'd like to list all modes here that might be used for run loops while we are handling networking. + // We have to explicitly include the run loop mode used for synchronous loads in WebCore so we don't get deadlock + // when those loads call security functions that are shimmed. + const void* values[2] = { kCFRunLoopCommonModes, ResourceHandle::synchronousLoadRunLoopMode() }; + return CFArrayCreate(0, values, 2, &kCFTypeArrayCallBacks); +} + +static NSArray *coreIPCRunLoopModesArray() +{ + static CFArrayRef modes = createCoreIPCRunLoopModesArray(); + return (NSArray *)modes; +} + +void callOnCoreIPCClientRunLoopAndWait(FunctionWithContext function, void* context) +{ + // FIXME: It would fit better with WebKit2 coding style to use a WTF Function here. + // To do that we'd need to make dispatch have an overload that takes an array of run loop modes or find some + // other way to specify that we want to include the synchronous load run loop mode. + RetainPtr<WKFunctionAdapter> adapter(AdoptNS, [[WKFunctionAdapter alloc] init]); + adapter->function = function; + adapter->context = context; + [adapter.get() performSelectorOnMainThread:@selector(perform) withObject:nil waitUntilDone:YES modes:coreIPCRunLoopModesArray()]; +} + +} diff --git a/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h new file mode 100644 index 000000000..ae80130ad --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.h @@ -0,0 +1,35 @@ +/* + * 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 KeychainItemShimMethods_h +#define KeychainItemShimMethods_h + +namespace WebKit { + +void initializeKeychainItemShim(); + +} + +#endif // KeychainItemShimMethods_h diff --git a/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm new file mode 100644 index 000000000..0f1ac9317 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/KeychainItemShimMethods.mm @@ -0,0 +1,308 @@ +/* + * 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 "config.h" +#import "KeychainItemShimMethods.h" + +#if defined(BUILDING_ON_SNOW_LEOPARD) + +#import "CoreIPCClientRunLoop.h" +#import "SecKeychainItemRequestData.h" +#import "SecKeychainItemResponseData.h" +#import "WebProcess.h" +#import "WebProcessProxyMessages.h" +#import "WebProcessShim.h" +#import <dlfcn.h> +#import <wtf/MainThread.h> + +namespace WebKit { + +// Methods to allow the shim to manage memory for its own AttributeList contents. +static HashSet<SecKeychainAttributeList*>& shimManagedAttributeLists() +{ + DEFINE_STATIC_LOCAL(HashSet<SecKeychainAttributeList*>, set, ()); + return set; +} + +static void freeAttributeListContents(SecKeychainAttributeList* attrList) +{ + ASSERT(shimManagedAttributeLists().contains(attrList)); + ASSERT(attrList); + + for (size_t i = 0; i < attrList->count; ++i) + free(attrList->attr[i].data); + + shimManagedAttributeLists().remove(attrList); +} + +static void allocateAttributeListContents(const Vector<KeychainAttribute>& attributes, SecKeychainAttributeList* attrList) +{ + ASSERT(isMainThread()); + + if (!attrList) + return; + + ASSERT(!shimManagedAttributeLists().contains(attrList)); + ASSERT(attributes.size() == attrList->count); + + shimManagedAttributeLists().add(attrList); + + for (size_t i = 0; i < attrList->count; ++i) { + ASSERT(attributes[i].tag == attrList->attr[i].tag); + + CFDataRef cfData = attributes[i].data.get(); + if (!cfData) { + attrList->attr[i].length = 0; + attrList->attr[i].data = 0; + continue; + } + + CFIndex length = CFDataGetLength(cfData); + attrList->attr[i].length = length; + attrList->attr[i].data = malloc(length); + CFDataGetBytes(cfData, CFRangeMake(0, length), static_cast<UInt8*>(attrList->attr[i].data)); + } +} + +// Methods to allow the shim to manage memory for its own KeychainItem content data. +static HashSet<void*>& shimManagedKeychainItemContents() +{ + DEFINE_STATIC_LOCAL(HashSet<void*>, set, ()); + return set; +} + +static void allocateKeychainItemContentData(CFDataRef cfData, UInt32* length, void** data) +{ + ASSERT(isMainThread()); + ASSERT((length && data) || (!length && !data)); + if (!data) + return; + + if (!cfData) { + *data = 0; + *length = 0; + return; + } + + *length = CFDataGetLength(cfData); + *data = malloc(*length); + CFDataGetBytes(cfData, CFRangeMake(0, *length), (UInt8*)*data); + shimManagedKeychainItemContents().add(*data); +} + +// FIXME (https://bugs.webkit.org/show_bug.cgi?id=60975) - Once CoreIPC supports sync messaging from a secondary thread, +// we can remove FreeAttributeListContext, FreeKeychainItemDataContext, KeychainItemAPIContext, and these 5 main-thread methods, +// and we can have the shim methods call out directly from whatever thread they're called on. + +struct FreeAttributeListContext { + SecKeychainAttributeList* attrList; + bool freed; +}; + +static void webFreeAttributeListContentOnMainThread(void* voidContext) +{ + FreeAttributeListContext* context = (FreeAttributeListContext*)voidContext; + + if (!shimManagedAttributeLists().contains(context->attrList)) { + context->freed = false; + return; + } + + freeAttributeListContents(context->attrList); + context->freed = true; +} + +static bool webFreeAttributeListContent(SecKeychainAttributeList* attrList) +{ + FreeAttributeListContext context; + context.attrList = attrList; + + callOnCoreIPCClientRunLoopAndWait(webFreeAttributeListContentOnMainThread, &context); + + return context.freed; +} + +struct FreeKeychainItemDataContext { + void* data; + bool freed; +}; + +static void webFreeKeychainItemContentOnMainThread(void* voidContext) +{ + FreeKeychainItemDataContext* context = (FreeKeychainItemDataContext*)voidContext; + + if (!shimManagedKeychainItemContents().contains(context->data)) { + context->freed = false; + return; + } + + shimManagedKeychainItemContents().remove(context->data); + free(context->data); + context->freed = true; +} + +static bool webFreeKeychainItemContent(void* data) +{ + FreeKeychainItemDataContext context; + context.data = data; + + callOnCoreIPCClientRunLoopAndWait(webFreeKeychainItemContentOnMainThread, &context); + + return context.freed; +} + +struct SecKeychainItemContext { + SecKeychainItemRef item; + + SecKeychainAttributeList* attributeList; + SecItemClass initialItemClass; + UInt32 length; + const void* data; + + SecItemClass* resultItemClass; + UInt32* resultLength; + void** resultData; + + OSStatus resultCode; +}; + +static void webSecKeychainItemCopyContentOnMainThread(void* voidContext) +{ + SecKeychainItemContext* context = (SecKeychainItemContext*)voidContext; + + SecKeychainItemRequestData requestData(context->item, context->attributeList); + SecKeychainItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecKeychainItemCopyContent(requestData), Messages::WebProcessProxy::SecKeychainItemCopyContent::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + allocateAttributeListContents(response.attributes(), context->attributeList); + allocateKeychainItemContentData(response.data(), context->resultLength, context->resultData); + if (context->resultItemClass) + *context->resultItemClass = response.itemClass(); + context->resultCode = response.resultCode(); +} + +static OSStatus webSecKeychainItemCopyContent(SecKeychainItemRef item, SecItemClass* itemClass, SecKeychainAttributeList* attrList, UInt32* length, void** outData) +{ + SecKeychainItemContext context; + memset(&context, 0, sizeof(SecKeychainItemContext)); + context.item = item; + context.resultItemClass = itemClass; + context.attributeList = attrList; + context.resultLength = length; + context.resultData = outData; + + callOnCoreIPCClientRunLoopAndWait(webSecKeychainItemCopyContentOnMainThread, &context); + + // FIXME: should return context.resultCode. Returning noErr is a workaround for <rdar://problem/9520886>; + // the authentication should fail anyway, since on error no data will be returned. + return noErr; +} + +static void webSecKeychainItemCreateFromContentOnMainThread(void* voidContext) +{ + SecKeychainItemContext* context = (SecKeychainItemContext*)voidContext; + + SecKeychainItemRequestData requestData(context->initialItemClass, context->attributeList, context->length, context->data); + SecKeychainItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecKeychainItemCreateFromContent(requestData), Messages::WebProcessProxy::SecKeychainItemCreateFromContent::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + if (response.keychainItem()) + CFRetain(response.keychainItem()); + context->item = response.keychainItem(); + context->resultCode = response.resultCode(); +} + +static OSStatus webSecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList* attrList, UInt32 length, const void* data, SecKeychainItemRef *item) +{ + SecKeychainItemContext context; + memset(&context, 0, sizeof(SecKeychainItemContext)); + context.initialItemClass = itemClass; + context.attributeList = attrList; + context.length = length; + context.data = data; + + callOnCoreIPCClientRunLoopAndWait(webSecKeychainItemCreateFromContentOnMainThread, &context); + + if (item) + *item = context.item; + else + CFRelease(context.item); + + return context.resultCode; +} + +static void webSecKeychainItemModifyContentOnMainThread(void* voidContext) +{ + SecKeychainItemContext* context = (SecKeychainItemContext*)voidContext; + + SecKeychainItemRequestData requestData(context->item, context->attributeList, context->length, context->data); + SecKeychainItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecKeychainItemModifyContent(requestData), Messages::WebProcessProxy::SecKeychainItemModifyContent::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + context->resultCode = response.resultCode(); +} + +static OSStatus webSecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList* attrList, UInt32 length, const void* data) +{ + SecKeychainItemContext context; + context.item = itemRef; + context.attributeList = (SecKeychainAttributeList*)attrList; + context.length = length; + context.data = data; + + callOnCoreIPCClientRunLoopAndWait(webSecKeychainItemModifyContentOnMainThread, &context); + + return context.resultCode; +} + +void initializeKeychainItemShim() +{ + const WebProcessKeychainItemShimCallbacks callbacks = { + webSecKeychainItemCopyContent, + webSecKeychainItemCreateFromContent, + webSecKeychainItemModifyContent, + webFreeAttributeListContent, + webFreeKeychainItemContent + }; + + WebProcessKeychainItemShimInitializeFunc initializeFunction = reinterpret_cast<WebProcessKeychainItemShimInitializeFunc>(dlsym(RTLD_DEFAULT, "WebKitWebProcessKeychainItemShimInitialize")); + initializeFunction(callbacks); +} + +} // namespace WebKit + +#endif // defined(BUILDING_ON_SNOW_LEOPARD) diff --git a/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h new file mode 100644 index 000000000..9d67ed982 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.h @@ -0,0 +1,35 @@ +/* + * 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 SecItemShimMethods_h +#define SecItemShimMethods_h + +namespace WebKit { + +void initializeSecItemShim(); + +} + +#endif // SecItemShimMethods_h diff --git a/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm new file mode 100644 index 000000000..5b2b75ce8 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/SecItemShimMethods.mm @@ -0,0 +1,175 @@ +/* + * 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 "config.h" +#import "SecItemShimMethods.h" + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + +#import "CoreIPCClientRunLoop.h" +#import "SecItemRequestData.h" +#import "SecItemResponseData.h" +#import "WebProcess.h" +#import "WebProcessProxyMessages.h" +#import "WebProcessShim.h" +#import <Security/SecItem.h> +#import <dlfcn.h> + +namespace WebKit { + +// FIXME (https://bugs.webkit.org/show_bug.cgi?id=60975) - Once CoreIPC supports sync messaging from a secondary thread, +// we can remove SecItemAPIContext and these 4 main-thread methods, and we can have the shim methods call out directly +// from whatever thread they're on. + +struct SecItemAPIContext { + CFDictionaryRef query; + CFDictionaryRef attributesToUpdate; + CFTypeRef resultObject; + OSStatus resultCode; +}; + +static void webSecItemCopyMatchingMainThread(void* voidContext) +{ + SecItemAPIContext* context = (SecItemAPIContext*)voidContext; + + SecItemRequestData requestData(context->query); + SecItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemCopyMatching(requestData), Messages::WebProcessProxy::SecItemCopyMatching::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + context->resultObject = response.resultObject().leakRef(); + context->resultCode = response.resultCode(); +} + +static OSStatus webSecItemCopyMatching(CFDictionaryRef query, CFTypeRef* result) +{ + SecItemAPIContext context; + context.query = query; + + callOnCoreIPCClientRunLoopAndWait(webSecItemCopyMatchingMainThread, &context); + + if (result) + *result = context.resultObject; + return context.resultCode; +} + +static void webSecItemAddOnMainThread(void* voidContext) +{ + SecItemAPIContext* context = (SecItemAPIContext*)voidContext; + + SecItemRequestData requestData(context->query); + SecItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemAdd(requestData), Messages::WebProcessProxy::SecItemAdd::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + context->resultObject = response.resultObject().leakRef(); + context->resultCode = response.resultCode(); +} + +static OSStatus webSecItemAdd(CFDictionaryRef query, CFTypeRef* result) +{ + SecItemAPIContext context; + context.query = query; + + callOnCoreIPCClientRunLoopAndWait(webSecItemAddOnMainThread, &context); + + if (result) + *result = context.resultObject; + return context.resultCode; +} + +static void webSecItemUpdateOnMainThread(void* voidContext) +{ + SecItemAPIContext* context = (SecItemAPIContext*)voidContext; + + SecItemRequestData requestData(context->query, context->attributesToUpdate); + SecItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemUpdate(requestData), Messages::WebProcessProxy::SecItemUpdate::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + context->resultCode = response.resultCode(); +} + +static OSStatus webSecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) +{ + SecItemAPIContext context; + context.query = query; + context.attributesToUpdate = attributesToUpdate; + + callOnCoreIPCClientRunLoopAndWait(webSecItemUpdateOnMainThread, &context); + + return context.resultCode; +} + +static void webSecItemDeleteOnMainThread(void* voidContext) +{ + SecItemAPIContext* context = (SecItemAPIContext*)voidContext; + + SecItemRequestData requestData(context->query); + SecItemResponseData response; + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::SecItemDelete(requestData), Messages::WebProcessProxy::SecItemDelete::Reply(response), 0)) { + context->resultCode = errSecInteractionNotAllowed; + ASSERT_NOT_REACHED(); + return; + } + + context->resultCode = response.resultCode(); +} + +static OSStatus webSecItemDelete(CFDictionaryRef query) +{ + SecItemAPIContext context; + context.query = query; + + callOnCoreIPCClientRunLoopAndWait(webSecItemDeleteOnMainThread, &context); + + return context.resultCode; +} + +void initializeSecItemShim() +{ + const WebProcessSecItemShimCallbacks callbacks = { + webSecItemCopyMatching, + webSecItemAdd, + webSecItemUpdate, + webSecItemDelete + }; + + WebProcessSecItemShimInitializeFunc func = reinterpret_cast<WebProcessSecItemShimInitializeFunc>(dlsym(RTLD_DEFAULT, "WebKitWebProcessSecItemShimInitialize")); + func(callbacks); +} + +} // namespace WebKit + +#endif // !BUILDING_ON_SNOW_LEOPARD diff --git a/Source/WebKit2/WebProcess/mac/WebKit.icns b/Source/WebKit2/WebProcess/mac/WebKit.icns Binary files differnew file mode 100644 index 000000000..7a09fd3f9 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebKit.icns diff --git a/Source/WebKit2/WebProcess/mac/WebProcessMac.mm b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm new file mode 100644 index 000000000..e96ab4834 --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm @@ -0,0 +1,275 @@ +/* + * 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 "config.h" +#import "WebProcess.h" + +#import "SandboxExtension.h" +#import "WKFullKeyboardAccessWatcher.h" +#import "WebInspector.h" +#import "WebPage.h" +#import "WebProcessCreationParameters.h" +#import "WebProcessProxyMessages.h" +#import <WebCore/FileSystem.h> +#import <WebCore/LocalizedStrings.h> +#import <WebCore/MemoryCache.h> +#import <WebCore/PageCache.h> +#import <WebKitSystemInterface.h> +#import <algorithm> +#import <dispatch/dispatch.h> +#import <mach/host_info.h> +#import <mach/mach.h> +#import <mach/mach_error.h> +#import <objc/runtime.h> +#import <stdio.h> + +#if defined(BUILDING_ON_SNOW_LEOPARD) +#import "KeychainItemShimMethods.h" +#else +#import "SecItemShimMethods.h" +#endif + +#if ENABLE(WEB_PROCESS_SANDBOX) +#import <stdlib.h> +#import <sysexits.h> + +// We have to #undef __APPLE_API_PRIVATE to prevent sandbox.h from looking for a header file that does not exist (<rdar://problem/9679211>). +#undef __APPLE_API_PRIVATE +#import <sandbox.h> + +#define SANDBOX_NAMED_EXTERNAL 0x0003 +extern "C" int sandbox_init_with_parameters(const char *profile, uint64_t flags, const char *const parameters[], char **errorbuf); + +#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 = 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(ResourceCachesToClear cachesToClear) +{ + if (cachesToClear == InMemoryResourceCachesOnly) + return; + [[NSURLCache sharedURLCache] removeAllCachedResponses]; +} + +#if ENABLE(WEB_PROCESS_SANDBOX) +static void appendSandboxParameterPathInternal(Vector<const char*>& vector, const char* name, const char* path) +{ + char normalizedPath[PATH_MAX]; + if (!realpath(path, normalizedPath)) + normalizedPath[0] = '\0'; + + vector.append(name); + vector.append(fastStrDup(normalizedPath)); +} + +static void appendReadwriteConfDirectory(Vector<const char*>& vector, const char* name, int confID) +{ + char path[PATH_MAX]; + if (confstr(confID, path, PATH_MAX) <= 0) + path[0] = '\0'; + + appendSandboxParameterPathInternal(vector, name, path); +} + +static void appendReadonlySandboxDirectory(Vector<const char*>& vector, const char* name, NSString *path) +{ + appendSandboxParameterPathInternal(vector, name, [path length] ? [(NSString *)path fileSystemRepresentation] : ""); +} + +static void appendReadwriteSandboxDirectory(Vector<const char*>& vector, const char* name, NSString *path) +{ + NSError *error = nil; + + // This is very unlikely to fail, but in case it actually happens, we'd like some sort of output in the console. + if (![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) + NSLog(@"could not create \"%@\", error %@", path, error); + + appendSandboxParameterPathInternal(vector, name, [(NSString *)path fileSystemRepresentation]); +} + +#endif + +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; + } + + Vector<const char*> sandboxParameters; + + // These are read-only. + appendReadonlySandboxDirectory(sandboxParameters, "WEBKIT2_FRAMEWORK_DIR", [[[NSBundle bundleForClass:NSClassFromString(@"WKView")] bundlePath] stringByDeletingLastPathComponent]); + appendReadonlySandboxDirectory(sandboxParameters, "UI_PROCESS_BUNDLE_RESOURCE_DIR", parameters.uiProcessBundleResourcePath); + appendReadonlySandboxDirectory(sandboxParameters, "WEBKIT_WEB_INSPECTOR_DIR", parameters.webInspectorBaseDirectory); + + // These are read-write getconf paths. + appendReadwriteConfDirectory(sandboxParameters, "DARWIN_USER_TEMP_DIR", _CS_DARWIN_USER_TEMP_DIR); + appendReadwriteConfDirectory(sandboxParameters, "DARWIN_USER_CACHE_DIR", _CS_DARWIN_USER_CACHE_DIR); + + // These are read-write paths. + appendReadwriteSandboxDirectory(sandboxParameters, "HOME_DIR", NSHomeDirectory()); + appendReadwriteSandboxDirectory(sandboxParameters, "WEBKIT_DATABASE_DIR", parameters.databaseDirectory); + appendReadwriteSandboxDirectory(sandboxParameters, "WEBKIT_LOCALSTORAGE_DIR", parameters.localStorageDirectory); + appendReadwriteSandboxDirectory(sandboxParameters, "WEBKIT_APPLICATION_CACHE_DIR", parameters.applicationCacheDirectory); + appendReadwriteSandboxDirectory(sandboxParameters, "NSURL_CACHE_DIR", parameters.nsURLCachePath); + + sandboxParameters.append(static_cast<const char*>(0)); + + const char* profilePath = [[[NSBundle mainBundle] pathForResource:@"com.apple.WebProcess" ofType:@"sb"] fileSystemRepresentation]; + + char* errorBuf; + if (sandbox_init_with_parameters(profilePath, SANDBOX_NAMED_EXTERNAL, sandboxParameters.data(), &errorBuf)) { + fprintf(stderr, "WebProcess: couldn't initialize sandbox profile [%s]\n", profilePath); + for (size_t i = 0; sandboxParameters[i]; i += 2) + fprintf(stderr, "%s=%s\n", sandboxParameters[i], sandboxParameters[i + 1]); + exit(EX_NOPERM); + } + + for (size_t i = 0; sandboxParameters[i]; i += 2) + fastFree(const_cast<char*>(sandboxParameters[i + 1])); + + // This will override LSFileQuarantineEnabled from Info.plist unless sandbox quarantine is globally disabled. + OSStatus error = WKEnableSandboxStyleFileQuarantine(); + if (error) { + fprintf(stderr, "WebProcess: couldn't enable sandbox style file quarantine: %ld\n", (long)error); + exit(EX_NOPERM); + } +#endif +} + +static id NSApplicationAccessibilityFocusedUIElement(NSApplication*, SEL) +{ + WebPage* page = WebProcess::shared().focusedWebPage(); + if (!page || !page->accessibilityRemoteObject()) + return 0; + + return [page->accessibilityRemoteObject() accessibilityFocusedUIElement]; +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*) +{ + [[NSFileManager defaultManager] changeCurrentDirectoryPath:[[NSBundle mainBundle] bundlePath]]; + + initializeSandbox(parameters); + + if (!parameters.parentProcessName.isNull()) { + NSString *applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Web Content", "Visible name of the web process. The argument is the application name."), (NSString *)parameters.parentProcessName]; + WKSetVisibleApplicationName((CFStringRef)applicationName); + } + + if (!parameters.nsURLCachePath.isNull()) { + NSUInteger cacheMemoryCapacity = parameters.nsURLCacheMemoryCapacity; + NSUInteger cacheDiskCapacity = parameters.nsURLCacheDiskCapacity; + + RetainPtr<NSURLCache> parentProcessURLCache(AdoptNS, [[NSURLCache alloc] initWithMemoryCapacity:cacheMemoryCapacity diskCapacity:cacheDiskCapacity diskPath:parameters.nsURLCachePath]); + [NSURLCache setSharedURLCache:parentProcessURLCache.get()]; + } + + WebInspector::setLocalizedStringsPath(parameters.webInspectorLocalizedStringsPath); + + m_compositingRenderServerPort = parameters.acceleratedCompositingPort.port(); + + // rdar://9118639 accessibilityFocusedUIElement in NSApplication defaults to use the keyWindow. Since there's + // no window in WK2, NSApplication needs to use the focused page's focused element. + Method methodToPatch = class_getInstanceMethod([NSApplication class], @selector(accessibilityFocusedUIElement)); + method_setImplementation(methodToPatch, (IMP)NSApplicationAccessibilityFocusedUIElement); +} + +void WebProcess::initializeShim() +{ +#if defined(BUILDING_ON_SNOW_LEOPARD) + initializeKeychainItemShim(); +#else + initializeSecItemShim(); +#endif +} + +void WebProcess::platformTerminate() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/mac/WebProcessMainMac.mm b/Source/WebKit2/WebProcess/mac/WebProcessMainMac.mm new file mode 100644 index 000000000..b5a3fe07d --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebProcessMainMac.mm @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2010, 2011, 2012 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 "config.h" +#import "WebProcessMain.h" + +#import "CommandLine.h" +#import "EnvironmentUtilities.h" +#import "EnvironmentVariables.h" +#import "RunLoop.h" +#import "WebProcess.h" +#import "WebSystemInterface.h" +#import <WebKit2/WKView.h> +#import <WebKitSystemInterface.h> +#import <mach/mach_error.h> +#import <objc/objc-auto.h> +#import <runtime/InitializeThreading.h> +#import <servers/bootstrap.h> +#import <signal.h> +#import <spawn.h> +#import <stdio.h> +#import <sysexits.h> +#import <unistd.h> +#import <wtf/RetainPtr.h> +#import <wtf/MainThread.h> +#import <wtf/text/CString.h> +#import <wtf/text/StringBuilder.h> + +#if !defined(BUILDING_ON_SNOW_LEOPARD) +extern "C" kern_return_t bootstrap_register2(mach_port_t, name_t, mach_port_t, uint64_t); +#endif + +@interface NSApplication (WebNSApplicationDetails) +-(void)_installAutoreleasePoolsOnCurrentThreadIfNecessary; +@end + +#define SHOW_CRASH_REPORTER 1 + +using namespace WebCore; + +namespace WebKit { + +int WebProcessMain(const CommandLine& commandLine) +{ + // Remove the WebProcess shim from the DYLD_INSERT_LIBRARIES environment variable so any processes spawned by + // the WebProcess don't try to insert the shim and crash. + EnvironmentUtilities::stripValuesEndingWithString("DYLD_INSERT_LIBRARIES", "/WebProcessShim.dylib"); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + String serviceName = commandLine["servicename"]; + String clientExecutable; +#if !defined(BUILDING_ON_SNOW_LEOPARD) + clientExecutable = commandLine["client-executable"]; +#endif + + if (serviceName.isEmpty() && clientExecutable.isEmpty()) + return EXIT_FAILURE; + + // Get the server port. + mach_port_t serverPort; + if (clientExecutable.isEmpty()) { + kern_return_t kr = bootstrap_look_up(bootstrap_port, serviceName.utf8().data(), &serverPort); + if (kr) { + fprintf(stderr, "bootstrap_look_up result: %s (%x)\n", mach_error_string(kr), kr); + return 2; + } + } +#if !defined(BUILDING_ON_SNOW_LEOPARD) + else { + mach_port_name_t publishedService; + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &publishedService); + mach_port_insert_right(mach_task_self(), publishedService, publishedService, MACH_MSG_TYPE_MAKE_SEND); + // Make it possible to look up. + serviceName = String::format("com.apple.WebKit.WebProcess-%d", getpid()); + if (kern_return_t kr = bootstrap_register2(bootstrap_port, const_cast<char*>(serviceName.utf8().data()), publishedService, 0)) { + fprintf(stderr, "Failed to register service name \"%s\". %s (%x)\n", serviceName.utf8().data(), mach_error_string(kr), kr); + return EXIT_FAILURE; + } + + CString command = clientExecutable.utf8(); + const char* args[] = { command.data(), 0 }; + + EnvironmentVariables environmentVariables; + environmentVariables.set(EnvironmentVariables::preexistingProcessServiceNameKey(), serviceName.utf8().data()); + environmentVariables.set(EnvironmentVariables::preexistingProcessTypeKey(), commandLine["type"].utf8().data()); + + posix_spawn_file_actions_t fileActions; + posix_spawn_file_actions_init(&fileActions); + posix_spawn_file_actions_addinherit_np(&fileActions, STDIN_FILENO); + posix_spawn_file_actions_addinherit_np(&fileActions, STDOUT_FILENO); + posix_spawn_file_actions_addinherit_np(&fileActions, STDERR_FILENO); + + posix_spawnattr_t attributes; + posix_spawnattr_init(&attributes); + posix_spawnattr_setflags(&attributes, POSIX_SPAWN_CLOEXEC_DEFAULT | POSIX_SPAWN_SETPGROUP); + + int spawnResult = posix_spawn(0, command.data(), &fileActions, &attributes, const_cast<char**>(args), environmentVariables.environmentPointer()); + if (spawnResult) + return 2; + + mach_msg_empty_rcv_t message; + if (kern_return_t kr = mach_msg(&message.header, MACH_RCV_MSG, 0, sizeof(message), publishedService, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL)) { + fprintf(stderr, "Failed to receive port from the UI process. %s (%x)\n", mach_error_string(kr), kr); + return EXIT_FAILURE; + } + + mach_port_mod_refs(mach_task_self(), publishedService, MACH_PORT_RIGHT_RECEIVE, -1); + serverPort = message.header.msgh_remote_port; + mach_port_type_t portType; + kern_return_t kr = mach_port_type(mach_task_self(), serverPort, &portType); + if (kr || !(portType & MACH_PORT_TYPE_SEND)) { + fprintf(stderr, "Failed to obtain send right for port received from the UI process.\n"); + return EXIT_FAILURE; + } + } +#endif // !defined(BUILDING_ON_SNOW_LEOPARD) + + String localization = commandLine["localization"]; + RetainPtr<CFStringRef> cfLocalization(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(localization.characters()), localization.length())); + if (cfLocalization) + WKSetDefaultLocalization(cfLocalization.get()); + +#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(); + + // Initialize the shim. + WebProcess::shared().initializeShim(); + + // Create the connection. + WebProcess::shared().initialize(serverPort, RunLoop::main()); + + [pool drain]; + + // Initialize AppKit. + [NSApplication sharedApplication]; + + // Installs autorelease pools on the current CFRunLoop which prevents memory from accumulating between user events. + // FIXME: Remove when <rdar://problem/8929426> is fixed. + [[NSApplication sharedApplication] _installAutoreleasePoolsOnCurrentThreadIfNecessary]; + + WKAXRegisterRemoteApp(); + + RunLoop::run(); + + // FIXME: Do more cleanup here. + + return 0; +} + +} // namespace WebKit + diff --git a/Source/WebKit2/WebProcess/mac/WebProcessShim.h b/Source/WebKit2/WebProcess/mac/WebProcessShim.h new file mode 100644 index 000000000..469f3d03e --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebProcessShim.h @@ -0,0 +1,51 @@ +/* + * 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 WebProcessShim_h +#define WebProcessShim_h + +namespace WebKit { + +struct WebProcessSecItemShimCallbacks { + OSStatus (*secItemCopyMatching)(CFDictionaryRef query, CFTypeRef *result); + OSStatus (*secItemAdd)(CFDictionaryRef attributes, CFTypeRef *result); + OSStatus (*secItemUpdate)(CFDictionaryRef query, CFDictionaryRef attributesToUpdate); + OSStatus (*secItemDelete)(CFDictionaryRef query); +}; + +typedef void (*WebProcessSecItemShimInitializeFunc)(const WebProcessSecItemShimCallbacks& callbacks); + +struct WebProcessKeychainItemShimCallbacks { + OSStatus (*secKeychainItemCopyContent)(SecKeychainItemRef, SecItemClass*, SecKeychainAttributeList*, UInt32* length, void** outData); + OSStatus (*secKeychainItemCreateFromContent)(SecItemClass, SecKeychainAttributeList*, UInt32 length, const void* data, SecKeychainItemRef*); + OSStatus (*secKeychainItemModifyContent)(SecKeychainItemRef, const SecKeychainAttributeList*, UInt32 length, const void* data); + bool (*freeAttributeListContent)(SecKeychainAttributeList* attrList); + bool (*freeKeychainItemContentData)(void* data); +}; + +typedef void (*WebProcessKeychainItemShimInitializeFunc)(const WebProcessKeychainItemShimCallbacks& callbacks); + +} // namespace WebKit + +#endif // WebProcessShim_h diff --git a/Source/WebKit2/WebProcess/mac/WebProcessShim.mm b/Source/WebKit2/WebProcess/mac/WebProcessShim.mm new file mode 100644 index 000000000..6d694419b --- /dev/null +++ b/Source/WebKit2/WebProcess/mac/WebProcessShim.mm @@ -0,0 +1,126 @@ +/* + * 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 "WebProcessShim.h" + +#import <Security/SecItem.h> +#import <wtf/Platform.h> + +#define DYLD_INTERPOSE(_replacement,_replacee) \ + __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \ + __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee }; + +namespace WebKit { + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + +extern "C" void WebKitWebProcessSecItemShimInitialize(const WebProcessSecItemShimCallbacks&); + +static WebProcessSecItemShimCallbacks secItemShimCallbacks; + +static OSStatus shimSecItemCopyMatching(CFDictionaryRef query, CFTypeRef* result) +{ + return secItemShimCallbacks.secItemCopyMatching(query, result); +} + +static OSStatus shimSecItemAdd(CFDictionaryRef query, CFTypeRef* result) +{ + return secItemShimCallbacks.secItemAdd(query, result); +} + +static OSStatus shimSecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) +{ + return secItemShimCallbacks.secItemUpdate(query, attributesToUpdate); +} + +static OSStatus shimSecItemDelete(CFDictionaryRef query) +{ + return secItemShimCallbacks.secItemDelete(query); +} + +DYLD_INTERPOSE(shimSecItemCopyMatching, SecItemCopyMatching) +DYLD_INTERPOSE(shimSecItemAdd, SecItemAdd) +DYLD_INTERPOSE(shimSecItemUpdate, SecItemUpdate) +DYLD_INTERPOSE(shimSecItemDelete, SecItemDelete) + +__attribute__((visibility("default"))) +void WebKitWebProcessSecItemShimInitialize(const WebProcessSecItemShimCallbacks& callbacks) +{ + secItemShimCallbacks = callbacks; +} + +#endif // !defined(BUILDING_ON_SNOW_LEOPARD) + +#if defined(BUILDING_ON_SNOW_LEOPARD) + +extern "C" void WebKitWebProcessKeychainItemShimInitialize(const WebProcessKeychainItemShimCallbacks&); + +static WebProcessKeychainItemShimCallbacks keychainItemShimCallbacks; + +static OSStatus shimSecKeychainItemCopyContent(SecKeychainItemRef item, SecItemClass* itemClass, SecKeychainAttributeList* attrList, UInt32* length, void** outData) +{ + return keychainItemShimCallbacks.secKeychainItemCopyContent(item, itemClass, attrList, length, outData); +} + +static OSStatus shimSecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList* attrList, UInt32 length, const void* data, + SecKeychainRef keychainRef, SecAccessRef initialAccess, SecKeychainItemRef *itemRef) +{ + // We don't support shimming SecKeychainItemCreateFromContent with Keychain or Access arguments at this time + if (keychainRef || initialAccess) + return SecKeychainItemCreateFromContent(itemClass, attrList, length, data, keychainRef, initialAccess, itemRef); + return keychainItemShimCallbacks.secKeychainItemCreateFromContent(itemClass, attrList, length, data, itemRef); +} + +static OSStatus shimSecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList* attrList, UInt32 length, const void* data) +{ + return keychainItemShimCallbacks.secKeychainItemModifyContent(itemRef, attrList, length, data); +} + +static OSStatus shimSecKeychainItemFreeContent(SecKeychainAttributeList* attrList, void* data) +{ + bool attrListHandled = !attrList || keychainItemShimCallbacks.freeAttributeListContent(attrList); + bool keychainItemContentHandled = !data || keychainItemShimCallbacks.freeKeychainItemContentData(data); + + // If both items were handled by the shim handlers, return now. + if (attrListHandled && keychainItemContentHandled) + return errSecSuccess; + + // Have the native function handle whichever item wasn't already handled. + return SecKeychainItemFreeContent(attrListHandled ? attrList : NULL, keychainItemContentHandled ? data : NULL); +} + +DYLD_INTERPOSE(shimSecKeychainItemCopyContent, SecKeychainItemCopyContent) +DYLD_INTERPOSE(shimSecKeychainItemCreateFromContent, SecKeychainItemCreateFromContent) +DYLD_INTERPOSE(shimSecKeychainItemModifyContent, SecKeychainItemModifyContent) +DYLD_INTERPOSE(shimSecKeychainItemFreeContent, SecKeychainItemFreeContent) + +__attribute__((visibility("default"))) +void WebKitWebProcessKeychainItemShimInitialize(const WebProcessKeychainItemShimCallbacks& callbacks) +{ + keychainItemShimCallbacks = callbacks; +} + +#endif // defined(BUILDING_ON_SNOW_LEOPARD) + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp new file mode 100644 index 000000000..a5a75d0c3 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.cpp @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 "config.h" +#include "QtBuiltinBundle.h" + +#include "QtBuiltinBundlePage.h" +#include "WKArray.h" +#include "WKBundlePage.h" +#include "WKNumber.h" +#include "WKRetainPtr.h" +#include "WKString.h" +#include "WKStringQt.h" +#include <wtf/PassOwnPtr.h> + +namespace WebKit { + +QtBuiltinBundle::~QtBuiltinBundle() +{ + // For OwnPtr's sake. +} + +QtBuiltinBundle& QtBuiltinBundle::shared() +{ + static QtBuiltinBundle& shared = *new QtBuiltinBundle; + return shared; +} + +void QtBuiltinBundle::initialize(WKBundleRef bundle) +{ + m_bundle = bundle; + WKBundleClient client = { + kWKBundleClientCurrentVersion, + this, + didCreatePage, + willDestroyPage, + 0, // didInitializePageGroup + didReceiveMessage + }; + WKBundleSetClient(m_bundle, &client); +} + +void QtBuiltinBundle::didCreatePage(WKBundleRef, WKBundlePageRef page, const void* clientInfo) +{ + static_cast<QtBuiltinBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page); +} + +void QtBuiltinBundle::willDestroyPage(WKBundleRef, WKBundlePageRef page, const void* clientInfo) +{ + static_cast<QtBuiltinBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page); +} + +void QtBuiltinBundle::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo) +{ + static_cast<QtBuiltinBundle*>(const_cast<void*>(clientInfo))->didReceiveMessage(messageName, messageBody); +} + +void QtBuiltinBundle::didCreatePage(WKBundlePageRef page) +{ + m_pages.add(page, adoptPtr(new QtBuiltinBundlePage(this, page))); +} + +void QtBuiltinBundle::willDestroyPage(WKBundlePageRef page) +{ + m_pages.remove(page); +} + +void QtBuiltinBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody) +{ + if (WKStringIsEqualToUTF8CString(messageName, "MessageToNavigatorQtObject")) + handleMessageToNavigatorQtObject(messageBody); + else if (WKStringIsEqualToUTF8CString(messageName, "SetNavigatorQtObjectEnabled")) + handleSetNavigatorQtObjectEnabled(messageBody); +} + +void QtBuiltinBundle::handleMessageToNavigatorQtObject(WKTypeRef messageBody) +{ + ASSERT(messageBody); + ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID()); + + WKArrayRef body = static_cast<WKArrayRef>(messageBody); + ASSERT(WKArrayGetSize(body) == 2); + ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 0)) == WKBundlePageGetTypeID()); + ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 1)) == WKStringGetTypeID()); + + WKBundlePageRef page = static_cast<WKBundlePageRef>(WKArrayGetItemAtIndex(body, 0)); + WKStringRef contents = static_cast<WKStringRef>(WKArrayGetItemAtIndex(body, 1)); + + QtBuiltinBundlePage* bundlePage = m_pages.get(page); + if (!bundlePage) + return; + bundlePage->didReceiveMessageToNavigatorQtObject(contents); +} + +void QtBuiltinBundle::handleSetNavigatorQtObjectEnabled(WKTypeRef messageBody) +{ + ASSERT(messageBody); + ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID()); + + WKArrayRef body = static_cast<WKArrayRef>(messageBody); + ASSERT(WKArrayGetSize(body) == 2); + ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 0)) == WKBundlePageGetTypeID()); + ASSERT(WKGetTypeID(WKArrayGetItemAtIndex(body, 1)) == WKBooleanGetTypeID()); + + WKBundlePageRef page = static_cast<WKBundlePageRef>(WKArrayGetItemAtIndex(body, 0)); + WKBooleanRef enabled = static_cast<WKBooleanRef>(WKArrayGetItemAtIndex(body, 1)); + + QtBuiltinBundlePage* bundlePage = m_pages.get(page); + if (!bundlePage) + return; + bundlePage->setNavigatorQtObjectEnabled(enabled); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h new file mode 100644 index 000000000..498fec7c2 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundle.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 QtBuiltinBundle_h +#define QtBuiltinBundle_h + +#include "WKBundle.h" +#include "WKBundlePage.h" +#include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> + +namespace WebKit { + +class QtBuiltinBundlePage; + +class QtBuiltinBundle { +public: + ~QtBuiltinBundle(); + + static QtBuiltinBundle& shared(); + void initialize(WKBundleRef); + + WKBundleRef toRef() const { return m_bundle; } + + // Bundle Client. + static void didCreatePage(WKBundleRef, WKBundlePageRef, const void*); + static void willDestroyPage(WKBundleRef, WKBundlePageRef, const void*); + static void didReceiveMessage(WKBundleRef, WKStringRef messageName, WKTypeRef messageBody, const void*); + + void didCreatePage(WKBundlePageRef); + void willDestroyPage(WKBundlePageRef); + void didReceiveMessage(WKStringRef messageName, WKTypeRef messageBody); + +private: + void handleMessageToNavigatorQtObject(WKTypeRef messageBody); + void handleSetNavigatorQtObjectEnabled(WKTypeRef messageBody); + + HashMap<WKBundlePageRef, OwnPtr<QtBuiltinBundlePage> > m_pages; + WKBundleRef m_bundle; +}; + +} // namespace WebKit + +#endif // QtBuiltinBundle_h diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp new file mode 100644 index 000000000..2c89556b3 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 "config.h" +#include "QtBuiltinBundlePage.h" + +#include "QtBuiltinBundle.h" +#include "WKArray.h" +#include "WKBundleFrame.h" +#include "WKRetainPtr.h" +#include "WKString.h" +#include "WKStringPrivate.h" +#include "WKStringQt.h" +#include <JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> + +namespace WebKit { + +QtBuiltinBundlePage::QtBuiltinBundlePage(QtBuiltinBundle* bundle, WKBundlePageRef page) + : m_bundle(bundle) + , m_page(page) + , m_navigatorQtObject(0) + , m_navigatorQtObjectEnabled(false) +{ + WKBundlePageLoaderClient loaderClient = { + kWKBundlePageLoaderClientCurrentVersion, + this, + 0, // didStartProvisionalLoadForFrame + 0, // didReceiveServerRedirectForProvisionalLoadForFrame + 0, // didFailProvisionalLoadWithErrorForFrame + 0, // didCommitLoadForFrame + 0, // didFinishDocumentLoadForFrame + 0, // didFinishLoadForFrame + 0, // didFailLoadWithErrorForFrame + 0, // didSameDocumentNavigationForFrame + 0, // didReceiveTitleForFrame + 0, // didFirstLayoutForFrame + 0, // didFirstVisuallyNonEmptyLayoutForFrame + 0, // didRemoveFrameFromHierarchy + 0, // didDisplayInsecureContentForFrame + 0, // didRunInsecureContentForFrame + didClearWindowForFrame, + 0, // didCancelClientRedirectForFrame + 0, // willPerformClientRedirectForFrame + 0, // didHandleOnloadEventsForFrame + 0, // didLayoutForFrame + 0, // didDetectXSSForFrame + }; + WKBundlePageSetPageLoaderClient(m_page, &loaderClient); +} + +QtBuiltinBundlePage::~QtBuiltinBundlePage() +{ + if (!m_navigatorQtObject) + return; + WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page); + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + JSValueUnprotect(context, m_navigatorQtObject); +} + +void QtBuiltinBundlePage::didClearWindowForFrame(WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void* clientInfo) +{ + static_cast<QtBuiltinBundlePage*>(const_cast<void*>(clientInfo))->didClearWindowForFrame(frame, world); +} + +static JSValueRef qt_postMessageCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) +{ + // FIXME: should it work regardless of the thisObject? + + if (argumentCount < 1 || !JSValueIsString(context, arguments[0])) + return JSValueMakeUndefined(context); + + QtBuiltinBundlePage* bundlePage = reinterpret_cast<QtBuiltinBundlePage*>(JSObjectGetPrivate(thisObject)); + ASSERT(bundlePage); + + // FIXME: needed? + if (!bundlePage->navigatorQtObjectEnabled()) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> jsContents = JSValueToStringCopy(context, arguments[0], 0); + WKRetainPtr<WKStringRef> contents(AdoptWK, WKStringCreateWithJSString(jsContents.get())); + bundlePage->postMessageFromNavigatorQtObject(contents.get()); + return JSValueMakeUndefined(context); +} + +void QtBuiltinBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, WKBundleScriptWorldRef world) +{ + if (!WKBundleFrameIsMainFrame(frame) || WKBundleScriptWorldNormalWorld() != world) + return; + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContextForWorld(frame, world); + registerNavigatorQtObject(context); +} + +void QtBuiltinBundlePage::postMessageFromNavigatorQtObject(WKStringRef contents) +{ + static WKStringRef messageName = WKStringCreateWithUTF8CString("MessageFromNavigatorQtObject"); + WKTypeRef body[] = { page(), contents }; + WKRetainPtr<WKArrayRef> messageBody(AdoptWK, WKArrayCreate(body, sizeof(body) / sizeof(WKTypeRef))); + WKBundlePostMessage(m_bundle->toRef(), messageName, messageBody.get()); +} + +static JSObjectRef createWrappedMessage(JSGlobalContextRef context, WKStringRef data) +{ + static JSStringRef dataName = JSStringCreateWithUTF8CString("data"); + + JSRetainPtr<JSStringRef> jsData = WKStringCopyJSString(data); + JSObjectRef wrappedMessage = JSObjectMake(context, 0, 0); + JSObjectSetProperty(context, wrappedMessage, dataName, JSValueMakeString(context, jsData.get()), kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); + return wrappedMessage; +} + +void QtBuiltinBundlePage::didReceiveMessageToNavigatorQtObject(WKStringRef contents) +{ + static JSStringRef onmessageName = JSStringCreateWithUTF8CString("onmessage"); + + if (!m_navigatorQtObject) + return; + + WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page); + JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame); + + JSValueRef onmessageValue = JSObjectGetProperty(context, m_navigatorQtObject, onmessageName, 0); + if (!JSValueIsObject(context, onmessageValue)) + return; + + JSObjectRef onmessageFunction = JSValueToObject(context, onmessageValue, 0); + if (!JSObjectIsFunction(context, onmessageFunction)) + return; + + JSObjectRef wrappedMessage = createWrappedMessage(context, contents); + JSObjectCallAsFunction(context, onmessageFunction, 0, 1, &wrappedMessage, 0); +} + +void QtBuiltinBundlePage::setNavigatorQtObjectEnabled(bool enabled) +{ + if (enabled == m_navigatorQtObjectEnabled) + return; + // Note that this will take effect only after the next page load. + m_navigatorQtObjectEnabled = enabled; +} + +void QtBuiltinBundlePage::registerNavigatorQtObject(JSGlobalContextRef context) +{ + static JSStringRef postMessageName = JSStringCreateWithUTF8CString("postMessage"); + static JSStringRef navigatorName = JSStringCreateWithUTF8CString("navigator"); + static JSStringRef qtName = JSStringCreateWithUTF8CString("qt"); + + if (m_navigatorQtObject) + JSValueUnprotect(context, m_navigatorQtObject); + m_navigatorQtObject = JSObjectMake(context, navigatorQtObjectClass(), this); + JSValueProtect(context, m_navigatorQtObject); + + JSObjectRef postMessage = JSObjectMakeFunctionWithCallback(context, postMessageName, qt_postMessageCallback); + JSObjectSetProperty(context, m_navigatorQtObject, postMessageName, postMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); + + JSValueRef navigatorValue = JSObjectGetProperty(context, JSContextGetGlobalObject(context), navigatorName, 0); + if (!JSValueIsObject(context, navigatorValue)) + return; + JSObjectRef navigatorObject = JSValueToObject(context, navigatorValue, 0); + JSObjectSetProperty(context, navigatorObject, qtName, m_navigatorQtObject, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, 0); +} + +JSClassRef QtBuiltinBundlePage::navigatorQtObjectClass() +{ + static JSClassRef classRef = 0; + if (!classRef) { + const JSClassDefinition navigatorQtObjectClass = kJSClassDefinitionEmpty; + classRef = JSClassCreate(&navigatorQtObjectClass); + } + return classRef; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h new file mode 100644 index 000000000..3ffb3f008 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtBuiltinBundlePage.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 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 QtBuiltinBundlePage_h +#define QtBuiltinBundlePage_h + +#include "JSObjectRef.h" +#include "WKBundlePage.h" +#include "WKBundleScriptWorld.h" + +namespace WebKit { + +class QtBuiltinBundle; + +class QtBuiltinBundlePage { +public: + QtBuiltinBundlePage(QtBuiltinBundle*, WKBundlePageRef); + ~QtBuiltinBundlePage(); + + WKBundlePageRef page() const { return m_page; } + + // Loader Client. + static void didClearWindowForFrame(WKBundlePageRef, WKBundleFrameRef, WKBundleScriptWorldRef, const void*); + + void didClearWindowForFrame(WKBundleFrameRef, WKBundleScriptWorldRef); + + void postMessageFromNavigatorQtObject(WKStringRef message); + void didReceiveMessageToNavigatorQtObject(WKStringRef message); + + bool navigatorQtObjectEnabled() const { return m_navigatorQtObjectEnabled; } + void setNavigatorQtObjectEnabled(bool); + +private: + void registerNavigatorQtObject(JSGlobalContextRef); + + static JSClassRef navigatorQtObjectClass(); + + QtBuiltinBundle* m_bundle; + WKBundlePageRef m_page; + JSObjectRef m_navigatorQtObject; + bool m_navigatorQtObjectEnabled; +}; + +} // namespace WebKit + +#endif // QtBuiltinBundlePage_h diff --git a/Source/WebKit2/WebProcess/qt/QtNetworkAccessManager.cpp b/Source/WebKit2/WebProcess/qt/QtNetworkAccessManager.cpp new file mode 100644 index 000000000..57b953fea --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtNetworkAccessManager.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@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 "config.h" +#include "QtNetworkAccessManager.h" + +#include "SharedMemory.h" +#include "WebFrameNetworkingContext.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <QNetworkReply> +#include <QNetworkRequest> + +namespace WebKit { + +QtNetworkAccessManager::QtNetworkAccessManager(WebProcess* webProcess) + : QNetworkAccessManager() + , m_webProcess(webProcess) +{ +} + +QtNetworkAccessManager::QtNetworkAccessManager(QObject* parent) + : QNetworkAccessManager(parent) + , m_webProcess(0) +{ +} + +WebPage* QtNetworkAccessManager::obtainOriginatingWebPage(const QNetworkRequest& request) +{ + QObject* originatingObject = request.originatingObject(); + if (!originatingObject) + return 0; + + QVariant pagePtr = originatingObject->property("PagePointer"); + if (!pagePtr.isValid() || !pagePtr.canConvert<void*>()) + return 0; + + WebPage* webPage = static_cast<WebPage*>(pagePtr.value<void*>()); + Q_ASSERT(webPage); + return webPage; +} + +QNetworkReply* QtNetworkAccessManager::createRequest(Operation operation, const QNetworkRequest& request, QIODevice* outData) +{ + WebPage* webPage = obtainOriginatingWebPage(request); + if (webPage && m_applicationSchemes.contains(webPage, request.url().scheme().toLower())) { + QtNetworkReply* reply = new QtNetworkReply(request, this); + webPage->receivedApplicationSchemeRequest(request, reply); + return reply; + } + + return QNetworkAccessManager::createRequest(operation, request, outData); +} + +void QtNetworkAccessManager::registerApplicationScheme(const WebPage* page, const QString& scheme) +{ + m_applicationSchemes.insert(page, scheme.toLower()); +} + +} + +#include "moc_QtNetworkAccessManager.cpp" diff --git a/Source/WebKit2/WebProcess/qt/QtNetworkAccessManager.h b/Source/WebKit2/WebProcess/qt/QtNetworkAccessManager.h new file mode 100644 index 000000000..8d9eb1d0e --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtNetworkAccessManager.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@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. + */ + +#ifndef QtNetworkAccessManager_h +#define QtNetworkAccessManager_h + +#include <QMultiHash> +#include <QNetworkAccessManager> +#include <QString> + +namespace WebKit { + +class WebPage; +class WebProcess; + +class QtNetworkAccessManager : public QNetworkAccessManager { + Q_OBJECT +public: + QtNetworkAccessManager(QObject* parent); + QtNetworkAccessManager(WebProcess*); + void registerApplicationScheme(const WebPage*, const QString& scheme); + +protected: + virtual QNetworkReply* createRequest(Operation, const QNetworkRequest&, QIODevice* outgoingData = 0) OVERRIDE; + static WebPage* obtainOriginatingWebPage(const QNetworkRequest&); + +private: + QMultiHash<const WebPage*, QString> m_applicationSchemes; + WebProcess* m_webProcess; + +}; + +} // namespace WebKit + +#endif // QtNetworkAccessManager_h diff --git a/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp b/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp new file mode 100644 index 000000000..fd0f5cb7a --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtNetworkReply.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@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 "config.h" +#include "QtNetworkReply.h" + +#include "SharedMemory.h" +#include "WebFrameNetworkingContext.h" +#include "WebPage.h" +#include "WebProcess.h" +#include <QNetworkCookie> +#include <QNetworkReply> +#include <QNetworkRequest> + +namespace WebKit { + +QtNetworkReply::QtNetworkReply(const QNetworkRequest& req, QtNetworkAccessManager* parent) + : QNetworkReply(parent) + , m_bytesAvailable(0) + , m_sharedMemorySize(0) +{ + setRequest(req); + setOperation(QNetworkAccessManager::GetOperation); + setUrl(req.url()); + setOpenMode(QIODevice::ReadOnly); + setHeader(QNetworkRequest::ContentTypeHeader, QVariant(QString::fromLocal8Bit("text/html; charset=UTF-16"))); +} + +void QtNetworkReply::setData(const SharedMemory::Handle& handle, qint64 dataSize) +{ + m_sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); + if (!m_sharedMemory) + return; + + m_bytesAvailable = dataSize; + m_sharedMemorySize = dataSize; +} + +void QtNetworkReply::setReplyData(const QtNetworkReplyData& replyData) +{ + if (replyData.m_operation) + setOperation(replyData.m_operation); + if (!replyData.m_contentDisposition.isNull()) + setHeader(QNetworkRequest::ContentDispositionHeader, QString(replyData.m_contentDisposition)); + if (!replyData.m_contentType.isNull()) + setHeader(QNetworkRequest::ContentTypeHeader, QString(replyData.m_contentType)); + if (!replyData.m_location.isNull()) + setHeader(QNetworkRequest::LocationHeader, QString(replyData.m_location)); + if (replyData.m_lastModified) + setHeader(QNetworkRequest::LastModifiedHeader, QDateTime::fromMSecsSinceEpoch(replyData.m_lastModified)); + if (!replyData.m_cookie.isNull()) + setHeader(QNetworkRequest::SetCookieHeader, QVariant::fromValue(QNetworkCookie::parseCookies(QString(replyData.m_cookie).toAscii()))); + if (!replyData.m_userAgent.isNull()) + setHeader(QNetworkRequest::UserAgentHeader, QString(replyData.m_userAgent)); + if (!replyData.m_server.isNull()) + setHeader(QNetworkRequest::ServerHeader, QString(replyData.m_server)); + setHeader(QNetworkRequest::ContentLengthHeader, QVariant::fromValue(replyData.m_contentLength)); + setData(replyData.m_dataHandle, replyData.m_contentLength); +} + +qint64 QtNetworkReply::readData(char* data, qint64 maxlen) +{ + qint64 bytesRead = maxlen < m_bytesAvailable ? maxlen : m_bytesAvailable; + if (qMemCopy(data, static_cast<char*>(m_sharedMemory->data()) + m_sharedMemorySize - m_bytesAvailable, bytesRead)) { + m_bytesAvailable -= bytesRead; + return bytesRead; + } + return 0; +} + +qint64 QtNetworkReply::bytesAvailable() const +{ + return m_bytesAvailable + QNetworkReply::bytesAvailable(); +} + +void QtNetworkReply::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) +{ + QNetworkReply::setHeader(header, value); +} + +void QtNetworkReply::abort() { } +void QtNetworkReply::close() { } +void QtNetworkReply::setReadBufferSize(qint64 size) { } +bool QtNetworkReply::canReadLine () const { return true; } + +void QtNetworkReply::finalize() +{ + QNetworkReply::setFinished(true); + emit readyRead(); + emit finished(); +} + +} // namespace WebKit + diff --git a/Source/WebKit2/WebProcess/qt/QtNetworkReply.h b/Source/WebKit2/WebProcess/qt/QtNetworkReply.h new file mode 100644 index 000000000..8ceb7926e --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/QtNetworkReply.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 Zeno Albisser <zeno@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. + */ + +#ifndef QtNetworkReply_h +#define QtNetworkReply_h + +#include "QtNetworkReplyData.h" +#include "SharedMemory.h" +#include <QByteArray> +#include <QDateTime> +#include <QNetworkReply> + +namespace WebKit { + +class QtNetworkAccessManager; + +class QtNetworkReply : public QNetworkReply { +public: + QtNetworkReply(const QNetworkRequest&, QtNetworkAccessManager* parent); + + virtual qint64 readData(char *data, qint64 maxlen); + virtual qint64 bytesAvailable() const; + void setHeader(QNetworkRequest::KnownHeaders, const QVariant &value); + void setData(const SharedMemory::Handle&, qint64 dataSize); + void setReplyData(const QtNetworkReplyData&); + void finalize(); + +protected: + virtual void abort(); + virtual void close(); + virtual void setReadBufferSize(qint64); + virtual bool canReadLine() const; + +private: + qint64 m_bytesAvailable; + QByteArray m_buffer; + RefPtr<SharedMemory> m_sharedMemory; + qint64 m_sharedMemorySize; +}; + +} // namespace WebKit + +#endif // QtNetworkReply_h diff --git a/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp b/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp new file mode 100644 index 000000000..c38e38241 --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/WebProcessMainQt.cpp @@ -0,0 +1,215 @@ +/* + * 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 "config.h" +#include "RunLoop.h" +#include <runtime/InitializeThreading.h> +#include "WebProcess.h" +#include <wtf/MainThread.h> + +#include <QApplication> +#include <QList> +#include <QNetworkProxyFactory> +#include <QString> +#include <QStringList> +#include <QUrl> +#include <QtGlobal> + +#if USE(ACCELERATED_COMPOSITING) +#include "WebGraphicsLayer.h" +#endif + +#ifndef NDEBUG +#if !OS(WINDOWS) +#include <unistd.h> +#endif +#endif + +#ifndef NDEBUG +#include <QDebug> +#endif + +#if !USE(UNIX_DOMAIN_SOCKETS) +#include <servers/bootstrap.h> + +extern "C" kern_return_t bootstrap_look_up2(mach_port_t, const name_t, mach_port_t*, pid_t, uint64_t); +#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(QString::fromLocal8Bit(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(QString::fromLocal8Bit(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(); + bool localHost = false; + + if (!query.peerHostName().compare(QLatin1String("localhost"), Qt::CaseInsensitive) || !query.peerHostName().compare(QLatin1String("127.0.0.1"), Qt::CaseInsensitive)) + localHost = true; + if (protocol == QLatin1String("http") && !localHost) + return m_httpProxy; + if (protocol == QLatin1String("https") && !localHost) + 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); +} + +void messageHandler(QtMsgType type, const char* message) +{ + if (type == QtCriticalMsg) { + fprintf(stderr, "%s\n", message); + return; + } + + // Do nothing +} + +Q_DECL_EXPORT int WebProcessMainQt(int argc, char** argv) +{ + // Has to be done before QApplication is constructed in case + // QApplication itself produces debug output. + QByteArray suppressOutput = qgetenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT"); + if (!suppressOutput.isEmpty() && suppressOutput != "0") + qInstallMsgHandler(messageHandler); + + QApplication::setGraphicsSystem(QLatin1String("raster")); + QApplication* app = new QApplication(argc, argv); +#ifndef NDEBUG + if (qgetenv("QT_WEBKIT2_DEBUG") == "1") { + qDebug() << "Waiting 3 seconds for debugger"; + sleep(3); + } +#endif + + initializeProxy(); + + srandom(time(0)); + + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + // Create the connection. + if (app->arguments().size() <= 1) { + qDebug() << "Error: wrong number of arguments."; + return 1; + } + +#if OS(DARWIN) + QString serviceName = app->arguments().value(1); + + // Get the server port. + mach_port_t identifier; + kern_return_t kr = bootstrap_look_up2(bootstrap_port, serviceName.toUtf8().data(), &identifier, 0, 0); + if (kr) { + printf("bootstrap_look_up2 result: %x", kr); + return 2; + } +#else + bool wasNumber = false; + int identifier = app->arguments().at(1).toInt(&wasNumber, 10); + if (!wasNumber) { + qDebug() << "Error: connection identifier wrong."; + return 1; + } +#endif +#if USE(ACCELERATED_COMPOSITING) + WebGraphicsLayer::initFactory(); +#endif + + 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 000000000..a2beac14b --- /dev/null +++ b/Source/WebKit2/WebProcess/qt/WebProcessQt.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcess.h" + +#include "InjectedBundle.h" +#include "QtBuiltinBundle.h" +#include "QtNetworkAccessManager.h" +#include "WKBundleAPICast.h" +#include "WebProcessCreationParameters.h" + +#include <QCoreApplication> +#include <QNetworkAccessManager> +#include <QNetworkCookieJar> +#include <WebCore/CookieJarQt.h> +#include <WebCore/PageCache.h> +#include <WebCore/RuntimeEnabledFeatures.h> + +#if defined(Q_OS_MACX) +#include <dispatch/dispatch.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +static const int DefaultPageCacheCapacity = 20; + +void WebProcess::platformSetCacheModel(CacheModel) +{ + // FIXME: see bug 73918 + pageCache()->setCapacity(DefaultPageCacheCapacity); +} + +void WebProcess::platformClearResourceCaches(ResourceCachesToClear) +{ +} + +#if defined(Q_OS_MACX) +static void parentProcessDiedCallback(void*) +{ + QCoreApplication::quit(); +} +#endif + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments) +{ + m_networkAccessManager = new QtNetworkAccessManager(this); + ASSERT(!parameters.cookieStorageDirectory.isEmpty() && !parameters.cookieStorageDirectory.isNull()); + WebCore::SharedCookieJarQt* jar = WebCore::SharedCookieJarQt::create(parameters.cookieStorageDirectory); + m_networkAccessManager->setCookieJar(jar); + // Do not let QNetworkAccessManager delete the jar. + jar->setParent(0); + +#if defined(Q_OS_MACX) + pid_t ppid = getppid(); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, ppid, DISPATCH_PROC_EXIT, queue); + if (source) { + dispatch_source_set_event_handler_f(source, parentProcessDiedCallback); + dispatch_resume(source); + } +#endif + + // 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 + + // We'll only install the Qt builtin bundle if we don't have one given by the UI process. + // Currently only WTR provides its own bundle. + if (parameters.injectedBundlePath.isEmpty()) { + m_injectedBundle = InjectedBundle::create(String()); + m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle)); + QtBuiltinBundle::shared().initialize(toAPI(m_injectedBundle.get())); + } +} + +void WebProcess::platformTerminate() +{ + delete m_networkAccessManager; + m_networkAccessManager = 0; + WebCore::SharedCookieJarQt::shared()->destroy(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/win/WebProcessMainWin.cpp b/Source/WebKit2/WebProcess/win/WebProcessMainWin.cpp new file mode 100644 index 000000000..5edeefe5c --- /dev/null +++ b/Source/WebKit2/WebProcess/win/WebProcessMainWin.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 "config.h" +#include "WebProcessMain.h" + +#include "CommandLine.h" +#include "RunLoop.h" +#include "WebProcess.h" +#include <WebCore/SoftLinking.h> +#include <runtime/InitializeThreading.h> +#include <wtf/MainThread.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 000000000..809aacb3a --- /dev/null +++ b/Source/WebKit2/WebProcess/win/WebProcessWin.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 "config.h" +#include "WebProcess.h" + +#include "WebCookieManager.h" +#include "WebPage.h" +#include "WebProcessCreationParameters.h" +#include <WebCore/FileSystem.h> +#include <WebCore/MemoryCache.h> +#include <WebCore/PageCache.h> +#include <WebCore/ResourceHandle.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; +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef defaultStorageSession = ResourceHandle::defaultStorageSession()) + cfurlCacheDirectory.adoptCF(wkCopyFoundationCacheDirectory(defaultStorageSession)); + else +#endif + cfurlCacheDirectory.adoptCF(wkCopyFoundationCacheDirectory(0)); + + 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; +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef defaultStorageSession = ResourceHandle::defaultStorageSession()) + cfurlCache.adoptCF(wkCopyURLCache(defaultStorageSession)); + else +#endif // USE(CFURLSTORAGESESSIONS) + 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(ResourceCachesToClear cachesToClear) +{ +#if USE(CFNETWORK) + if (cachesToClear == InMemoryResourceCachesOnly) + return; + + RetainPtr<CFURLCacheRef> cache; +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef defaultStorageSession = ResourceHandle::defaultStorageSession()) + cache.adoptCF(wkCopyURLCache(defaultStorageSession)); + else +#endif // USE(CFURLSTORAGESESSIONS) + cache.adoptCF(CFURLCacheCopySharedURLCache()); + + CFURLCacheRemoveAllCachedResponses(cache.get()); +#endif // USE(CFNETWORK) +} + +void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*) +{ + setShouldPaintNativeControls(parameters.shouldPaintNativeControls); + +#if USE(CFNETWORK) + RetainPtr<CFURLStorageSessionRef> defaultStorageSession(AdoptCF, wkDeserializeStorageSession(parameters.serializedDefaultStorageSession.get())); + ResourceHandle::setDefaultStorageSession(defaultStorageSession.get()); + + WebCookieManager::shared().setHTTPCookieAcceptPolicy(parameters.initialHTTPCookieAcceptPolicy); + + // By using the default storage session that came from the ui process, the web process + // automatically uses the same the URL Cache as ui process. + if (defaultStorageSession) + return; + + RetainPtr<CFStringRef> cachePath(AdoptCF, parameters.cfURLCachePath.createCFString()); + if (!cachePath) + return; + + CFIndex cacheDiskCapacity = parameters.cfURLCacheDiskCapacity; + CFIndex cacheMemoryCapacity = parameters.cfURLCacheMemoryCapacity; + RetainPtr<CFURLCacheRef> uiProcessCache(AdoptCF, CFURLCacheCreate(kCFAllocatorDefault, cacheMemoryCapacity, cacheDiskCapacity, cachePath.get())); + CFURLCacheSetSharedURLCache(uiProcessCache.get()); +#endif // USE(CFNETWORK) +} + +void WebProcess::platformTerminate() +{ +} + +void WebProcess::setShouldPaintNativeControls(bool shouldPaintNativeControls) +{ +#if USE(SAFARI_THEME) + Settings::setShouldPaintNativeControls(shouldPaintNativeControls); +#endif +} + +struct EnumWindowsContext { + DWORD currentThreadID; + Vector<HWND>* windows; +}; + +static BOOL CALLBACK addWindowToVectorIfOwnedByCurrentThread(HWND window, LPARAM lParam) +{ + EnumWindowsContext* context = reinterpret_cast<EnumWindowsContext*>(lParam); + + if (::GetWindowThreadProcessId(window, 0) != context->currentThreadID) + return TRUE; + + context->windows->append(window); + return TRUE; +} + +Vector<HWND> WebProcess::windowsToReceiveSentMessagesWhileWaitingForSyncReply() +{ + Vector<HWND> windows; + + // Any non-message-only window created by this thread needs to receive sent messages while we + // wait for a sync reply. Otherwise we could deadlock with the UI process if, e.g., the focus + // window changes. See <http://webkit.org/b/58239>. + + EnumWindowsContext context; + context.currentThreadID = ::GetCurrentThreadId(); + context.windows = &windows; + + // Start out with top-level windows created by this thread (like Flash's hidden + // SWFlash_PlaceholderX top-level windows). + ::EnumThreadWindows(context.currentThreadID, addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); + + // Also include any descendants of those top-level windows. + size_t topLevelWindowCount = windows.size(); + for (size_t i = 0; i < topLevelWindowCount; ++i) + ::EnumChildWindows(windows[i], addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); + + // Also include any descendants of the WebPages' windows which we've created (e.g., for windowed plugins). + HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values it = m_pageMap.begin(); it != end; ++it) + ::EnumChildWindows((*it)->nativeWindow(), addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); + + return windows; +} + +} // namespace WebKit |