WebKitFindController.cpp [plain text]
#include "config.h"
#include "WebKitFindController.h"
#include "WebKitEnumTypes.h"
#include "WebKitPrivate.h"
#include "WebKitWebViewBasePrivate.h"
#include <glib/gi18n-lib.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
using namespace WebCore;
enum {
FOUND_TEXT,
FAILED_TO_FIND_TEXT,
COUNTED_MATCHES,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_TEXT,
PROP_OPTIONS,
PROP_MAX_MATCH_COUNT,
PROP_WEB_VIEW
};
typedef enum {
FindOperation,
CountOperation
} WebKitFindControllerOperation;
struct _WebKitFindControllerPrivate {
CString searchText;
uint32_t findOptions;
unsigned maxMatchCount;
WebKitWebView* webView;
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE(WebKitFindController, webkit_find_controller, G_TYPE_OBJECT)
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, kWKFindOptionsCaseInsensitive);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, kWKFindOptionsAtWordStarts);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, kWKFindOptionsTreatMedialCapitalAsWordStart);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_BACKWARDS, kWKFindOptionsBackwards);
COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_WRAP_AROUND, kWKFindOptionsWrapAround);
static void didFindString(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo)
{
g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FOUND_TEXT], 0, matchCount);
}
static void didFailToFindString(WKPageRef page, WKStringRef string, const void* clientInfo)
{
g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FAILED_TO_FIND_TEXT], 0);
}
static void didCountStringMatches(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo)
{
g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[COUNTED_MATCHES], 0, matchCount);
}
static void webkit_find_controller_init(WebKitFindController* findController)
{
WebKitFindControllerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(findController, WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerPrivate);
findController->priv = priv;
new (priv) WebKitFindControllerPrivate();
}
static WKPageRef inline getWKPageFromWebKitWebView(WebKitWebView* webView)
{
return toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)));
}
static void webkitFindControllerConstructed(GObject* object)
{
WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object);
WKPageFindClient wkFindClient = {
kWKPageFindClientCurrentVersion,
findController, didFindString,
didFailToFindString,
didCountStringMatches
};
WKPageSetPageFindClient(getWKPageFromWebKitWebView(findController->priv->webView), &wkFindClient);
}
static void webkitFindControllerGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
{
WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object);
switch (propId) {
case PROP_TEXT:
g_value_set_string(value, webkit_find_controller_get_search_text(findController));
break;
case PROP_OPTIONS:
g_value_set_uint(value, webkit_find_controller_get_options(findController));
break;
case PROP_MAX_MATCH_COUNT:
g_value_set_uint(value, webkit_find_controller_get_max_match_count(findController));
break;
case PROP_WEB_VIEW:
g_value_set_object(value, webkit_find_controller_get_web_view(findController));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
}
}
static void webkitFindControllerSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
{
WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object);
switch (propId) {
case PROP_WEB_VIEW:
findController->priv->webView = WEBKIT_WEB_VIEW(g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
}
}
static void webkitFindControllerFinalize(GObject* object)
{
WEBKIT_FIND_CONTROLLER(object)->priv->~WebKitFindControllerPrivate();
G_OBJECT_CLASS(webkit_find_controller_parent_class)->finalize(object);
}
static void webkit_find_controller_class_init(WebKitFindControllerClass* findClass)
{
GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass);
gObjectClass->constructed = webkitFindControllerConstructed;
gObjectClass->get_property = webkitFindControllerGetProperty;
gObjectClass->set_property = webkitFindControllerSetProperty;
gObjectClass->finalize = webkitFindControllerFinalize;
g_type_class_add_private(findClass, sizeof(WebKitFindControllerPrivate));
g_object_class_install_property(gObjectClass,
PROP_TEXT,
g_param_spec_string("text",
_("Search text"),
_("Text to search for in the view"),
0,
WEBKIT_PARAM_READABLE));
g_object_class_install_property(gObjectClass,
PROP_OPTIONS,
g_param_spec_flags("options",
_("Search Options"),
_("Search options to be used in the search operation"),
WEBKIT_TYPE_FIND_OPTIONS,
WEBKIT_FIND_OPTIONS_NONE,
WEBKIT_PARAM_READABLE));
g_object_class_install_property(gObjectClass,
PROP_MAX_MATCH_COUNT,
g_param_spec_uint("max-match-count",
_("Maximum matches count"),
_("The maximum number of matches in a given text to report"),
0, G_MAXUINT, 0,
WEBKIT_PARAM_READABLE));
g_object_class_install_property(gObjectClass,
PROP_WEB_VIEW,
g_param_spec_object("web-view",
_("WebView"),
_("The WebView associated with this find controller"),
WEBKIT_TYPE_WEB_VIEW,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
signals[FOUND_TEXT] =
g_signal_new("found-text",
G_TYPE_FROM_CLASS(gObjectClass),
G_SIGNAL_RUN_LAST,
0, 0, 0,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
signals[FAILED_TO_FIND_TEXT] =
g_signal_new("failed-to-find-text",
G_TYPE_FROM_CLASS(gObjectClass),
G_SIGNAL_RUN_LAST,
0, 0, 0,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[COUNTED_MATCHES] =
g_signal_new("counted-matches",
G_TYPE_FROM_CLASS(gObjectClass),
G_SIGNAL_RUN_LAST,
0, 0, 0,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1, G_TYPE_UINT);
}
const char* webkit_find_controller_get_search_text(WebKitFindController* findController)
{
g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0);
return findController->priv->searchText.data();
}
guint32 webkit_find_controller_get_options(WebKitFindController* findController)
{
g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), WEBKIT_FIND_OPTIONS_NONE);
return findController->priv->findOptions;
}
guint webkit_find_controller_get_max_match_count(WebKitFindController* findController)
{
g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0);
return findController->priv->maxMatchCount;
}
WebKitWebView* webkit_find_controller_get_web_view(WebKitFindController* findController)
{
g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0);
return findController->priv->webView;
}
static void webKitFindControllerPerform(WebKitFindController* findController, WebKitFindControllerOperation operation)
{
WKFindOptions wkFindOptions = static_cast<WKFindOptions>(findController->priv->findOptions);
WKRetainPtr<WKStringRef> wkSearchText(AdoptWK, WKStringCreateWithUTF8CString(findController->priv->searchText.data()));
WKPageRef wkPage = getWKPageFromWebKitWebView(findController->priv->webView);
if (operation == FindOperation) {
wkFindOptions = static_cast<WKFindOptions>(findController->priv->findOptions | kWKFindOptionsShowHighlight);
WKPageFindString(wkPage, wkSearchText.get(), wkFindOptions, findController->priv->maxMatchCount);
return;
}
WKPageCountStringMatches(wkPage, wkSearchText.get(), wkFindOptions, findController->priv->maxMatchCount);
}
static inline void webKitFindControllerSetSearchData(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount)
{
findController->priv->searchText = searchText;
findController->priv->findOptions = findOptions;
findController->priv->maxMatchCount = maxMatchCount;
}
void webkit_find_controller_search(WebKitFindController* findController, const gchar* searchText, guint findOptions, guint maxMatchCount)
{
g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
g_return_if_fail(searchText);
webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount);
webKitFindControllerPerform(findController, FindOperation);
}
void webkit_find_controller_search_next(WebKitFindController* findController)
{
g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
findController->priv->findOptions = findController->priv->findOptions & ~WEBKIT_FIND_OPTIONS_BACKWARDS;
webKitFindControllerPerform(findController, FindOperation);
}
void webkit_find_controller_search_previous(WebKitFindController* findController)
{
g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
findController->priv->findOptions = findController->priv->findOptions | WEBKIT_FIND_OPTIONS_BACKWARDS;
webKitFindControllerPerform(findController, FindOperation);
}
void webkit_find_controller_count_matches(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount)
{
g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
g_return_if_fail(searchText);
webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount);
webKitFindControllerPerform(findController, CountOperation);
}
void webkit_find_controller_search_finish(WebKitFindController* findController)
{
g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController));
WKPageHideFindUI(getWKPageFromWebKitWebView(findController->priv->webView));
}