diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/API')
42 files changed, 1342 insertions, 322 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h index a440c6f..81c2f5f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h +++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h @@ -37,11 +37,13 @@ #include "WKPage.h" #include "WKPreferencesPrivate.h" #include "WKProtectionSpaceTypes.h" +#include "WKResourceCacheManager.h" #include "WKSharedAPICast.h" #include <WebCore/CookieJar.h> #include <WebCore/Credential.h> #include <WebCore/FrameLoaderTypes.h> #include <WebCore/ProtectionSpace.h> +#include <WebCore/Settings.h> namespace WebKit { @@ -182,6 +184,44 @@ inline WKFontSmoothingLevel toAPI(FontSmoothingLevel level) return kWKFontSmoothingLevelMedium; } +inline WKEditableLinkBehavior toAPI(WebCore::EditableLinkBehavior behavior) +{ + switch (behavior) { + case WebCore::EditableLinkDefaultBehavior: + return kWKEditableLinkBehaviorDefault; + case WebCore::EditableLinkAlwaysLive: + return kWKEditableLinkBehaviorAlwaysLive; + case WebCore::EditableLinkOnlyLiveWithShiftKey: + return kWKEditableLinkBehaviorOnlyLiveWithShiftKey; + case WebCore::EditableLinkLiveWhenNotFocused: + return kWKEditableLinkBehaviorLiveWhenNotFocused; + case WebCore::EditableLinkNeverLive: + return kWKEditableLinkBehaviorNeverLive; + } + + ASSERT_NOT_REACHED(); + return kWKEditableLinkBehaviorNeverLive; +} + +inline WebCore::EditableLinkBehavior toEditableLinkBehavior(WKEditableLinkBehavior wkBehavior) +{ + switch (wkBehavior) { + case kWKEditableLinkBehaviorDefault: + return WebCore::EditableLinkDefaultBehavior; + case kWKEditableLinkBehaviorAlwaysLive: + return WebCore::EditableLinkAlwaysLive; + case kWKEditableLinkBehaviorOnlyLiveWithShiftKey: + return WebCore::EditableLinkOnlyLiveWithShiftKey; + case kWKEditableLinkBehaviorLiveWhenNotFocused: + return WebCore::EditableLinkLiveWhenNotFocused; + case kWKEditableLinkBehaviorNeverLive: + return WebCore::EditableLinkNeverLive; + } + + ASSERT_NOT_REACHED(); + return WebCore::EditableLinkNeverLive; +} + inline WKProtectionSpaceServerType toAPI(WebCore::ProtectionSpaceServerType type) { switch (type) { @@ -246,9 +286,9 @@ inline WebCore::CredentialPersistence toCredentialPersistence(WKCredentialPersis inline ResourceCachesToClear toResourceCachesToClear(WKResourceCachesToClear wkResourceCachesToClear) { switch (wkResourceCachesToClear) { - case kWKAllResourceCaches: + case WKResourceCachesToClearAll: return AllResourceCaches; - case kWKInMemoryResourceCachesOnly: + case WKResourceCachesToClearInMemoryOnly: return InMemoryResourceCachesOnly; } diff --git a/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.cpp b/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.cpp index 5f6a222..00dc6da 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.cpp @@ -45,3 +45,8 @@ WKStringRef WKBackForwardListItemCopyTitle(WKBackForwardListItemRef itemRef) { return toCopiedAPI(toImpl(itemRef)->title()); } + +WKURLRef WKBackForwardListItemCopyOriginalURL(WKBackForwardListItemRef itemRef) +{ + return toCopiedURLAPI(toImpl(itemRef)->originalURL()); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.h b/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.h index b0bf1de..3810d15 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.h +++ b/Source/WebKit2/UIProcess/API/C/WKBackForwardListItem.h @@ -36,6 +36,7 @@ WK_EXPORT WKTypeID WKBackForwardListItemGetTypeID(); WK_EXPORT WKURLRef WKBackForwardListItemCopyURL(WKBackForwardListItemRef item); WK_EXPORT WKStringRef WKBackForwardListItemCopyTitle(WKBackForwardListItemRef item); +WK_EXPORT WKURLRef WKBackForwardListItemCopyOriginalURL(WKBackForwardListItemRef item); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/WKContext.cpp b/Source/WebKit2/UIProcess/API/C/WKContext.cpp index bf196b7..063f3ea 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContext.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKContext.cpp @@ -84,9 +84,9 @@ void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownload toImpl(contextRef)->initializeDownloadClient(wkClient); } -void WKContextDownloadURLRequest(WKContextRef contextRef, const WKURLRequestRef requestRef) +WKDownloadRef WKContextDownloadURLRequest(WKContextRef contextRef, const WKURLRequestRef requestRef) { - toImpl(contextRef)->download(0, toImpl(requestRef)->resourceRequest()); + return toAPI(toImpl(contextRef)->download(0, toImpl(requestRef)->resourceRequest())); } void WKContextSetInitializationUserDataForInjectedBundle(WKContextRef contextRef, WKTypeRef userDataRef) @@ -148,16 +148,6 @@ void WKContextSetDomainRelaxationForbiddenForURLScheme(WKContextRef contextRef, toImpl(contextRef)->setDomainRelaxationForbiddenForURLScheme(toImpl(urlScheme)->string()); } -void WKContextClearResourceCaches(WKContextRef contextRef, WKResourceCachesToClear cachesToClear) -{ - toImpl(contextRef)->clearResourceCaches(toResourceCachesToClear(cachesToClear)); -} - -void WKContextClearApplicationCache(WKContextRef contextRef) -{ - toImpl(contextRef)->clearApplicationCache(); -} - WKCookieManagerRef WKContextGetCookieManager(WKContextRef contextRef) { return toAPI(toImpl(contextRef)->cookieManagerProxy()); @@ -227,3 +217,18 @@ void WKContextSetLocalStorageDirectory(WKContextRef contextRef, WKStringRef loca { toImpl(contextRef)->setLocalStorageDirectory(toImpl(localStorageDirectory)->string()); } + +void WKContextDisableProcessTermination(WKContextRef contextRef) +{ + toImpl(contextRef)->disableProcessTermination(); +} + +void WKContextEnableProcessTermination(WKContextRef contextRef) +{ + toImpl(contextRef)->enableProcessTermination(); +} + +void _WKContextSetHTTPPipeliningEnabled(WKContextRef contextRef, bool enabled) +{ + toImpl(contextRef)->setHTTPPipeliningEnabled(enabled); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKContext.h b/Source/WebKit2/UIProcess/API/C/WKContext.h index 606574f..6e8e4c0 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContext.h +++ b/Source/WebKit2/UIProcess/API/C/WKContext.h @@ -39,12 +39,6 @@ enum { }; typedef uint32_t WKCacheModel; -enum { - kWKAllResourceCaches = 0, - kWKInMemoryResourceCachesOnly = 1 -}; -typedef uint32_t WKResourceCachesToClear; - // Injected Bundle Client typedef void (*WKContextDidReceiveMessageFromInjectedBundleCallback)(WKContextRef page, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo); typedef void (*WKContextDidReceiveSynchronousMessageFromInjectedBundleCallback)(WKContextRef page, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void *clientInfo); @@ -115,7 +109,7 @@ WK_EXPORT void WKContextSetInjectedBundleClient(WKContextRef context, const WKCo WK_EXPORT void WKContextSetHistoryClient(WKContextRef context, const WKContextHistoryClient* client); WK_EXPORT void WKContextSetDownloadClient(WKContextRef context, const WKContextDownloadClient* client); -WK_EXPORT void WKContextDownloadURLRequest(WKContextRef context, const WKURLRequestRef request); +WK_EXPORT WKDownloadRef WKContextDownloadURLRequest(WKContextRef context, const WKURLRequestRef request); WK_EXPORT void WKContextSetInitializationUserDataForInjectedBundle(WKContextRef context, WKTypeRef userData); WK_EXPORT void WKContextPostMessageToInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody); @@ -125,9 +119,6 @@ WK_EXPORT void WKContextAddVisitedLink(WKContextRef context, WKStringRef visited WK_EXPORT void WKContextSetCacheModel(WKContextRef context, WKCacheModel cacheModel); WK_EXPORT WKCacheModel WKContextGetCacheModel(WKContextRef context); -WK_EXPORT void WKContextClearResourceCaches(WKContextRef context, WKResourceCachesToClear cachesToClear); -WK_EXPORT void WKContextClearApplicationCache(WKContextRef context); - WK_EXPORT void WKContextStartMemorySampler(WKContextRef context, WKDoubleRef interval); WK_EXPORT void WKContextStopMemorySampler(WKContextRef context); diff --git a/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h b/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h index 5fd7dd3..153ef3e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h @@ -61,6 +61,13 @@ WK_EXPORT void WKContextSetIconDatabasePath(WKContextRef context, WKStringRef ic WK_EXPORT void WKContextSetDatabaseDirectory(WKContextRef context, WKStringRef databaseDirectory); WK_EXPORT void WKContextSetLocalStorageDirectory(WKContextRef context, WKStringRef localStorageDirectory); +// FIXME: This is a workaround for testing purposes only and should be removed once a better +// solution has been found for testing. +WK_EXPORT void WKContextDisableProcessTermination(WKContextRef context); +WK_EXPORT void WKContextEnableProcessTermination(WKContextRef context); + +WK_EXPORT void _WKContextSetHTTPPipeliningEnabled(WKContextRef context, bool enabled); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKFrame.h b/Source/WebKit2/UIProcess/API/C/WKFrame.h index 334a27b..eec939e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKFrame.h +++ b/Source/WebKit2/UIProcess/API/C/WKFrame.h @@ -36,12 +36,12 @@ extern "C" { #endif -enum WKFrameLoadState { +enum { kWKFrameLoadStateProvisional = 0, kWKFrameLoadStateCommitted = 1, kWKFrameLoadStateFinished = 2 }; -typedef enum WKFrameLoadState WKFrameLoadState; +typedef uint32_t WKFrameLoadState; WK_EXPORT WKTypeID WKFrameGetTypeID(); diff --git a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp index c8e87a0..8e9327f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp @@ -36,6 +36,13 @@ WKTypeID WKIconDatabaseGetTypeID() return toAPI(WebIconDatabase::APIType); } +void WKIconDatabaseSetIconDatabaseClient(WKIconDatabaseRef iconDatabaseRef, const WKIconDatabaseClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + toImpl(iconDatabaseRef)->initializeIconDatabaseClient(wkClient); +} + void WKIconDatabaseRetainIconForURL(WKIconDatabaseRef iconDatabaseRef, WKURLRef pageURLRef) { toImpl(iconDatabaseRef)->retainIconForPageURL(toWTFString(pageURLRef)); @@ -50,3 +57,18 @@ void WKIconDatabaseEnableDatabaseCleanup(WKIconDatabaseRef iconDatabaseRef) { toImpl(iconDatabaseRef)->enableDatabaseCleanup(); } + +void WKIconDatabaseRemoveAllIcons(WKIconDatabaseRef iconDatabaseRef) +{ + toImpl(iconDatabaseRef)->removeAllIcons(); +} + +void WKIconDatabaseCheckIntegrityBeforeOpening(WKIconDatabaseRef iconDatabaseRef) +{ + toImpl(iconDatabaseRef)->checkIntegrityBeforeOpening(); +} + +void WKIconDatabaseClose(WKIconDatabaseRef iconDatabaseRef) +{ + toImpl(iconDatabaseRef)->close(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h index 1ea1860..ece3399 100644 --- a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h +++ b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h @@ -32,12 +32,31 @@ extern "C" { #endif +// IconDatabase Client. +typedef void (*WKIconDatabaseDidChangeIconForPageURLCallback)(WKIconDatabaseRef iconDatabase, WKURLRef pageURL, const void* clientInfo); +typedef void (*WKIconDatabaseDidRemoveAllIconsCallback)(WKIconDatabaseRef iconDatabase, const void* clientInfo); + +struct WKIconDatabaseClient { + int version; + const void * clientInfo; + WKIconDatabaseDidChangeIconForPageURLCallback didChangeIconForPageURL; + WKIconDatabaseDidRemoveAllIconsCallback didRemoveAllIcons; +}; +typedef struct WKIconDatabaseClient WKIconDatabaseClient; + WK_EXPORT WKTypeID WKIconDatabaseGetTypeID(); +WK_EXPORT void WKIconDatabaseSetIconDatabaseClient(WKIconDatabaseRef iconDatabase, const WKIconDatabaseClient* client); + WK_EXPORT void WKIconDatabaseRetainIconForURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL); WK_EXPORT void WKIconDatabaseReleaseIconForURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL); WK_EXPORT void WKIconDatabaseEnableDatabaseCleanup(WKIconDatabaseRef iconDatabase); +WK_EXPORT void WKIconDatabaseRemoveAllIcons(WKIconDatabaseRef iconDatabase); +WK_EXPORT void WKIconDatabaseCheckIntegrityBeforeOpening(WKIconDatabaseRef iconDatabase); + +WK_EXPORT void WKIconDatabaseClose(WKIconDatabaseRef iconDatabase); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.cpp b/Source/WebKit2/UIProcess/API/C/WKPage.cpp index 7061e39..18bc5a7 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPage.cpp @@ -32,6 +32,7 @@ #include "WebBackForwardList.h" #include "WebData.h" #include "WebPageProxy.h" +#include "WebProcessProxy.h" #ifdef __BLOCKS__ #include <Block.h> @@ -46,7 +47,7 @@ WKTypeID WKPageGetTypeID() WKContextRef WKPageGetContext(WKPageRef pageRef) { - return toAPI(toImpl(pageRef)->context()); + return toAPI(toImpl(pageRef)->process()->context()); } WKPageGroupRef WKPageGetPageGroup(WKPageRef pageRef) diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.h b/Source/WebKit2/UIProcess/API/C/WKPage.h index 03f49f7..72405a3 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.h +++ b/Source/WebKit2/UIProcess/API/C/WKPage.h @@ -41,6 +41,12 @@ extern "C" { #endif +enum { + kWKFocusDirectionBackward = 0, + kWKFocusDirectionForward = 1 +}; +typedef uint32_t WKFocusDirection; + typedef void (*WKPageCallback)(WKPageRef page, const void* clientInfo); // FrameLoad Client @@ -149,6 +155,9 @@ typedef WKPageRef (*WKPageCreateNewPageCallback)(WKPageRef page, WKDictionaryRef typedef void (*WKPageRunJavaScriptAlertCallback)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void *clientInfo); typedef bool (*WKPageRunJavaScriptConfirmCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, const void *clientInfo); typedef WKStringRef (*WKPageRunJavaScriptPromptCallback)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, const void *clientInfo); +typedef void (*WKPageTakeFocusCallback)(WKPageRef page, WKFocusDirection direction, const void *clientInfo); +typedef void (*WKPageFocusCallback)(WKPageRef page, const void *clientInfo); +typedef void (*WKPageUnfocusCallback)(WKPageRef page, const void *clientInfo); typedef void (*WKPageSetStatusTextCallback)(WKPageRef page, WKStringRef text, const void *clientInfo); typedef void (*WKPageMouseDidMoveOverElementCallback)(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo); typedef void (*WKPageMissingPluginButtonClickedCallback)(WKPageRef page, WKStringRef mimeType, WKStringRef url, WKStringRef pluginsPageURL, const void* clientInfo); @@ -181,6 +190,9 @@ struct WKPageUIClient { WKPageCreateNewPageCallback createNewPage; WKPageCallback showPage; WKPageCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; WKPageRunJavaScriptAlertCallback runJavaScriptAlert; WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp index 0122531..449a1e8 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp @@ -29,6 +29,7 @@ #include "WKAPICast.h" #include "WebPreferences.h" +#include <WebCore/Settings.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> @@ -71,6 +72,16 @@ bool WKPreferencesGetLoadsImagesAutomatically(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->loadsImagesAutomatically(); } +void WKPreferencesSetLoadsSiteIconsIgnoringImageLoadingPreference(WKPreferencesRef preferencesRef, bool loadsSiteIconsIgnoringImageLoadingPreference) +{ + toImpl(preferencesRef)->setLoadsSiteIconsIgnoringImageLoadingPreference(loadsSiteIconsIgnoringImageLoadingPreference); +} + +bool WKPreferencesGetLoadsSiteIconsIgnoringImageLoadingPreference(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->loadsSiteIconsIgnoringImageLoadingPreference(); +} + void WKPreferencesSetOfflineWebApplicationCacheEnabled(WKPreferencesRef preferencesRef, bool offlineWebApplicationCacheEnabled) { toImpl(preferencesRef)->setOfflineWebApplicationCacheEnabled(offlineWebApplicationCacheEnabled); @@ -251,6 +262,16 @@ uint32_t WKPreferencesGetMinimumFontSize(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->minimumFontSize(); } +void WKPreferencesSetEditableLinkBehavior(WKPreferencesRef preferencesRef, WKEditableLinkBehavior wkBehavior) +{ + toImpl(preferencesRef)->setEditableLinkBehavior(toEditableLinkBehavior(wkBehavior)); +} + +WKEditableLinkBehavior WKPreferencesGetEditableLinkBehavior(WKPreferencesRef preferencesRef) +{ + return toAPI(static_cast<WebCore::EditableLinkBehavior>(toImpl(preferencesRef)->editableLinkBehavior())); +} + void WKPreferencesSetDefaultTextEncodingName(WKPreferencesRef preferencesRef, WKStringRef name) { toImpl(preferencesRef)->setDefaultTextEncodingName(toWTFString(name)); diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.h b/Source/WebKit2/UIProcess/API/C/WKPreferences.h index f2486bf..930f23d 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.h +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.h @@ -50,6 +50,10 @@ WK_EXPORT void WKPreferencesSetLoadsImagesAutomatically(WKPreferencesRef prefere WK_EXPORT bool WKPreferencesGetLoadsImagesAutomatically(WKPreferencesRef preferences); // Defaults to false. +WK_EXPORT void WKPreferencesSetLoadsSiteIconsIgnoringImageLoadingPreference(WKPreferencesRef preferences, bool loadsSiteIconsIgnoringImageLoadingPreference); +WK_EXPORT bool WKPreferencesGetLoadsSiteIconsIgnoringImageLoadingPreference(WKPreferencesRef preferences); + +// Defaults to false. WK_EXPORT void WKPreferencesSetOfflineWebApplicationCacheEnabled(WKPreferencesRef preferences, bool offlineWebApplicationCacheEnabled); WK_EXPORT bool WKPreferencesGetOfflineWebApplicationCacheEnabled(WKPreferencesRef preferences); diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h b/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h index ddf1b9a..d67db14 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h @@ -43,10 +43,23 @@ enum WKFontSmoothingLevel { }; typedef enum WKFontSmoothingLevel WKFontSmoothingLevel; +enum WKEditableLinkBehavior { + kWKEditableLinkBehaviorDefault, + kWKEditableLinkBehaviorAlwaysLive, + kWKEditableLinkBehaviorOnlyLiveWithShiftKey, + kWKEditableLinkBehaviorLiveWhenNotFocused, + kWKEditableLinkBehaviorNeverLive +}; +typedef enum WKEditableLinkBehavior WKEditableLinkBehavior; + // Defaults to kWKFontSmoothingLevelMedium. WK_EXPORT void WKPreferencesSetFontSmoothingLevel(WKPreferencesRef, WKFontSmoothingLevel); WK_EXPORT WKFontSmoothingLevel WKPreferencesGetFontSmoothingLevel(WKPreferencesRef); +// Defaults to EditableLinkNeverLive. +WK_EXPORT void WKPreferencesSetEditableLinkBehavior(WKPreferencesRef preferencesRef, WKEditableLinkBehavior); +WK_EXPORT WKEditableLinkBehavior WKPreferencesGetEditableLinkBehavior(WKPreferencesRef preferencesRef); + // Defaults to false. WK_EXPORT void WKPreferencesSetAcceleratedDrawingEnabled(WKPreferencesRef, bool); WK_EXPORT bool WKPreferencesGetAcceleratedDrawingEnabled(WKPreferencesRef); diff --git a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp index 483beeb..a5711e0 100644 --- a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp @@ -41,12 +41,12 @@ void WKResourceCacheManagerGetCacheOrigins(WKResourceCacheManagerRef cacheManage toImpl(cacheManagerRef)->getCacheOrigins(ArrayCallback::create(context, callback)); } -void WKResourceCacheManagerClearCacheForOrigin(WKResourceCacheManagerRef cacheManagerRef, WKSecurityOriginRef originRef) +void WKResourceCacheManagerClearCacheForOrigin(WKResourceCacheManagerRef cacheManagerRef, WKSecurityOriginRef originRef, WKResourceCachesToClear cachesToClear) { - toImpl(cacheManagerRef)->clearCacheForOrigin(toImpl(originRef)); + toImpl(cacheManagerRef)->clearCacheForOrigin(toImpl(originRef), toResourceCachesToClear(cachesToClear)); } -void WKResourceCacheManagerClearCacheForAllOrigins(WKResourceCacheManagerRef cacheManagerRef) +void WKResourceCacheManagerClearCacheForAllOrigins(WKResourceCacheManagerRef cacheManagerRef, WKResourceCachesToClear cachesToClear) { - toImpl(cacheManagerRef)->clearCacheForAllOrigins(); + toImpl(cacheManagerRef)->clearCacheForAllOrigins(toResourceCachesToClear(cachesToClear)); } diff --git a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h index 479169d..80c4531 100644 --- a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h @@ -32,13 +32,19 @@ extern "C" { #endif +enum { + WKResourceCachesToClearAll = 0, + WKResourceCachesToClearInMemoryOnly = 1 +}; +typedef uint32_t WKResourceCachesToClear; + WK_EXPORT WKTypeID WKResourceCacheManagerGetTypeID(); typedef void (*WKResourceCacheManagerGetCacheOriginsFunction)(WKArrayRef, WKErrorRef, void*); WK_EXPORT void WKResourceCacheManagerGetCacheOrigins(WKResourceCacheManagerRef contextRef, void* context, WKResourceCacheManagerGetCacheOriginsFunction function); -WK_EXPORT void WKResourceCacheManagerClearCacheForOrigin(WKResourceCacheManagerRef cacheManger, WKSecurityOriginRef origin); -WK_EXPORT void WKResourceCacheManagerClearCacheForAllOrigins(WKResourceCacheManagerRef cacheManager); +WK_EXPORT void WKResourceCacheManagerClearCacheForOrigin(WKResourceCacheManagerRef cacheManger, WKSecurityOriginRef origin, WKResourceCachesToClear cachesToClear); +WK_EXPORT void WKResourceCacheManagerClearCacheForAllOrigins(WKResourceCacheManagerRef cacheManager, WKResourceCachesToClear cachesToClear); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.cpp b/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.cpp index 5e50dd8..40e4a0e 100644 --- a/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.cpp +++ b/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.cpp @@ -34,8 +34,8 @@ using namespace WebKit; using namespace WebCore; -CGImageRef WKIconDatabaseGetCGImageForURL(WKIconDatabaseRef iconDatabaseRef, WKURLRef urlRef) +CGImageRef WKIconDatabaseTryGetCGImageForURL(WKIconDatabaseRef iconDatabaseRef, WKURLRef urlRef, WKSize size) { Image* image = toImpl(iconDatabaseRef)->imageForPageURL(toWTFString(urlRef)); - return image ? image->getCGImageRef() : 0; + return image ? image->getFirstCGImageRefOfSize(IntSize(static_cast<int>(size.width), static_cast<int>(size.height))) : 0; } diff --git a/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.h b/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.h index 48cf5bf..62ae82e 100644 --- a/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.h +++ b/Source/WebKit2/UIProcess/API/C/cg/WKIconDatabaseCG.h @@ -28,12 +28,13 @@ #include <CoreGraphics/CGImage.h> #include <WebKit2/WKBase.h> +#include <WebKit2/WKGeometry.h> #ifdef __cplusplus extern "C" { #endif -WK_EXPORT CGImageRef WKIconDatabaseGetCGImageForURL(WKIconDatabaseRef iconDatabase, WKURLRef urlString); +WK_EXPORT CGImageRef WKIconDatabaseTryGetCGImageForURL(WKIconDatabaseRef iconDatabase, WKURLRef urlString, WKSize size); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/win/WKAPICastWin.h b/Source/WebKit2/UIProcess/API/C/win/WKAPICastWin.h index 09cf06f..24891f5 100644 --- a/Source/WebKit2/UIProcess/API/C/win/WKAPICastWin.h +++ b/Source/WebKit2/UIProcess/API/C/win/WKAPICastWin.h @@ -30,14 +30,25 @@ #error "Please #include \"WKAPICast.h\" instead of this file directly." #endif +#include "WebGrammarDetail.h" +#include <WebCore/TextCheckerClient.h> + namespace WebKit { class WebView; class WebEditCommandProxy; +class WebTextChecker; WK_ADD_API_MAPPING(WKViewRef, WebView) WK_ADD_API_MAPPING(WKEditCommandRef, WebEditCommandProxy) +WK_ADD_API_MAPPING(WKTextCheckerRef, WebTextChecker) +WK_ADD_API_MAPPING(WKGrammarDetailRef, WebGrammarDetail) +inline ProxyingRefPtr<WebGrammarDetail> toAPI(const WebCore::GrammarDetail& grammarDetail) +{ + return ProxyingRefPtr<WebGrammarDetail>(WebGrammarDetail::create(grammarDetail)); } +} // namespace WebKit + #endif // WKAPICastWin_h diff --git a/Source/WebKit2/UIProcess/API/C/win/WKGrammarDetail.cpp b/Source/WebKit2/UIProcess/API/C/win/WKGrammarDetail.cpp new file mode 100644 index 0000000..5ab0fc4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/win/WKGrammarDetail.cpp @@ -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 "WKGrammarDetail.h" + +#include "APIObject.h" +#include "ImmutableArray.h" +#include "WKAPICast.h" +#include "WebGrammarDetail.h" + +using namespace WebKit; + +WKTypeID WKGrammarDetailGetTypeID() +{ + return toAPI(APIObject::TypeGrammarDetail); +} + +WKGrammarDetailRef WKGrammarDetailCreate(int location, int length, WKArrayRef guesses, WKStringRef userDescription) +{ + RefPtr<WebGrammarDetail> detail = WebGrammarDetail::create(location, length, toImpl(guesses), toWTFString(userDescription)); + return toAPI(detail.release().releaseRef()); +} + +int WKGrammarDetailGetLocation(WKGrammarDetailRef grammarDetailRef) +{ + return toImpl(grammarDetailRef)->location(); +} + +int WKGrammarDetailGetLength(WKGrammarDetailRef grammarDetailRef) +{ + return toImpl(grammarDetailRef)->length(); +} + +WKArrayRef WKGrammarDetailCopyGuesses(WKGrammarDetailRef grammarDetailRef) +{ + return toAPI(toImpl(grammarDetailRef)->guesses().leakRef()); +} + +WKStringRef WKGrammarDetailCopyUserDescription(WKGrammarDetailRef grammarDetailRef) +{ + return toCopiedAPI(toImpl(grammarDetailRef)->userDescription()); +} diff --git a/Source/WebKit2/UIProcess/API/C/win/WKGrammarDetail.h b/Source/WebKit2/UIProcess/API/C/win/WKGrammarDetail.h new file mode 100644 index 0000000..c187ce6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/win/WKGrammarDetail.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 WKGrammarDetail_h +#define WKGrammarDetail_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKGrammarDetailGetTypeID(); +WK_EXPORT WKGrammarDetailRef WKGrammarDetailCreate(int location, int length, WKArrayRef guesses, WKStringRef userDescription); + +WK_EXPORT int WKGrammarDetailGetLocation(WKGrammarDetailRef grammarDetailRef); +WK_EXPORT int WKGrammarDetailGetLength(WKGrammarDetailRef grammarDetailRef); +WK_EXPORT WKArrayRef WKGrammarDetailCopyGuesses(WKGrammarDetailRef grammarDetailRef); +WK_EXPORT WKStringRef WKGrammarDetailCopyUserDescription(WKGrammarDetailRef grammarDetailRef); + +#ifdef __cplusplus +} +#endif + +#endif /* WKGrammarDetail_h */ diff --git a/Source/WebKit2/UIProcess/API/C/win/WKTextChecker.cpp b/Source/WebKit2/UIProcess/API/C/win/WKTextChecker.cpp new file mode 100644 index 0000000..3329da2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/win/WKTextChecker.cpp @@ -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. + */ + +#include "config.h" +#include "WKTextChecker.h" + +#include "WKAPICast.h" +#include "WebPageProxy.h" +#include "WebTextChecker.h" + +using namespace WebKit; + +void WKTextCheckerSetClient(const WKTextCheckerClient* wkClient) +{ + if (wkClient && wkClient->version) + return; + WebTextChecker::shared()->setClient(wkClient); +} + +void WKTextCheckerContinuousSpellCheckingEnabledStateChanged(bool enabled) +{ + WebTextChecker::shared()->continuousSpellCheckingEnabledStateChanged(enabled); +} + +void WKTextCheckerGrammarCheckingEnabledStateChanged(bool enabled) +{ + WebTextChecker::shared()->grammarCheckingEnabledStateChanged(enabled); +} + +void WKTextCheckerCheckSpelling(WKPageRef page, bool startBeforeSelection) +{ + WebTextChecker::shared()->checkSpelling(toImpl(page), startBeforeSelection); +} + +void WKTextCheckerChangeSpellingToWord(WKPageRef page, WKStringRef word) +{ + WebTextChecker::shared()->changeSpellingToWord(toImpl(page), toWTFString(word)); +} diff --git a/Source/WebKit2/UIProcess/API/C/win/WKTextChecker.h b/Source/WebKit2/UIProcess/API/C/win/WKTextChecker.h new file mode 100644 index 0000000..31a855d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/win/WKTextChecker.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 WKTextChecker_h +#define WKTextChecker_h + +#include <WebKit2/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// TextChecker Client +typedef bool (*WKTextCheckerContinousSpellCheckingAllowed)(const void *clientInfo); +typedef bool (*WKTextCheckerContinousSpellCheckingEnabled)(const void *clientInfo); +typedef void (*WKTextCheckerSetContinousSpellCheckingEnabled)(bool enabled, const void *clientInfo); +typedef bool (*WKTextCheckerGrammarCheckingEnabled)(const void *clientInfo); +typedef void (*WKTextCheckerSetGrammarCheckingEnabled)(bool enabled, const void *clientInfo); +typedef uint64_t (*WKTextCheckerUniqueSpellDocumentTag)(WKPageRef page, const void *clientInfo); +typedef void (*WKTextCheckerCloseSpellDocumentWithTag)(uint64_t tag, const void *clientInfo); +typedef void (*WKTextCheckerCheckSpellingOfString)(uint64_t tag, WKStringRef text, int32_t* misspellingLocation, int32_t* misspellingLength, const void *clientInfo); +typedef void (*WKTextCheckerCheckGrammarOfString)(uint64_t tag, WKStringRef text, WKArrayRef* grammarDetails, int32_t* badGrammarLocation, int32_t* badGrammarLength, const void *clientInfo); +typedef bool (*WKTextCheckerSpellingUIIsShowing)(const void *clientInfo); +typedef void (*WKTextCheckerToggleSpellingUIIsShowing)(const void *clientInfo); +typedef void (*WKTextCheckerUpdateSpellingUIWithMisspelledWord)(uint64_t tag, WKStringRef misspelledWord, const void *clientInfo); +typedef void (*WKTextCheckerUpdateSpellingUIWithGrammarString)(uint64_t tag, WKStringRef badGrammarPhrase, WKGrammarDetailRef grammarDetail, const void *clientInfo); +typedef WKArrayRef (*WKTextCheckerGuessesForWord)(uint64_t tag, WKStringRef word, const void *clientInfo); +typedef void (*WKTextCheckerLearnWord)(uint64_t tag, WKStringRef word, const void *clientInfo); +typedef void (*WKTextCheckerIgnoreWord)(uint64_t tag, WKStringRef word, const void *clientInfo); + +struct WKTextCheckerClient { + int version; + const void * clientInfo; + WKTextCheckerContinousSpellCheckingAllowed continuousSpellCheckingAllowed; + WKTextCheckerContinousSpellCheckingEnabled continuousSpellCheckingEnabled; + WKTextCheckerSetContinousSpellCheckingEnabled setContinuousSpellCheckingEnabled; + WKTextCheckerGrammarCheckingEnabled grammarCheckingEnabled; + WKTextCheckerSetGrammarCheckingEnabled setGrammarCheckingEnabled; + WKTextCheckerUniqueSpellDocumentTag uniqueSpellDocumentTag; + WKTextCheckerCloseSpellDocumentWithTag closeSpellDocumentWithTag; + WKTextCheckerCheckSpellingOfString checkSpellingOfString; + WKTextCheckerCheckGrammarOfString checkGrammarOfString; + WKTextCheckerSpellingUIIsShowing spellingUIIsShowing; + WKTextCheckerToggleSpellingUIIsShowing toggleSpellingUIIsShowing; + WKTextCheckerUpdateSpellingUIWithMisspelledWord updateSpellingUIWithMisspelledWord; + WKTextCheckerUpdateSpellingUIWithGrammarString updateSpellingUIWithGrammarString; + WKTextCheckerGuessesForWord guessesForWord; + WKTextCheckerLearnWord learnWord; + WKTextCheckerIgnoreWord ignoreWord; +}; +typedef struct WKTextCheckerClient WKTextCheckerClient; + +WK_EXPORT void WKTextCheckerSetClient(const WKTextCheckerClient* client); + +WK_EXPORT void WKTextCheckerContinuousSpellCheckingEnabledStateChanged(bool); +WK_EXPORT void WKTextCheckerGrammarCheckingEnabledStateChanged(bool); + +WK_EXPORT void WKTextCheckerCheckSpelling(WKPageRef page, bool startBeforeSelection); +WK_EXPORT void WKTextCheckerChangeSpellingToWord(WKPageRef page, WKStringRef word); + +#ifdef __cplusplus +} +#endif + +#endif /* WKTextChecker_h */ diff --git a/Source/WebKit2/UIProcess/API/C/win/WKView.h b/Source/WebKit2/UIProcess/API/C/win/WKView.h index c8ac44c..8b5e5b2 100644 --- a/Source/WebKit2/UIProcess/API/C/win/WKView.h +++ b/Source/WebKit2/UIProcess/API/C/win/WKView.h @@ -43,12 +43,16 @@ typedef uint32_t WKViewUndoType; typedef void (*WKViewRegisterEditCommandCallback)(WKViewRef, WKEditCommandRef, WKViewUndoType undoOrRedo, const void *clientInfo); typedef void (*WKViewClearAllEditCommandsCallback)(WKViewRef, const void *clientInfo); +typedef bool (*WKViewCanUndoRedoCallback)(WKViewRef, WKViewUndoType undoOrRedo, const void *clientInfo); +typedef void (*WKViewExecuteUndoRedoCallback)(WKViewRef, WKViewUndoType undoOrRedo, const void *clientInfo); struct WKViewUndoClient { int version; const void * clientInfo; WKViewRegisterEditCommandCallback registerEditCommand; WKViewClearAllEditCommandsCallback clearAllEditCommands; + WKViewCanUndoRedoCallback canUndoRedo; + WKViewExecuteUndoRedoCallback executeUndoRedo; }; typedef struct WKViewUndoClient WKViewUndoClient; diff --git a/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h b/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h index cb2a63e..ae5ba65 100644 --- a/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h +++ b/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h @@ -204,9 +204,15 @@ template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr< return a != b.get(); } +template<typename T> inline WKRetainPtr<T> adoptWK(T o) +{ + return WKRetainPtr<T>(AdoptWK, o); +} + } // namespace WebKit using WebKit::WKRetainPtr; using WebKit::AdoptWK; +using WebKit::adoptWK; #endif // WKRetainPtr_h diff --git a/Source/WebKit2/UIProcess/API/mac/PDFViewController.h b/Source/WebKit2/UIProcess/API/mac/PDFViewController.h index dc30f56..041aa7b 100644 --- a/Source/WebKit2/UIProcess/API/mac/PDFViewController.h +++ b/Source/WebKit2/UIProcess/API/mac/PDFViewController.h @@ -26,6 +26,7 @@ #ifndef PDFViewController_h #define PDFViewController_h +#include "WebFindOptions.h" #include <wtf/Forward.h> #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> @@ -64,6 +65,10 @@ public: NSPrintOperation *makePrintOperation(NSPrintInfo *); void openPDFInFinder(); void savePDFToDownloadsFolder(); + void linkClicked(const String& url); + + void findString(const String&, FindOptions, unsigned maxMatchCount); + void countStringMatches(const String&, FindOptions, unsigned maxMatchCount); private: explicit PDFViewController(WKView *wkView); diff --git a/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm b/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm index 5c64000..436a08a 100644 --- a/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm +++ b/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm @@ -30,10 +30,12 @@ #import "WKAPICast.h" #import "WKView.h" #import "WebData.h" +#import "WebEventFactory.h" #import "WebPageGroup.h" #import "WebPageProxy.h" #import "WebPreferences.h" #import <PDFKit/PDFKit.h> +#import <WebCore/LocalizedStrings.h> #import <wtf/text/WTFString.h> // Redeclarations of PDFKit notifications. We can't use the API since we use a weak link to the framework. @@ -51,7 +53,51 @@ using namespace WebKit; @end extern "C" NSString *_NSPathForSystemFramework(NSString *framework); + +// MARK: C UTILITY FUNCTIONS + +static void _applicationInfoForMIMEType(NSString *type, NSString **name, NSImage **image) +{ + ASSERT(name); + ASSERT(image); + CFURLRef appURL = 0; + + OSStatus error = LSCopyApplicationForMIMEType((CFStringRef)type, kLSRolesAll, &appURL); + if (error != noErr) + return; + + NSString *appPath = [(NSURL *)appURL path]; + if (appURL) + CFRelease(appURL); + + *image = [[NSWorkspace sharedWorkspace] iconForFile:appPath]; + [*image setSize:NSMakeSize(16, 16)]; + + *name = [[NSFileManager defaultManager] displayNameAtPath:appPath]; +} + +// FIXME 4182876: We can eliminate this function in favor if -isEqual: if [PDFSelection isEqual:] is overridden +// to compare contents. +static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selectionB) +{ + NSArray *aPages = [selectionA pages]; + NSArray *bPages = [selectionB pages]; + + if (![aPages isEqual:bPages]) + return NO; + + NSUInteger count = [aPages count]; + for (NSUInteger i = 0; i < count; ++i) { + NSRect aBounds = [selectionA boundsForPage:[aPages objectAtIndex:i]]; + NSRect bBounds = [selectionB boundsForPage:[bPages objectAtIndex:i]]; + if (!NSEqualRects(aBounds, bBounds)) + return NO; + } + + return YES; +} + @interface WKPDFView : NSView { PDFViewController* _pdfViewController; @@ -68,7 +114,7 @@ extern "C" NSString *_NSPathForSystemFramework(NSString *framework); - (void)setDocument:(PDFDocument *)pdfDocument; - (void)_applyPDFPreferences; - +- (PDFSelection *)_nextMatchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag fromSelection:(PDFSelection *)initialSelection startInSelection:(BOOL)startInSelection; @end @implementation WKPDFView @@ -159,6 +205,64 @@ extern "C" NSString *_NSPathForSystemFramework(NSString *framework); [self _updatePreferencesSoon]; } +- (void)_openWithFinder:(id)sender +{ + _pdfViewController->openPDFInFinder(); +} + +- (PDFSelection *)_nextMatchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag fromSelection:(PDFSelection *)initialSelection startInSelection:(BOOL)startInSelection +{ + if (![string length]) + return nil; + + int options = 0; + if (!forward) + options |= NSBackwardsSearch; + + if (!caseFlag) + options |= NSCaseInsensitiveSearch; + + PDFDocument *document = [_pdfView document]; + + PDFSelection *selectionForInitialSearch = [initialSelection copy]; + if (startInSelection) { + // Initially we want to include the selected text in the search. So we must modify the starting search + // selection to fit PDFDocument's search requirements: selection must have a length >= 1, begin before + // the current selection (if searching forwards) or after (if searching backwards). + int initialSelectionLength = [[initialSelection string] length]; + if (forward) { + [selectionForInitialSearch extendSelectionAtStart:1]; + [selectionForInitialSearch extendSelectionAtEnd:-initialSelectionLength]; + } else { + [selectionForInitialSearch extendSelectionAtEnd:1]; + [selectionForInitialSearch extendSelectionAtStart:-initialSelectionLength]; + } + } + PDFSelection *foundSelection = [document findString:string fromSelection:selectionForInitialSearch withOptions:options]; + [selectionForInitialSearch release]; + + // If we first searched in the selection, and we found the selection, search again from just past the selection + if (startInSelection && _PDFSelectionsAreEqual(foundSelection, initialSelection)) + foundSelection = [document findString:string fromSelection:initialSelection withOptions:options]; + + if (!foundSelection && wrapFlag) + foundSelection = [document findString:string fromSelection:nil withOptions:options]; + + return foundSelection; +} + +- (NSUInteger)_countMatches:(NSString *)string caseSensitive:(BOOL)caseFlag +{ + if (![string length]) + return 0; + + int options = caseFlag ? 0 : NSCaseInsensitiveSearch; + + return [[[_pdfView document] findString:string withOptions:options] count]; +} + +// MARK: NSView overrides + - (void)viewDidMoveToWindow { if (![self window]) @@ -181,7 +285,69 @@ extern "C" NSString *_NSPathForSystemFramework(NSString *framework); [notificationCenter removeObserver:self name:_webkit_PDFViewPageChangedNotification object:_pdfView]; } -// PDFView delegate methods +- (NSView *)hitTest:(NSPoint)point +{ + // Override hitTest so we can override menuForEvent. + NSEvent *event = [NSApp currentEvent]; + NSEventType type = [event type]; + if (type == NSRightMouseDown || (type == NSLeftMouseDown && ([event modifierFlags] & NSControlKeyMask))) + return self; + + return [super hitTest:point]; +} + +- (NSMenu *)menuForEvent:(NSEvent *)theEvent +{ + NSMenu *menu = [[NSMenu alloc] initWithTitle:@""]; + + NSEnumerator *menuItemEnumerator = [[[_pdfView menuForEvent:theEvent] itemArray] objectEnumerator]; + while (NSMenuItem *item = [menuItemEnumerator nextObject]) { + NSMenuItem *itemCopy = [item copy]; + [menu addItem:itemCopy]; + [itemCopy release]; + + if ([item action] != @selector(copy:)) + continue; + + // Add in an "Open with <default PDF viewer>" item + NSString *appName = nil; + NSImage *appIcon = nil; + + _applicationInfoForMIMEType(@"application/pdf", &appName, &appIcon); + if (!appName) + appName = WEB_UI_STRING("Finder", "Default application name for Open With context menu"); + + // To match the PDFKit style, we'll add Open with Preview even when there's no document yet to view, and + // disable it using validateUserInterfaceItem. + NSString *title = [NSString stringWithFormat:WEB_UI_STRING("Open with %@", "context menu item for PDF"), appName]; + + item = [[NSMenuItem alloc] initWithTitle:title action:@selector(_openWithFinder:) keyEquivalent:@""]; + if (appIcon) + [item setImage:appIcon]; + [menu addItem:[NSMenuItem separatorItem]]; + [menu addItem:item]; + [item release]; + } + + return [menu autorelease]; +} + +// MARK: NSUserInterfaceValidations PROTOCOL IMPLEMENTATION + +- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item +{ + SEL action = [item action]; + if (action == @selector(_openWithFinder:)) + return [_pdfView document] != nil; + return YES; +} + +// MARK: PDFView delegate methods + +- (void)PDFViewWillClickOnLink:(PDFView *)sender withURL:(NSURL *)URL +{ + _pdfViewController->linkClicked([URL absoluteString]); +} - (void)PDFViewOpenPDFInNativeApplication:(PDFView *)sender { @@ -416,4 +582,55 @@ NSString *PDFViewController::pathToPDFOnDisk() return path; } +void PDFViewController::linkClicked(const String& url) +{ + NSEvent* nsEvent = [NSApp currentEvent]; + WebMouseEvent event; + switch ([nsEvent type]) { + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + event = WebEventFactory::createWebMouseEvent(nsEvent, m_pdfView); + default: + // For non mouse-clicks or for keyboard events, pass an empty WebMouseEvent + // through. The event is only used by the WebFrameLoaderClient to determine + // the modifier keys and which mouse button is down. These queries will be + // valid with an empty event. + break; + } + + page()->linkClicked(url, event); +} + +void PDFViewController::findString(const String& string, FindOptions options, unsigned maxMatchCount) +{ + BOOL forward = !(options & FindOptionsBackwards); + BOOL caseFlag = !(options & FindOptionsCaseInsensitive); + BOOL wrapFlag = options & FindOptionsWrapAround; + + PDFSelection *selection = [m_wkPDFView.get() _nextMatchFor:string direction:forward caseSensitive:caseFlag wrap:wrapFlag fromSelection:[m_pdfView currentSelection] startInSelection:NO]; + NSUInteger matchCount = [m_wkPDFView.get() _countMatches:string caseSensitive:caseFlag]; + if (matchCount > maxMatchCount) + matchCount = maxMatchCount; + + if (!selection) { + page()->didFailToFindString(string); + return; + } + + [m_pdfView setCurrentSelection:selection]; + [m_pdfView scrollSelectionToVisible:nil]; + page()->didFindString(string, matchCount); +} + +void PDFViewController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) +{ + BOOL caseFlag = !(options & FindOptionsCaseInsensitive); + + NSUInteger matchCount = [m_wkPDFView.get() _countMatches:string caseSensitive:caseFlag]; + if (matchCount > maxMatchCount) + matchCount = maxMatchCount; + page()->didCountStringMatches(string, matchCount); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h index e217fc5..9e08a28 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * 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 @@ -30,8 +30,8 @@ #include "PageClient.h" #include <wtf/RetainPtr.h> +@class WKEditorUndoTargetObjC; @class WKView; -@class WebEditorUndoTargetObjC; namespace WebKit { @@ -63,16 +63,18 @@ private: virtual void processDidCrash(); virtual void pageClosed(); virtual void didRelaunchProcess(); - virtual void setFocus(bool focused); - virtual void takeFocus(bool direction); virtual void toolTipChanged(const String& oldToolTip, const String& newToolTip); virtual void setCursor(const WebCore::Cursor&); virtual void setViewportArguments(const WebCore::ViewportArguments&); virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo); virtual void clearAllEditCommands(); - virtual void interceptKeyEvent(const NativeWebKeyboardEvent& event, Vector<WebCore::KeypressCommand>& commandName, uint32_t selectionStart, uint32_t selectionEnd, Vector<WebCore::CompositionUnderline>& underlines); + virtual bool canUndoRedo(WebPageProxy::UndoOrRedo); + virtual void executeUndoRedo(WebPageProxy::UndoOrRedo); + virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<WebCore::KeypressCommand>&); + virtual bool executeSavedCommandBySelector(const String& selector); virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag); + virtual void updateSecureInputState(); virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&); virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&); @@ -100,10 +102,13 @@ private: virtual double customRepresentationZoomFactor(); virtual void setCustomRepresentationZoomFactor(double); + virtual void findStringInCustomRepresentation(const String&, FindOptions, unsigned maxMatchCount); + virtual void countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned maxMatchCount); virtual void flashBackingStoreUpdates(const Vector<WebCore::IntRect>& updateRects); virtual void didPerformDictionaryLookup(const String&, double scaleFactor, const DictionaryPopupInfo&); + virtual void dismissDictionaryLookupPanel(); virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings); virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel); @@ -113,7 +118,7 @@ private: virtual float userSpaceScaleFactor() const; WKView* m_wkView; - RetainPtr<WebEditorUndoTargetObjC> m_undoTarget; + RetainPtr<WKEditorUndoTargetObjC> m_undoTarget; #if !defined(BUILDING_ON_SNOW_LEOPARD) CorrectionPanel m_correctionPanel; #endif diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm index 7a0d62d..e1888de 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * 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 @@ -52,20 +52,24 @@ @end using namespace WebCore; +using namespace WebKit; -@interface WebEditCommandObjC : NSObject +@interface WKEditCommandObjC : NSObject { - RefPtr<WebKit::WebEditCommandProxy> m_command; + RefPtr<WebEditCommandProxy> m_command; } +- (id)initWithWebEditCommandProxy:(PassRefPtr<WebEditCommandProxy>)command; +- (WebEditCommandProxy*)command; +@end -- (id)initWithWebEditCommandProxy:(PassRefPtr<WebKit::WebEditCommandProxy>)command; -- (WebKit::WebEditCommandProxy*)command; - +@interface WKEditorUndoTargetObjC : NSObject +- (void)undoEditing:(id)sender; +- (void)redoEditing:(id)sender; @end -@implementation WebEditCommandObjC +@implementation WKEditCommandObjC -- (id)initWithWebEditCommandProxy:(PassRefPtr<WebKit::WebEditCommandProxy>)command +- (id)initWithWebEditCommandProxy:(PassRefPtr<WebEditCommandProxy>)command { self = [super init]; if (!self) @@ -75,31 +79,24 @@ using namespace WebCore; return self; } -- (WebKit::WebEditCommandProxy*)command +- (WebEditCommandProxy*)command { return m_command.get(); } @end -@interface WebEditorUndoTargetObjC : NSObject - -- (void)undoEditing:(id)sender; -- (void)redoEditing:(id)sender; - -@end - -@implementation WebEditorUndoTargetObjC +@implementation WKEditorUndoTargetObjC - (void)undoEditing:(id)sender { - ASSERT([sender isKindOfClass:[WebEditCommandObjC class]]); + ASSERT([sender isKindOfClass:[WKEditCommandObjC class]]); [sender command]->unapply(); } - (void)redoEditing:(id)sender { - ASSERT([sender isKindOfClass:[WebEditCommandObjC class]]); + ASSERT([sender isKindOfClass:[WKEditCommandObjC class]]); [sender command]->reapply(); } @@ -119,7 +116,7 @@ PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView) PageClientImpl::PageClientImpl(WKView* wkView) : m_wkView(wkView) - , m_undoTarget(AdoptNS, [[WebEditorUndoTargetObjC alloc] init]) + , m_undoTarget(AdoptNS, [[WKEditorUndoTargetObjC alloc] init]) { } @@ -157,7 +154,7 @@ IntSize PageClientImpl::viewSize() bool PageClientImpl::isViewWindowActive() { - return [[m_wkView window] isKeyWindow]; + return [[m_wkView window] isKeyWindow] || [NSApp keyWindow] == [m_wkView window]; } bool PageClientImpl::isViewFocused() @@ -170,6 +167,9 @@ bool PageClientImpl::isViewVisible() if (![m_wkView window]) return false; + if (![[m_wkView window] isVisible]) + return false; + if ([m_wkView isHiddenOrHasHiddenAncestor]) return false; @@ -196,20 +196,6 @@ void PageClientImpl::didRelaunchProcess() [m_wkView _didRelaunchProcess]; } -void PageClientImpl::setFocus(bool focused) -{ - if (focused) - [[m_wkView window] makeFirstResponder:m_wkView]; - else - // takeFocus in this context means take focus away from the WKView. - takeFocus(true); -} - -void PageClientImpl::takeFocus(bool direction) -{ - [m_wkView _takeFocus:direction]; -} - void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip) { [m_wkView _toolTipChangedFrom:nsStringFromWebCoreString(oldToolTip) to:nsStringFromWebCoreString(newToolTip)]; @@ -223,67 +209,19 @@ void PageClientImpl::setCursor(const WebCore::Cursor& cursor) void PageClientImpl::setViewportArguments(const WebCore::ViewportArguments&) { - -} - -static NSString* nameForEditAction(EditAction editAction) -{ - // FIXME: Use localized strings. - // FIXME: Move this to a platform independent location. - - switch (editAction) { - case EditActionUnspecified: return nil; - case EditActionSetColor: return @"Set Color"; - case EditActionSetBackgroundColor: return @"Set Background Color"; - case EditActionTurnOffKerning: return @"Turn Off Kerning"; - case EditActionTightenKerning: return @"Tighten Kerning"; - case EditActionLoosenKerning: return @"Loosen Kerning"; - case EditActionUseStandardKerning: return @"Use Standard Kerning"; - case EditActionTurnOffLigatures: return @"Turn Off Ligatures"; - case EditActionUseStandardLigatures: return @"Use Standard Ligatures"; - case EditActionUseAllLigatures: return @"Use All Ligatures"; - case EditActionRaiseBaseline: return @"Raise Baseline"; - case EditActionLowerBaseline: return @"Lower Baseline"; - case EditActionSetTraditionalCharacterShape: return @"Set Traditional Character Shape"; - case EditActionSetFont: return @"Set Font"; - case EditActionChangeAttributes: return @"Change Attributes"; - case EditActionAlignLeft: return @"Align Left"; - case EditActionAlignRight: return @"Align Right"; - case EditActionCenter: return @"Center"; - case EditActionJustify: return @"Justify"; - case EditActionSetWritingDirection: return @"Set Writing Direction"; - case EditActionSubscript: return @"Subscript"; - case EditActionSuperscript: return @"Superscript"; - case EditActionUnderline: return @"Underline"; - case EditActionOutline: return @"Outline"; - case EditActionUnscript: return @"Unscript"; - case EditActionDrag: return @"Drag"; - case EditActionCut: return @"Cut"; - case EditActionPaste: return @"Paste"; - case EditActionPasteFont: return @"Paste Font"; - case EditActionPasteRuler: return @"Paste Ruler"; - case EditActionTyping: return @"Typing"; - case EditActionCreateLink: return @"Create Link"; - case EditActionUnlink: return @"Unlink"; - case EditActionInsertList: return @"Insert List"; - case EditActionFormatBlock: return @"Formatting"; - case EditActionIndent: return @"Indent"; - case EditActionOutdent: return @"Outdent"; - } - return nil; } void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo) { RefPtr<WebEditCommandProxy> command = prpCommand; - RetainPtr<WebEditCommandObjC> commandObjC(AdoptNS, [[WebEditCommandObjC alloc] initWithWebEditCommandProxy:command]); - NSString *actionName = nameForEditAction(command->editAction()); + RetainPtr<WKEditCommandObjC> commandObjC(AdoptNS, [[WKEditCommandObjC alloc] initWithWebEditCommandProxy:command]); + String actionName = WebEditCommandProxy::nameForEditAction(command->editAction()); NSUndoManager *undoManager = [m_wkView undoManager]; [undoManager registerUndoWithTarget:m_undoTarget.get() selector:((undoOrRedo == WebPageProxy::Undo) ? @selector(undoEditing:) : @selector(redoEditing:)) object:commandObjC.get()]; - if (actionName) - [undoManager setActionName:actionName]; + if (!actionName.isEmpty()) + [undoManager setActionName:(NSString *)actionName]; } void PageClientImpl::clearAllEditCommands() @@ -291,10 +229,19 @@ void PageClientImpl::clearAllEditCommands() [[m_wkView undoManager] removeAllActionsWithTarget:m_undoTarget.get()]; } -void PageClientImpl::interceptKeyEvent(const NativeWebKeyboardEvent& event, Vector<WebCore::KeypressCommand>& commandsList, uint32_t selectionStart, uint32_t selectionEnd, Vector<WebCore::CompositionUnderline>& underlines) +bool PageClientImpl::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) { - commandsList = [m_wkView _interceptKeyEvent:event.nativeEvent()]; - [m_wkView _getTextInputState:selectionStart selectionEnd:selectionEnd underlines:underlines]; + return (undoOrRedo == WebPageProxy::Undo) ? [[m_wkView undoManager] canUndo] : [[m_wkView undoManager] canRedo]; +} + +void PageClientImpl::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) +{ + return (undoOrRedo == WebPageProxy::Undo) ? [[m_wkView undoManager] undo] : [[m_wkView undoManager] redo]; +} + +bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent& event, Vector<WebCore::KeypressCommand>& commands) +{ + return [m_wkView _interpretKeyEvent:event.nativeEvent() savingCommandsTo:commands]; } void PageClientImpl::setDragImage(const IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) @@ -304,7 +251,12 @@ void PageClientImpl::setDragImage(const IntPoint& clientPosition, PassRefPtr<Sha [m_wkView _setDragImage:dragNSImage.get() at:clientPosition linkDrag:isLinkDrag]; } - + +void PageClientImpl::updateSecureInputState() +{ + [m_wkView _updateSecureInputState]; +} + FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect) { return [m_wkView _convertToDeviceSpace:rect]; @@ -408,6 +360,16 @@ void PageClientImpl::setCustomRepresentationZoomFactor(double zoomFactor) [m_wkView _setCustomRepresentationZoomFactor:zoomFactor]; } +void PageClientImpl::findStringInCustomRepresentation(const String& string, FindOptions options, unsigned maxMatchCount) +{ + [m_wkView _findStringInCustomRepresentation:string withFindOptions:options maxMatchCount:maxMatchCount]; +} + +void PageClientImpl::countStringMatchesInCustomRepresentation(const String& string, FindOptions options, unsigned maxMatchCount) +{ + [m_wkView _countStringMatchesInCustomRepresentation:string withFindOptions:options maxMatchCount:maxMatchCount]; +} + void PageClientImpl::flashBackingStoreUpdates(const Vector<IntRect>&) { notImplemented(); @@ -437,6 +399,13 @@ void PageClientImpl::didPerformDictionaryLookup(const String& text, double scale #endif } +void PageClientImpl::dismissDictionaryLookupPanel() +{ +#if !defined(BUILDING_ON_SNOW_LEOPARD) + WKHideWordDefinitionWindow(); +#endif +} + void PageClientImpl::showCorrectionPanel(CorrectionPanelInfo::PanelType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) { #if !defined(BUILDING_ON_SNOW_LEOPARD) @@ -484,4 +453,9 @@ float PageClientImpl::userSpaceScaleFactor() const #endif } +bool PageClientImpl::executeSavedCommandBySelector(const String& selectorString) +{ + return [m_wkView _executeSavedCommandBySelector:NSSelectorFromString(selectorString)]; +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm index 3b69a1d..2c9ceaa 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKTextInputWindowController.mm @@ -86,7 +86,14 @@ BOOL hadMarkedText = [_inputTextView hasMarkedText]; *string = nil; - + + // Let TSM know that a bottom input window would be created for marked text. + EventRef carbonEvent = static_cast<EventRef>(const_cast<void*>([event eventRef])); + if (carbonEvent) { + Boolean ignorePAH = true; + SetEventParameter(carbonEvent, 'iPAH', typeBoolean, sizeof(ignorePAH), &ignorePAH); + } + if (![[_inputTextView inputContext] handleEvent:event]) return NO; diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.h b/Source/WebKit2/UIProcess/API/mac/WKView.h index 8c1826c..098b3ca 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.h +++ b/Source/WebKit2/UIProcess/API/mac/WKView.h @@ -29,7 +29,7 @@ @class WKViewData; WK_EXPORT -@interface WKView : NSView <NSTextInput> { +@interface WKView : NSView <NSTextInputClient> { WKViewData *_data; unsigned _frameSizeUpdatesDisabledCount; } diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm index 05693ef..80345f7 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm @@ -26,14 +26,17 @@ #import "config.h" #import "WKView.h" +#import "AttributedString.h" #import "ChunkedUpdateDrawingAreaProxy.h" #import "DataReference.h" #import "DrawingAreaProxyImpl.h" +#import "EditorState.h" #import "FindIndicator.h" #import "FindIndicatorWindow.h" #import "LayerTreeContext.h" #import "Logging.h" #import "NativeWebKeyboardEvent.h" +#import "NativeWebMouseEvent.h" #import "PDFViewController.h" #import "PageClientImpl.h" #import "PasteboardTypes.h" @@ -69,24 +72,23 @@ #import <wtf/RefPtr.h> #import <wtf/RetainPtr.h> -@interface NSApplication (WebNSApplicationDetails) +@interface NSApplication (WKNSApplicationDetails) - (void)speakString:(NSString *)string; - (void)_setCurrentEvent:(NSEvent *)event; @end -@interface NSWindow (WebNSWindowDetails) +@interface NSObject (WKNSTextInputContextDetails) +- (BOOL)wantsToHandleMouseEvents; +- (BOOL)handleMouseEvent:(NSEvent *)event; +@end + +@interface NSWindow (WKNSWindowDetails) - (NSRect)_growBoxRect; - (id)_growBoxOwner; - (void)_setShowOpaqueGrowBoxForOwner:(id)owner; - (BOOL)_updateGrowBoxForWindowFrameChange; @end -extern "C" { - // Need to declare this attribute name because AppKit exports it but does not make it available in API or SPI headers. - // <rdar://problem/8631468> tracks the request to make it available. This code should be removed when the bug is closed. - extern NSString *NSTextInputReplacementRangeAttributeName; -} - using namespace WebKit; using namespace WebCore; @@ -98,6 +100,13 @@ typedef HashMap<String, ValidationVector> ValidationMap; } +struct WKViewInterpretKeyEventsParameters { + bool eventInterpretationHadSideEffects; + bool consumedByIM; + bool executingSavedKeypressCommands; + Vector<KeypressCommand>* commands; +}; + @interface WKViewData : NSObject { @public OwnPtr<PageClientImpl> _pageClient; @@ -122,18 +131,13 @@ typedef HashMap<String, ValidationVector> ValidationMap; // the application to distinguish the case of a new event from one // that has been already sent to WebCore. RetainPtr<NSEvent> _keyDownEventBeingResent; - bool _isInInterpretKeyEvents; - Vector<KeypressCommand> _commandsList; + WKViewInterpretKeyEventsParameters* _interpretKeyEventsParameters; NSSize _resizeScrollOffset; // The identifier of the plug-in we want to send complex text input to, or 0 if there is none. uint64_t _pluginComplexTextInputIdentifier; - Vector<CompositionUnderline> _underlines; - unsigned _selectionStart; - unsigned _selectionEnd; - bool _inBecomeFirstResponder; bool _inResignFirstResponder; NSEvent *_mouseDownEvent; @@ -150,15 +154,21 @@ typedef HashMap<String, ValidationVector> ValidationMap; BOOL _hasSpellCheckerDocumentTag; NSInteger _spellCheckerDocumentTag; + + BOOL _inSecureInputState; } @end -@implementation WKViewData +@interface WKResponderChainSink : NSResponder { + NSResponder *_lastResponderInChain; + bool _didReceiveUnhandledCommand; +} +- (id)initWithResponderChain:(NSResponder *)chain; +- (void)detach; +- (bool)didReceiveUnhandledCommand; @end -@interface NSObject (NSTextInputContextDetails) -- (BOOL)wantsToHandleMouseEvents; -- (BOOL)handleMouseEvent:(NSEvent *)event; +@implementation WKViewData @end @implementation WKView @@ -239,6 +249,8 @@ typedef HashMap<String, ValidationVector> ValidationMap; { _data->_page->close(); + ASSERT(!_data->_inSecureInputState); + [_data release]; _data = nil; @@ -282,7 +294,10 @@ typedef HashMap<String, ValidationVector> ValidationMap; NSSelectionDirection direction = [[self window] keyViewSelectionDirection]; _data->_inBecomeFirstResponder = true; + + [self _updateSecureInputState]; _data->_page->viewStateDidChange(WebPageProxy::ViewIsFocused); + _data->_inBecomeFirstResponder = false; if (direction != NSDirectSelection) @@ -294,7 +309,13 @@ typedef HashMap<String, ValidationVector> ValidationMap; - (BOOL)resignFirstResponder { _data->_inResignFirstResponder = true; + + if (_data->_inSecureInputState) { + DisableSecureEventInput(); + _data->_inSecureInputState = NO; + } _data->_page->viewStateDidChange(WebPageProxy::ViewIsFocused); + _data->_inResignFirstResponder = false; return YES; @@ -514,13 +535,13 @@ WEBCORE_COMMAND(yankAndSelect) - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType { - BOOL isValidSendType = !sendType || ([PasteboardTypes::forSelection() containsObject:sendType] && !_data->_page->selectionState().isNone); + BOOL isValidSendType = !sendType || ([PasteboardTypes::forSelection() containsObject:sendType] && !_data->_page->editorState().selectionIsNone); BOOL isValidReturnType = NO; if (!returnType) isValidReturnType = YES; - else if ([PasteboardTypes::forEditing() containsObject:returnType] && _data->_page->selectionState().isContentEditable) { + else if ([PasteboardTypes::forEditing() containsObject:returnType] && _data->_page->editorState().isContentEditable) { // We can insert strings in any editable context. We can insert other types, like images, only in rich edit contexts. - isValidReturnType = _data->_page->selectionState().isContentRichlyEditable || [returnType isEqualToString:NSStringPboardType]; + isValidReturnType = _data->_page->editorState().isContentRichlyEditable || [returnType isEqualToString:NSStringPboardType]; } if (isValidSendType && isValidReturnType) return self; @@ -604,12 +625,12 @@ static void validateCommandCallback(WKStringRef commandName, bool isEnabled, int if (action == @selector(showGuessPanel:)) { if (NSMenuItem *menuItem = ::menuItem(item)) - [menuItem setTitle:contextMenuItemTagShowSpellingPanel([[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible])]; - return _data->_page->selectionState().isContentEditable; + [menuItem setTitle:contextMenuItemTagShowSpellingPanel(![[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible])]; + return _data->_page->editorState().isContentEditable; } if (action == @selector(checkSpelling:) || action == @selector(changeSpelling:)) - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; if (action == @selector(toggleContinuousSpellChecking:)) { bool enabled = TextChecker::isContinuousSpellCheckingAllowed(); @@ -627,47 +648,47 @@ static void validateCommandCallback(WKStringRef commandName, bool isEnabled, int if (action == @selector(toggleAutomaticSpellingCorrection:)) { bool checked = TextChecker::state().isAutomaticSpellingCorrectionEnabled; [menuItem(item) setState:checked ? NSOnState : NSOffState]; - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; } if (action == @selector(orderFrontSubstitutionsPanel:)) { if (NSMenuItem *menuItem = ::menuItem(item)) - [menuItem setTitle:contextMenuItemTagShowSubstitutions([[[NSSpellChecker sharedSpellChecker] substitutionsPanel] isVisible])]; - return _data->_page->selectionState().isContentEditable; + [menuItem setTitle:contextMenuItemTagShowSubstitutions(![[[NSSpellChecker sharedSpellChecker] substitutionsPanel] isVisible])]; + return _data->_page->editorState().isContentEditable; } if (action == @selector(toggleSmartInsertDelete:)) { bool checked = _data->_page->isSmartInsertDeleteEnabled(); [menuItem(item) setState:checked ? NSOnState : NSOffState]; - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; } if (action == @selector(toggleAutomaticQuoteSubstitution:)) { bool checked = TextChecker::state().isAutomaticQuoteSubstitutionEnabled; [menuItem(item) setState:checked ? NSOnState : NSOffState]; - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; } if (action == @selector(toggleAutomaticDashSubstitution:)) { bool checked = TextChecker::state().isAutomaticDashSubstitutionEnabled; [menuItem(item) setState:checked ? NSOnState : NSOffState]; - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; } if (action == @selector(toggleAutomaticLinkDetection:)) { bool checked = TextChecker::state().isAutomaticLinkDetectionEnabled; [menuItem(item) setState:checked ? NSOnState : NSOffState]; - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; } if (action == @selector(toggleAutomaticTextReplacement:)) { bool checked = TextChecker::state().isAutomaticTextReplacementEnabled; [menuItem(item) setState:checked ? NSOnState : NSOffState]; - return _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().isContentEditable; } if (action == @selector(uppercaseWord:) || action == @selector(lowercaseWord:) || action == @selector(capitalizeWord:)) - return _data->_page->selectionState().selectedRangeLength && _data->_page->selectionState().isContentEditable; + return _data->_page->editorState().selectionIsRange && _data->_page->editorState().isContentEditable; if (action == @selector(stopSpeaking:)) return [NSApp isSpeaking]; @@ -751,9 +772,6 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) TextChecker::setContinuousSpellCheckingEnabled(spellCheckingEnabled); _data->_page->process()->updateTextCheckerState(); - - if (!spellCheckingEnabled) - _data->_page->unmarkAllMisspellings(); } - (BOOL)isGrammarCheckingEnabled @@ -768,9 +786,6 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) TextChecker::setGrammarCheckingEnabled(flag); _data->_page->process()->updateTextCheckerState(); - - if (!flag) - _data->_page->unmarkAllBadGrammar(); } - (IBAction)toggleGrammarChecking:(id)sender @@ -779,9 +794,6 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) TextChecker::setGrammarCheckingEnabled(grammarCheckingEnabled); _data->_page->process()->updateTextCheckerState(); - - if (!grammarCheckingEnabled) - _data->_page->unmarkAllBadGrammar(); } - (IBAction)toggleAutomaticSpellingCorrection:(id)sender @@ -927,6 +939,33 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) _data->_mouseDownEvent = [event retain]; } +#define NATIVE_MOUSE_EVENT_HANDLER(Selector) \ + - (void)Selector:(NSEvent *)theEvent \ + { \ + if ([[self inputContext] handleEvent:theEvent]) { \ + LOG(TextInput, "%s was handled by text input context", String(#Selector).substring(0, String(#Selector).find("Internal")).ascii().data()); \ + return; \ + } \ + NativeWebMouseEvent webEvent(theEvent, self); \ + _data->_page->handleMouseEvent(webEvent); \ + } + +NATIVE_MOUSE_EVENT_HANDLER(mouseEntered) +NATIVE_MOUSE_EVENT_HANDLER(mouseExited) +NATIVE_MOUSE_EVENT_HANDLER(mouseMovedInternal) +NATIVE_MOUSE_EVENT_HANDLER(mouseDownInternal) +NATIVE_MOUSE_EVENT_HANDLER(mouseUpInternal) +NATIVE_MOUSE_EVENT_HANDLER(mouseDraggedInternal) +NATIVE_MOUSE_EVENT_HANDLER(otherMouseDown) +NATIVE_MOUSE_EVENT_HANDLER(otherMouseDragged) +NATIVE_MOUSE_EVENT_HANDLER(otherMouseMoved) +NATIVE_MOUSE_EVENT_HANDLER(otherMouseUp) +NATIVE_MOUSE_EVENT_HANDLER(rightMouseDown) +NATIVE_MOUSE_EVENT_HANDLER(rightMouseDragged) +NATIVE_MOUSE_EVENT_HANDLER(rightMouseUp) + +#undef NATIVE_MOUSE_EVENT_HANDLER + #define EVENT_HANDLER(Selector, Type) \ - (void)Selector:(NSEvent *)theEvent \ { \ @@ -934,28 +973,17 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) _data->_page->handle##Type##Event(webEvent); \ } -EVENT_HANDLER(mouseEntered, Mouse) -EVENT_HANDLER(mouseExited, Mouse) -EVENT_HANDLER(mouseMoved, Mouse) -EVENT_HANDLER(otherMouseDown, Mouse) -EVENT_HANDLER(otherMouseDragged, Mouse) -EVENT_HANDLER(otherMouseMoved, Mouse) -EVENT_HANDLER(otherMouseUp, Mouse) -EVENT_HANDLER(rightMouseDown, Mouse) -EVENT_HANDLER(rightMouseDragged, Mouse) -EVENT_HANDLER(rightMouseMoved, Mouse) -EVENT_HANDLER(rightMouseUp, Mouse) EVENT_HANDLER(scrollWheel, Wheel) #undef EVENT_HANDLER -- (void)_mouseHandler:(NSEvent *)event +- (void)mouseMoved:(NSEvent *)event { - NSInputManager *currentInputManager = [NSInputManager currentInputManager]; - if ([currentInputManager wantsToHandleMouseEvents] && [currentInputManager handleMouseEvent:event]) + // When a view is first responder, it gets mouse moved events even when the mouse is outside its visible rect. + if (self == [[self window] firstResponder] && !NSPointInRect([self convertPoint:[event locationInWindow] fromView:nil], [self visibleRect])) return; - WebMouseEvent webEvent = WebEventFactory::createWebMouseEvent(event, self); - _data->_page->handleMouseEvent(webEvent); + + [self mouseMovedInternal:event]; } - (void)mouseDown:(NSEvent *)event @@ -963,20 +991,57 @@ EVENT_HANDLER(scrollWheel, Wheel) [self _setMouseDownEvent:event]; _data->_ignoringMouseDraggedEvents = NO; _data->_dragHasStarted = NO; - [self _mouseHandler:event]; + [self mouseDownInternal:event]; } - (void)mouseUp:(NSEvent *)event { [self _setMouseDownEvent:nil]; - [self _mouseHandler:event]; + [self mouseUpInternal:event]; } - (void)mouseDragged:(NSEvent *)event { if (_data->_ignoringMouseDraggedEvents) return; - [self _mouseHandler:event]; + [self mouseDraggedInternal:event]; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)event +{ + // There's a chance that responding to this event will run a nested event loop, and + // fetching a new event might release the old one. Retaining and then autoreleasing + // the current event prevents that from causing a problem inside WebKit or AppKit code. + [[event retain] autorelease]; + + if (![self hitTest:[event locationInWindow]]) + return NO; + + [self _setMouseDownEvent:event]; + bool result = _data->_page->acceptsFirstMouse([event eventNumber], WebEventFactory::createWebMouseEvent(event, self)); + [self _setMouseDownEvent:nil]; + return result; +} + +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)event +{ + // If this is the active window or we don't have a range selection, there is no need to perform additional checks + // and we can avoid making a synchronous call to the WebProcess. + if ([[self window] isKeyWindow] || _data->_page->editorState().selectionIsNone || !_data->_page->editorState().selectionIsRange) + return NO; + + // There's a chance that responding to this event will run a nested event loop, and + // fetching a new event might release the old one. Retaining and then autoreleasing + // the current event prevents that from causing a problem inside WebKit or AppKit code. + [[event retain] autorelease]; + + if (![self hitTest:[event locationInWindow]]) + return NO; + + [self _setMouseDownEvent:event]; + bool result = _data->_page->shouldDelayWindowOrderingForEvent(WebEventFactory::createWebMouseEvent(event, self)); + [self _setMouseDownEvent:nil]; + return result; } #if ENABLE(GESTURE_EVENTS) @@ -1018,52 +1083,75 @@ static const short kIOHIDEventTypeScroll = 6; { LOG(TextInput, "doCommandBySelector:\"%s\"", sel_getName(selector)); - if (!_data->_isInInterpretKeyEvents) { + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + if (parameters) + parameters->consumedByIM = false; + + // As in insertText:replacementRange:, we assume that the call comes from an input method if there is marked text. + bool isFromInputMethod = _data->_page->editorState().hasComposition; + + if (parameters && !isFromInputMethod) + parameters->commands->append(KeypressCommand(NSStringFromSelector(selector))); + else { + // FIXME: Send the command to Editor synchronously and only send it along the + // responder chain if it's a selector that does not correspond to an editing command. [super doCommandBySelector:selector]; - return; } - if (selector != @selector(noop:)) - _data->_commandsList.append(KeypressCommand(commandNameForSelector(selector))); } - (void)insertText:(id)string { - BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; // Otherwise, NSString - - LOG(TextInput, "insertText:\"%@\"", isAttributedString ? [string string] : string); + // Unlike and NSTextInputClient variant with replacementRange, this NSResponder method is called when there is no input context, + // so text input processing isn't performed. We are not going to actually insert any text in that case, but saving an insertText + // command ensures that a keypress event is dispatched as appropriate. + [self insertText:string replacementRange:NSMakeRange(NSNotFound, 0)]; +} + +- (void)insertText:(id)string replacementRange:(NSRange)replacementRange +{ + BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; + ASSERT(isAttributedString || [string isKindOfClass:[NSString class]]); + + if (replacementRange.location != NSNotFound) + LOG(TextInput, "insertText:\"%@\" replacementRange:(%u, %u)", isAttributedString ? [string string] : string, replacementRange.location, replacementRange.length); + else + LOG(TextInput, "insertText:\"%@\"", isAttributedString ? [string string] : string); + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + if (parameters) + parameters->consumedByIM = false; + NSString *text; - bool isFromInputMethod = _data->_page->selectionState().hasComposition; + bool isFromInputMethod = _data->_page->editorState().hasComposition; if (isAttributedString) { + // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data. text = [string string]; - // We deal with the NSTextInputReplacementRangeAttributeName attribute from NSAttributedString here - // simply because it is used by at least one Input Method -- it corresonds to the kEventParamTextInputSendReplaceRange - // event in TSM. This behaviour matches that of -[WebHTMLView setMarkedText:selectedRange:] when it receives an - // NSAttributedString - NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:NULL inRange:NSMakeRange(0, [text length])]; - LOG(TextInput, "ReplacementRange: %@", rangeString); - if (rangeString) - isFromInputMethod = YES; } else text = string; + // insertText can be called for several reasons: + // - If it's from normal key event processing (including key bindings), we may need to save the action to perform it later. + // - If it's from an input method, then we should go ahead and insert the text now. We assume it's from the input method if we have marked text. + // FIXME: In theory, this could be wrong for some input methods, so we should try to find another way to determine if the call is from the input method. + // - If it's sent outside of keyboard event processing (e.g. from Character Viewer, or when confirming an inline input area with a mouse), + // then we also execute it immediately, as there will be no other chance. + if (parameters && !isFromInputMethod) { + ASSERT(replacementRange.location == NSNotFound); + parameters->commands->append(KeypressCommand("insertText:", text)); + return; + } + String eventText = text; - - // We'd need a different code path here if we wanted to be able to handle this - // outside of interpretKeyEvents. - ASSERT(_data->_isInInterpretKeyEvents); + eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore + bool eventHandled = _data->_page->insertText(eventText, replacementRange.location, NSMaxRange(replacementRange)); - if (!isFromInputMethod) - _data->_commandsList.append(KeypressCommand("insertText", text)); - else { - eventText.replace(NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore - _data->_commandsList.append(KeypressCommand("insertText", eventText)); - } + if (parameters) + parameters->eventInterpretationHadSideEffects |= eventHandled; } - (BOOL)_handleStyleKeyEquivalent:(NSEvent *)event { - if (!_data->_page->selectionState().isContentEditable) + if (!_data->_page->editorState().isContentEditable) return NO; if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) != NSCommandKeyMask) @@ -1130,9 +1218,6 @@ static const short kIOHIDEventTypeScroll = 6; } } - _data->_underlines.clear(); - _data->_selectionStart = 0; - _data->_selectionEnd = 0; // We could be receiving a key down from AppKit if we have re-sent an event // that maps to an action that is currently unavailable (for example a copy when // there is no range selection). @@ -1144,37 +1229,108 @@ static const short kIOHIDEventTypeScroll = 6; _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, self)); } -- (NSTextInputContext *)inputContext { - if (_data->_pluginComplexTextInputIdentifier && !_data->_isInInterpretKeyEvents) +- (void)flagsChanged:(NSEvent *)theEvent +{ + // There's a chance that responding to this event will run a nested event loop, and + // fetching a new event might release the old one. Retaining and then autoreleasing + // the current event prevents that from causing a problem inside WebKit or AppKit code. + [[theEvent retain] autorelease]; + + unsigned short keyCode = [theEvent keyCode]; + + // Don't make an event from the num lock and function keys + if (!keyCode || keyCode == 10 || keyCode == 63) + return; + + _data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(theEvent, self)); +} + +- (void)_executeSavedKeypressCommands +{ + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + if (!parameters || parameters->commands->isEmpty()) + return; + + // We could be called again if the execution of one command triggers a call to selectedRange. + // In this case, the state is up to date, and we don't need to execute any more saved commands to return a result. + if (parameters->executingSavedKeypressCommands) + return; + + parameters->executingSavedKeypressCommands = true; + parameters->eventInterpretationHadSideEffects |= _data->_page->executeKeypressCommands(*parameters->commands); + parameters->commands->clear(); + parameters->executingSavedKeypressCommands = false; +} + +- (NSTextInputContext *)inputContext +{ + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + + if (_data->_pluginComplexTextInputIdentifier && !parameters) return [[WKTextInputWindowController sharedTextInputWindowController] inputContext]; + // Disable text input machinery when in non-editable content. An invisible inline input area affects performance, and can prevent Expose from working. + if (!_data->_page->editorState().isContentEditable) + return nil; + return [super inputContext]; } - (NSRange)selectedRange { - if (_data->_page->selectionState().isNone || !_data->_page->selectionState().isContentEditable) - return NSMakeRange(NSNotFound, 0); - - LOG(TextInput, "selectedRange -> (%u, %u)", _data->_page->selectionState().selectedRangeStart, _data->_page->selectionState().selectedRangeLength); - return NSMakeRange(_data->_page->selectionState().selectedRangeStart, _data->_page->selectionState().selectedRangeLength); + [self _executeSavedKeypressCommands]; + + uint64_t selectionStart; + uint64_t selectionLength; + _data->_page->getSelectedRange(selectionStart, selectionLength); + + NSRange result = NSMakeRange(selectionStart, selectionLength); + if (result.location == NSNotFound) + LOG(TextInput, "selectedRange -> (NSNotFound, %u)", result.length); + else + LOG(TextInput, "selectedRange -> (%u, %u)", result.location, result.length); + + return result; } - (BOOL)hasMarkedText { - LOG(TextInput, "hasMarkedText -> %u", _data->_page->selectionState().hasComposition); - return _data->_page->selectionState().hasComposition; + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + + BOOL result; + if (parameters) { + result = _data->_page->editorState().hasComposition; + if (result) { + // A saved command can confirm a composition, but it cannot start a new one. + [self _executeSavedKeypressCommands]; + result = _data->_page->editorState().hasComposition; + } + } else { + uint64_t location; + uint64_t length; + _data->_page->getMarkedRange(location, length); + result = location != NSNotFound; + } + + LOG(TextInput, "hasMarkedText -> %u", result); + return result; } - (void)unmarkText { + [self _executeSavedKeypressCommands]; + LOG(TextInput, "unmarkText"); - // We'd need a different code path here if we wanted to be able to handle this - // outside of interpretKeyEvents. - ASSERT(_data->_isInInterpretKeyEvents); + // Use pointer to get parameters passed to us by the caller of interpretKeyEvents. + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + + if (parameters) { + parameters->eventInterpretationHadSideEffects = true; + parameters->consumedByIM = false; + } - _data->_commandsList.append(KeypressCommand("unmarkText")); + _data->_page->confirmComposition(); } - (NSArray *)validAttributesForMarkedText @@ -1183,7 +1339,7 @@ static const short kIOHIDEventTypeScroll = 6; if (!validAttributes) { validAttributes = [[NSArray alloc] initWithObjects: NSUnderlineStyleAttributeName, NSUnderlineColorAttributeName, - NSMarkedClauseSegmentAttributeName, NSTextInputReplacementRangeAttributeName, nil]; + NSMarkedClauseSegmentAttributeName, nil]; // NSText also supports the following attributes, but it's // hard to tell which are really required for text input to // work well; I have not seen any input method make use of them yet. @@ -1215,47 +1371,86 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde } } -- (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange +- (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange replacementRange:(NSRange)replacementRange { - BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; // Otherwise, NSString - + [self _executeSavedKeypressCommands]; + + BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]]; + ASSERT(isAttributedString || [string isKindOfClass:[NSString class]]); + LOG(TextInput, "setMarkedText:\"%@\" selectedRange:(%u, %u)", isAttributedString ? [string string] : string, newSelRange.location, newSelRange.length); + + // Use pointer to get parameters passed to us by the caller of interpretKeyEvents. + WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; + + if (parameters) { + parameters->eventInterpretationHadSideEffects = true; + parameters->consumedByIM = false; + } - NSString *text = string; - + Vector<CompositionUnderline> underlines; + NSString *text; + if (isAttributedString) { + // FIXME: We ignore most attributes from the string, so an input method cannot specify e.g. a font or a glyph variation. text = [string string]; - extractUnderlines(string, _data->_underlines); + extractUnderlines(string, underlines); + } else + text = string; + + if (_data->_page->editorState().isInPasswordField) { + // In password fields, we only allow ASCII dead keys, and don't allow inline input, matching NSSecureTextInputField. + // Allowing ASCII dead keys is necessary to enable full Roman input when using a Vietnamese keyboard. + ASSERT(!_data->_page->editorState().hasComposition); + [[super inputContext] discardMarkedText]; // Inform the input method that we won't have an inline input area despite having been asked to. + if ([text length] == 1 && [[text decomposedStringWithCanonicalMapping] characterAtIndex:0] < 0x80) { + _data->_page->insertText(text, replacementRange.location, NSMaxRange(replacementRange)); + } else + NSBeep(); + return; } - - // We'd need a different code path here if we wanted to be able to handle this - // outside of interpretKeyEvents. - ASSERT(_data->_isInInterpretKeyEvents); - _data->_commandsList.append(KeypressCommand("setMarkedText", text)); - _data->_selectionStart = newSelRange.location; - _data->_selectionEnd = NSMaxRange(newSelRange); + _data->_page->setComposition(text, underlines, newSelRange.location, NSMaxRange(newSelRange), replacementRange.location, NSMaxRange(replacementRange)); } - (NSRange)markedRange { + [self _executeSavedKeypressCommands]; + uint64_t location; uint64_t length; - _data->_page->getMarkedRange(location, length); + LOG(TextInput, "markedRange -> (%u, %u)", location, length); return NSMakeRange(location, length); } -- (NSAttributedString *)attributedSubstringFromRange:(NSRange)nsRange +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)nsRange actualRange:(NSRangePointer)actualRange { - // This is not implemented for now. Need to figure out how to serialize the attributed string across processes. - LOG(TextInput, "attributedSubstringFromRange"); - return nil; + [self _executeSavedKeypressCommands]; + + if (!_data->_page->editorState().isContentEditable) { + LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> nil", nsRange.location, nsRange.length); + return nil; + } + + if (_data->_page->editorState().isInPasswordField) + return nil; + + AttributedString result; + _data->_page->getAttributedSubstringFromRange(nsRange.location, NSMaxRange(nsRange), result); + + if (actualRange) + *actualRange = nsRange; + + LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> \"%@\"", nsRange.location, nsRange.length, [result.string.get() string]); + return [[result.string.get() retain] autorelease]; } - (NSUInteger)characterIndexForPoint:(NSPoint)thePoint { + [self _executeSavedKeypressCommands]; + NSWindow *window = [self window]; if (window) @@ -1267,8 +1462,10 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde return result; } -- (NSRect)firstRectForCharacterRange:(NSRange)theRange +- (NSRect)firstRectForCharacterRange:(NSRange)theRange actualRange:(NSRangePointer)actualRange { + [self _executeSavedKeypressCommands]; + // Just to match NSTextView's behavior. Regression tests cannot detect this; // to reproduce, use a test application from http://bugs.webkit.org/show_bug.cgi?id=4682 // (type something; try ranges (1, -1) and (2, -1). @@ -1281,7 +1478,10 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde NSWindow *window = [self window]; if (window) resultRect.origin = [window convertBaseToScreen:resultRect.origin]; - + + if (actualRange) + *actualRange = theRange; + LOG(TextInput, "firstRectForCharacterRange:(%u, %u) -> (%f, %f, %f, %f)", theRange.location, theRange.length, resultRect.origin.x, resultRect.origin.y, resultRect.size.width, resultRect.size.height); return resultRect; } @@ -1318,7 +1518,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde DragData dragData(draggingInfo, client, global, static_cast<DragOperation>([draggingInfo draggingSourceOperationMask]), [self applicationFlags:draggingInfo]); _data->_page->resetDragOperation(); - _data->_page->performDragControllerAction(DragControllerActionEntered, &dragData, [[draggingInfo draggingPasteboard] name]); + _data->_page->dragEntered(&dragData, [[draggingInfo draggingPasteboard] name]); return NSDragOperationCopy; } @@ -1327,7 +1527,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde IntPoint client([self convertPoint:[draggingInfo draggingLocation] fromView:nil]); IntPoint global(globalPoint([draggingInfo draggingLocation], [self window])); DragData dragData(draggingInfo, client, global, static_cast<DragOperation>([draggingInfo draggingSourceOperationMask]), [self applicationFlags:draggingInfo]); - _data->_page->performDragControllerAction(DragControllerActionUpdated, &dragData, [[draggingInfo draggingPasteboard] name]); + _data->_page->dragUpdated(&dragData, [[draggingInfo draggingPasteboard] name]); return _data->_page->dragOperation(); } @@ -1336,7 +1536,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde IntPoint client([self convertPoint:[draggingInfo draggingLocation] fromView:nil]); IntPoint global(globalPoint([draggingInfo draggingLocation], [self window])); DragData dragData(draggingInfo, client, global, static_cast<DragOperation>([draggingInfo draggingSourceOperationMask]), [self applicationFlags:draggingInfo]); - _data->_page->performDragControllerAction(DragControllerActionExited, &dragData, [[draggingInfo draggingPasteboard] name]); + _data->_page->dragExited(&dragData, [[draggingInfo draggingPasteboard] name]); _data->_page->resetDragOperation(); } @@ -1345,15 +1545,53 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde return YES; } +// FIXME: This code is more or less copied from Pasteboard::getBestURL. +// It would be nice to be able to share the code somehow. +static void maybeCreateSandboxExtensionFromPasteboard(NSPasteboard *pasteboard, SandboxExtension::Handle& sandboxExtensionHandle) +{ + NSArray *types = [pasteboard types]; + if (![types containsObject:NSFilenamesPboardType]) + return; + + NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType]; + if ([files count] != 1) + return; + + NSString *file = [files objectAtIndex:0]; + BOOL isDirectory; + if (![[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory]) + return; + + if (isDirectory) + return; + + SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle); +} + - (BOOL)performDragOperation:(id <NSDraggingInfo>)draggingInfo { IntPoint client([self convertPoint:[draggingInfo draggingLocation] fromView:nil]); IntPoint global(globalPoint([draggingInfo draggingLocation], [self window])); DragData dragData(draggingInfo, client, global, static_cast<DragOperation>([draggingInfo draggingSourceOperationMask]), [self applicationFlags:draggingInfo]); - _data->_page->performDragControllerAction(DragControllerActionPerformDrag, &dragData, [[draggingInfo draggingPasteboard] name]); + + SandboxExtension::Handle sandboxExtensionHandle; + maybeCreateSandboxExtensionFromPasteboard([draggingInfo draggingPasteboard], sandboxExtensionHandle); + + _data->_page->performDrag(&dragData, [[draggingInfo draggingPasteboard] name], sandboxExtensionHandle); + return YES; } +// This code is needed to support drag and drop when the drag types cannot be matched. +// This is the case for elements that do not place content +// in the drag pasteboard automatically when the drag start (i.e. dragging a DIV element). +- (NSView *)_hitTest:(NSPoint *)point dragTypes:(NSSet *)types +{ + if ([[self superview] mouse:*point inRect:[self frame]]) + return self; + return nil; +} + - (void)_updateWindowVisibility { _data->_page->updateWindowIsVisible(![[self window] isMiniaturized]); @@ -1423,6 +1661,10 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde name:NSWindowDidMoveNotification object:window]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowFrameDidChange:) name:NSWindowDidResizeNotification object:window]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidOrderOffScreen:) + name:@"NSWindowDidOrderOffScreenNotification" object:window]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidOrderOnScreen:) + name:@"_NSWindowDidBecomeVisible" object:window]; } } @@ -1438,6 +1680,8 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidMoveNotification object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResizeNotification object:window]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSWindowDidOrderOffScreenNotification" object:window]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"_NSWindowDidBecomeVisible" object:window]; } - (void)viewWillMoveToWindow:(NSWindow *)window @@ -1492,15 +1736,19 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde - (void)_windowDidBecomeKey:(NSNotification *)notification { NSWindow *keyWindow = [notification object]; - if (keyWindow == [self window] || keyWindow == [[self window] attachedSheet]) + if (keyWindow == [self window] || keyWindow == [[self window] attachedSheet]) { + [self _updateSecureInputState]; _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); + } } - (void)_windowDidResignKey:(NSNotification *)notification { NSWindow *formerKeyWindow = [notification object]; - if (formerKeyWindow == [self window] || formerKeyWindow == [[self window] attachedSheet]) + if (formerKeyWindow == [self window] || formerKeyWindow == [[self window] attachedSheet]) { + [self _updateSecureInputState]; _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); + } } - (void)_windowDidMiniaturize:(NSNotification *)notification @@ -1518,6 +1766,16 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde [self _updateWindowAndViewFrames]; } +- (void)_windowDidOrderOffScreen:(NSNotification *)notification +{ + _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); +} + +- (void)_windowDidOrderOnScreen:(NSNotification *)notification +{ + _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); +} + static void drawPageBackground(CGContextRef context, WebPageProxy* page, const IntRect& rect) { if (!page->drawsBackground()) @@ -1667,6 +1925,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I // NSPrintOperation takes ownership of the view. NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:printingView.get()]; [printOperation setCanSpawnSeparateThread:YES]; + [printOperation setJobTitle:toImpl(frameRef)->title()]; printingView->_printOperation = printOperation; return printOperation; } @@ -1706,14 +1965,6 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I [self setNeedsDisplay:YES]; } -- (void)_takeFocus:(BOOL)forward -{ - if (forward) - [[self window] selectKeyViewFollowingView:self]; - else - [[self window] selectKeyViewPrecedingView:self]; -} - - (void)_setCursor:(NSCursor *)cursor { if ([NSCursor currentCursor] == cursor) @@ -1744,27 +1995,34 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I _data->_keyDownEventBeingResent = nullptr; } -- (Vector<KeypressCommand>&)_interceptKeyEvent:(NSEvent *)theEvent +- (BOOL)_interpretKeyEvent:(NSEvent *)event savingCommandsTo:(Vector<WebCore::KeypressCommand>&)commands { - ASSERT(!_data->_isInInterpretKeyEvents); + ASSERT(!_data->_interpretKeyEventsParameters); + ASSERT(commands.isEmpty()); - _data->_isInInterpretKeyEvents = true; - _data->_commandsList.clear(); + if ([event type] == NSFlagsChanged) + return NO; - // Calling interpretKeyEvents will trigger one or more calls to doCommandBySelector and insertText - // that will populate the commandsList vector. - [self interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + WKViewInterpretKeyEventsParameters parameters; + parameters.eventInterpretationHadSideEffects = false; + parameters.executingSavedKeypressCommands = false; + // We assume that an input method has consumed the event, and only change this assumption if one of the NSTextInput methods is called. + // We assume the IM will *not* consume hotkey sequences. + parameters.consumedByIM = !([event modifierFlags] & NSCommandKeyMask); + parameters.commands = &commands; + _data->_interpretKeyEventsParameters = ¶meters; - _data->_isInInterpretKeyEvents = false; + [self interpretKeyEvents:[NSArray arrayWithObject:event]]; - return _data->_commandsList; -} + _data->_interpretKeyEventsParameters = 0; -- (void)_getTextInputState:(unsigned)start selectionEnd:(unsigned)end underlines:(Vector<CompositionUnderline>&)lines -{ - start = _data->_selectionStart; - end = _data->_selectionEnd; - lines = _data->_underlines; + // An input method may consume an event and not tell us (e.g. when displaying a candidate window), + // in which case we should not bubble the event up the DOM. + if (parameters.consumedByIM) + return YES; + + // If we have already executed all or some of the commands, the event is "handled". Note that there are additional checks on web process side. + return parameters.eventInterpretationHadSideEffects; } - (NSRect)_convertToDeviceSpace:(NSRect)rect @@ -2010,6 +2268,22 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I _data->_pdfViewController->setZoomFactor(zoomFactor); } +- (void)_findStringInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count +{ + if (!_data->_pdfViewController) + return; + + _data->_pdfViewController->findString(string, options, count); +} + +- (void)_countStringMatchesInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count +{ + if (!_data->_pdfViewController) + return; + + _data->_pdfViewController->countStringMatches(string, options, count); +} + - (void)_setDragImage:(NSImage *)image at:(NSPoint)clientPoint linkDrag:(BOOL)linkDrag { // We need to prevent re-entering this call to avoid crashing in AppKit. @@ -2028,6 +2302,32 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I _data->_dragHasStarted = NO; } +- (void)_updateSecureInputState +{ + if (![[self window] isKeyWindow] || ([[self window] firstResponder] != self && !_data->_inBecomeFirstResponder)) { + if (_data->_inSecureInputState) { + DisableSecureEventInput(); + _data->_inSecureInputState = NO; + } + return; + } + // WKView has a single input context for all editable areas (except for plug-ins). + NSTextInputContext *context = [super inputContext]; + bool isInPasswordField = _data->_page->editorState().isInPasswordField; + + if (isInPasswordField) { + if (!_data->_inSecureInputState) + EnableSecureEventInput(); + static NSArray *romanInputSources = [[NSArray alloc] initWithObjects:&NSAllRomanInputSourcesLocaleIdentifier count:1]; + [context setAllowedInputSourceLocales:romanInputSources]; + } else { + if (_data->_inSecureInputState) + DisableSecureEventInput(); + [context setAllowedInputSourceLocales:nil]; + } + _data->_inSecureInputState = isInPasswordField; +} + - (void)_setDrawingAreaSize:(NSSize)size { if (!_data->_page->drawingArea()) @@ -2053,6 +2353,16 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I } #endif +- (bool)_executeSavedCommandBySelector:(SEL)selector +{ + // The sink does two things: 1) Tells us if the responder went unhandled, and + // 2) prevents any NSBeep; we don't ever want to beep here. + RetainPtr<WKResponderChainSink> sink(AdoptNS, [[WKResponderChainSink alloc] initWithResponderChain:self]); + [super doCommandBySelector:selector]; + [sink.get() detach]; + return ![sink.get() didReceiveUnhandledCommand]; +} + @end @implementation WKView (Private) @@ -2101,3 +2411,45 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I @end +@implementation WKResponderChainSink + +- (id)initWithResponderChain:(NSResponder *)chain +{ + self = [super init]; + if (!self) + return nil; + _lastResponderInChain = chain; + while (NSResponder *next = [_lastResponderInChain nextResponder]) + _lastResponderInChain = next; + [_lastResponderInChain setNextResponder:self]; + return self; +} + +- (void)detach +{ + [_lastResponderInChain setNextResponder:nil]; + _lastResponderInChain = nil; +} + +- (bool)didReceiveUnhandledCommand +{ + return _didReceiveUnhandledCommand; +} + +- (void)noResponderFor:(SEL)selector +{ + _didReceiveUnhandledCommand = true; +} + +- (void)doCommandBySelector:(SEL)selector +{ + _didReceiveUnhandledCommand = true; +} + +- (BOOL)tryToPerform:(SEL)action with:(id)object +{ + _didReceiveUnhandledCommand = true; + return YES; +} + +@end diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h index e4a40f7..82acdcf 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h @@ -24,22 +24,25 @@ */ #import "WKView.h" -#import <WebCore/Editor.h> -#import <WebCore/KeyboardEvent.h> +#import "WebFindOptions.h" +#import <wtf/Forward.h> +#import <wtf/Vector.h> namespace CoreIPC { class DataReference; } +namespace WebCore { + struct KeypressCommand; +} + namespace WebKit { class DrawingAreaProxy; class FindIndicator; class LayerTreeContext; } -#if ENABLE(FULLSCREEN_API) @class WKFullScreenWindowController; -#endif @interface WKView (Internal) - (PassOwnPtr<WebKit::DrawingAreaProxy>)_createDrawingAreaProxy; @@ -47,13 +50,12 @@ namespace WebKit { - (void)_processDidCrash; - (void)_pageClosed; - (void)_didRelaunchProcess; -- (void)_takeFocus:(BOOL)direction; - (void)_toolTipChangedFrom:(NSString *)oldToolTip to:(NSString *)newToolTip; - (void)_setCursor:(NSCursor *)cursor; - (void)_setUserInterfaceItemState:(NSString *)commandName enabled:(BOOL)isEnabled state:(int)newState; -- (Vector<WebCore::KeypressCommand>&)_interceptKeyEvent:(NSEvent *)theEvent; -- (void)_getTextInputState:(unsigned)start selectionEnd:(unsigned)end underlines:(Vector<WebCore::CompositionUnderline>&)lines; +- (BOOL)_interpretKeyEvent:(NSEvent *)theEvent savingCommandsTo:(Vector<WebCore::KeypressCommand>&)commands; - (void)_resendKeyDownEvent:(NSEvent *)event; +- (bool)_executeSavedCommandBySelector:(SEL)selector; - (NSRect)_convertToDeviceSpace:(NSRect)rect; - (NSRect)_convertToUserSpace:(NSRect)rect; - (void)_setFindIndicator:(PassRefPtr<WebKit::FindIndicator>)findIndicator fadeOut:(BOOL)fadeOut; @@ -68,7 +70,10 @@ namespace WebKit { - (void)_didFinishLoadingDataForCustomRepresentationWithSuggestedFilename:(const String&)suggestedFilename dataReference:(const CoreIPC::DataReference&)dataReference; - (double)_customRepresentationZoomFactor; - (void)_setCustomRepresentationZoomFactor:(double)zoomFactor; +- (void)_findStringInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count; +- (void)_countStringMatchesInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count; - (void)_setDragImage:(NSImage *)image at:(NSPoint)clientPoint linkDrag:(BOOL)linkDrag; +- (void)_updateSecureInputState; - (void)_setDrawingAreaSize:(NSSize)size; diff --git a/Source/WebKit2/UIProcess/API/qt/ClientImpl.cpp b/Source/WebKit2/UIProcess/API/qt/ClientImpl.cpp index 8197236..b427058 100644 --- a/Source/WebKit2/UIProcess/API/qt/ClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/qt/ClientImpl.cpp @@ -165,6 +165,17 @@ void qt_wk_close(WKPageRef page, const void* clientInfo) emit toQWKPage(clientInfo)->windowCloseRequested(); } +void qt_wk_takeFocus(WKPageRef page, WKFocusDirection direction, const void *clientInfo) +{ + emit toQWKPage(clientInfo)->focusNextPrevChild(direction == kWKFocusDirectionForward); +} + void qt_wk_runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo) { } + +void qt_wk_setStatusText(WKPageRef page, WKStringRef text, const void *clientInfo) +{ + QString qText = WKStringCopyQString(text); + emit toQWKPage(clientInfo)->statusBarMessage(qText); +} diff --git a/Source/WebKit2/UIProcess/API/qt/ClientImpl.h b/Source/WebKit2/UIProcess/API/qt/ClientImpl.h index 5d8c062..7955144 100644 --- a/Source/WebKit2/UIProcess/API/qt/ClientImpl.h +++ b/Source/WebKit2/UIProcess/API/qt/ClientImpl.h @@ -48,7 +48,9 @@ void qt_wk_didBecomeResponsive(WKPageRef, const void* clientInfo); WKPageRef qt_wk_createNewPage(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo); void qt_wk_showPage(WKPageRef page, const void *clientInfo); void qt_wk_close(WKPageRef page, const void *clientInfo); +void qt_wk_takeFocus(WKPageRef page, WKFocusDirection direction, const void *clientInfo); void qt_wk_runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo); +void qt_wk_setStatusText(WKPageRef page, WKStringRef text, const void *clientInfo); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/qt/WKView.h b/Source/WebKit2/UIProcess/API/qt/WKView.h index 5bb95e8..57a5458 100644 --- a/Source/WebKit2/UIProcess/API/qt/WKView.h +++ b/Source/WebKit2/UIProcess/API/qt/WKView.h @@ -22,6 +22,7 @@ #include <WebKit2/qgraphicswkview.h> #include <WebKit2/qwkcontext.h> +#include <WebKit2/qwkhistory.h> #include <WebKit2/qwkpage.h> #include <WebKit2/qwkpreferences.h> diff --git a/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp b/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp index 0381d73..d85ade3 100644 --- a/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp @@ -50,6 +50,7 @@ struct QGraphicsWKViewPrivate { QGraphicsWKViewPrivate(QGraphicsWKView* view); WKPageRef pageRef() const { return page->pageRef(); } + void onToolTipChanged(const QString&); void onScaleChanged(); void commitScale(); @@ -84,6 +85,7 @@ QGraphicsWKView::QGraphicsWKView(QWKContext* context, BackingStoreType backingSt connect(d->page, SIGNAL(cursorChanged(const QCursor&)), this, SLOT(updateCursor(const QCursor&))); connect(d->page, SIGNAL(focusNextPrevChild(bool)), this, SLOT(focusNextPrevChildCallback(bool))); connect(d->page, SIGNAL(showContextMenu(QSharedPointer<QMenu>)), this, SLOT(showContextMenu(QSharedPointer<QMenu>))); + connect(d->page, SIGNAL(toolTipChanged(QString)), this, SLOT(onToolTipChanged(QString))); } QGraphicsWKView::~QGraphicsWKView() @@ -424,6 +426,11 @@ void QGraphicsWKViewPrivate::onScaleChanged() #endif } +void QGraphicsWKViewPrivate::onToolTipChanged(const QString& toolTip) +{ + q->setToolTip(toolTip); +} + void QGraphicsWKViewPrivate::commitScale() { #if ENABLE(TILED_BACKING_STORE) diff --git a/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.h b/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.h index 03fc722..e4aecdd 100644 --- a/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.h +++ b/Source/WebKit2/UIProcess/API/qt/qgraphicswkview.h @@ -90,7 +90,8 @@ protected: virtual void focusOutEvent(QFocusEvent*); private: - Q_PRIVATE_SLOT(d, void onScaleChanged()); + Q_PRIVATE_SLOT(d, void onScaleChanged()) + Q_PRIVATE_SLOT(d, void onToolTipChanged(const QString&)) QGraphicsWKViewPrivate* d; friend class QGraphicsWKViewPrivate; diff --git a/Source/WebKit2/UIProcess/API/qt/qwkhistory.h b/Source/WebKit2/UIProcess/API/qt/qwkhistory.h index 81081c9..cf1c842 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwkhistory.h +++ b/Source/WebKit2/UIProcess/API/qt/qwkhistory.h @@ -25,10 +25,10 @@ #ifndef qwkhistory_h #define qwkhistory_h +#include "WebKit2/WKBackForwardListItem.h" #include "qwebkitglobal.h" #include <QObject> #include <QSharedData> -#include "WKBackForwardListItem.h" class QWKHistoryPrivate; class QWKHistoryItemPrivate; @@ -49,7 +49,7 @@ public: QUrl url() const; private: - QWKHistoryItem(WKBackForwardListItemRef item); + QWKHistoryItem(WKBackForwardListItemRef); QExplicitlySharedDataPointer<QWKHistoryItemPrivate> d; diff --git a/Source/WebKit2/UIProcess/API/qt/qwkpage.cpp b/Source/WebKit2/UIProcess/API/qt/qwkpage.cpp index a162918..7eb78da 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwkpage.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwkpage.cpp @@ -34,6 +34,7 @@ #include "FindIndicator.h" #include "LocalizedStrings.h" #include "NativeWebKeyboardEvent.h" +#include "NativeWebMouseEvent.h" #include "NotImplemented.h" #include "TiledDrawingAreaProxy.h" #include "WebContext.h" @@ -125,11 +126,6 @@ void QWKPagePrivate::setViewportArguments(const ViewportArguments& args) emit q->viewportChangeRequested(); } -void QWKPagePrivate::takeFocus(bool direction) -{ - emit q->focusNextPrevChild(direction); -} - PassOwnPtr<DrawingAreaProxy> QWKPagePrivate::createDrawingAreaProxy() { // FIXME: We should avoid this cast by decoupling the view from the page. @@ -206,7 +202,7 @@ void QWKPagePrivate::didChangeContentsSize(const IntSize& newSize) void QWKPagePrivate::toolTipChanged(const String&, const String& newTooltip) { - emit q->statusBarMessage(QString(newTooltip)); + emit q->toolTipChanged(QString(newTooltip)); } void QWKPagePrivate::registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo) @@ -217,6 +213,15 @@ void QWKPagePrivate::clearAllEditCommands() { } +bool QWKPagePrivate::canUndoRedo(WebPageProxy::UndoOrRedo) +{ + return false; +} + +void QWKPagePrivate::executeUndoRedo(WebPageProxy::UndoOrRedo) +{ +} + FloatRect QWKPagePrivate::convertToDeviceSpace(const FloatRect& rect) { return rect; @@ -297,32 +302,27 @@ void QWKPagePrivate::mouseMoveEvent(QGraphicsSceneMouseEvent* ev) return; lastPos = ev->pos(); - WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0); - page->handleMouseEvent(mouseEvent); + page->handleMouseEvent(NativeWebMouseEvent(ev, 0)); } void QWKPagePrivate::mousePressEvent(QGraphicsSceneMouseEvent* ev) { if (tripleClickTimer.isActive() && (ev->pos() - tripleClick).manhattanLength() < QApplication::startDragDistance()) { - WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 3); - page->handleMouseEvent(mouseEvent); + page->handleMouseEvent(NativeWebMouseEvent(ev, 3)); return; } - WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 1); - page->handleMouseEvent(mouseEvent); + page->handleMouseEvent(NativeWebMouseEvent(ev, 1)); } void QWKPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) { - WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 0); - page->handleMouseEvent(mouseEvent); + page->handleMouseEvent(NativeWebMouseEvent(ev, 0)); } void QWKPagePrivate::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev) { - WebMouseEvent mouseEvent = WebEventFactory::createWebMouseEvent(ev, 2); - page->handleMouseEvent(mouseEvent); + page->handleMouseEvent(NativeWebMouseEvent(ev, 2)); tripleClickTimer.start(QApplication::doubleClickInterval(), q); tripleClick = ev->pos().toPoint(); @@ -458,10 +458,13 @@ QWKPage::QWKPage(QWKContext* context) qt_wk_createNewPage, qt_wk_showPage, qt_wk_close, + qt_wk_takeFocus, + 0, /* focus */ + 0, /* unfocus */ qt_wk_runJavaScriptAlert, 0, /* runJavaScriptConfirm */ 0, /* runJavaScriptPrompt */ - 0, /* setStatusText */ + qt_wk_setStatusText, 0, /* mouseDidMoveOverElement */ 0, /* missingPluginButtonClicked */ 0, /* didNotHandleKeyEvent */ diff --git a/Source/WebKit2/UIProcess/API/qt/qwkpage.h b/Source/WebKit2/UIProcess/API/qt/qwkpage.h index 48fdd9f..5dcfad2 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwkpage.h +++ b/Source/WebKit2/UIProcess/API/qt/qwkpage.h @@ -48,7 +48,7 @@ public: WebActionCount }; - class ViewportAttributes { + class QWEBKIT_EXPORT ViewportAttributes { public: ViewportAttributes(); ViewportAttributes(const QWKPage::ViewportAttributes& other); @@ -122,6 +122,7 @@ public: public: Q_SIGNAL void statusBarMessage(const QString&); + Q_SIGNAL void toolTipChanged(const QString&); Q_SIGNAL void titleChanged(const QString&); Q_SIGNAL void loadStarted(); Q_SIGNAL void loadFinished(bool ok); diff --git a/Source/WebKit2/UIProcess/API/qt/qwkpage_p.h b/Source/WebKit2/UIProcess/API/qt/qwkpage_p.h index ee1fb0e..d2fd26b 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwkpage_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwkpage_p.h @@ -71,11 +71,11 @@ public: virtual void didFindZoomableArea(const WebCore::IntRect&); virtual void setCursor(const WebCore::Cursor&); virtual void setViewportArguments(const WebCore::ViewportArguments&); - virtual void takeFocus(bool direction); - virtual void setFocus(bool focused) { } virtual void toolTipChanged(const WTF::String&, const WTF::String&); virtual void registerEditCommand(PassRefPtr<WebKit::WebEditCommandProxy>, WebKit::WebPageProxy::UndoOrRedo); virtual void clearAllEditCommands(); + virtual bool canUndoRedo(WebPageProxy::UndoOrRedo); + virtual void executeUndoRedo(WebPageProxy::UndoOrRedo); virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&); virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&); virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&); @@ -94,7 +94,8 @@ public: virtual void didChangeScrollbarsForMainFrame() const { } virtual void flashBackingStoreUpdates(const Vector<WebCore::IntRect>& updateRects); - + virtual void findStringInCustomRepresentation(const String&, FindOptions, unsigned maxMatchCount) { } + virtual void countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned maxMatchCount) { } virtual float userSpaceScaleFactor() const { return 1; } void paint(QPainter* painter, QRect); |