blob: 1a9434af0f5dcae3db158034b464320b866c1dca [file] [log] [blame]
/*
* Copyright (C) 2009 Collabora Ltd.
* Copyright (C) 2009 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "webkithittestresult.h"
#include "Frame.h"
#include "FrameView.h"
#include "HitTestResult.h"
#include "KURL.h"
#include "WebKitDOMBinding.h"
#include "WebKitDOMNode.h"
#include "webkitenumtypes.h"
#include "webkitglobals.h"
#include "webkitglobalsprivate.h"
#include <glib/gi18n-lib.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
#include <wtf/text/CString.h>
/**
* SECTION:webkithittestresult
* @short_description: The target of a mouse event
*
* This class holds context information about the coordinates
* specified by a GDK event.
*/
G_DEFINE_TYPE(WebKitHitTestResult, webkit_hit_test_result, G_TYPE_OBJECT)
struct _WebKitHitTestResultPrivate {
guint context;
char* linkURI;
char* imageURI;
char* mediaURI;
GRefPtr<WebKitDOMNode> innerNode;
WebCore::IntPoint position;
};
enum {
PROP_0,
PROP_CONTEXT,
PROP_LINK_URI,
PROP_IMAGE_URI,
PROP_MEDIA_URI,
PROP_INNER_NODE,
PROP_X,
PROP_Y
};
static void webkit_hit_test_result_finalize(GObject* object)
{
WebKitHitTestResult* web_hit_test_result = WEBKIT_HIT_TEST_RESULT(object);
WebKitHitTestResultPrivate* priv = web_hit_test_result->priv;
g_free(priv->linkURI);
g_free(priv->imageURI);
g_free(priv->mediaURI);
G_OBJECT_CLASS(webkit_hit_test_result_parent_class)->finalize(object);
}
static void webkit_hit_test_result_dispose(GObject* object)
{
WEBKIT_HIT_TEST_RESULT(object)->priv->~WebKitHitTestResultPrivate();
G_OBJECT_CLASS(webkit_hit_test_result_parent_class)->dispose(object);
}
static void webkit_hit_test_result_get_property(GObject* object, guint propertyID, GValue* value, GParamSpec* pspec)
{
WebKitHitTestResult* web_hit_test_result = WEBKIT_HIT_TEST_RESULT(object);
WebKitHitTestResultPrivate* priv = web_hit_test_result->priv;
switch(propertyID) {
case PROP_CONTEXT:
g_value_set_flags(value, priv->context);
break;
case PROP_LINK_URI:
g_value_set_string(value, priv->linkURI);
break;
case PROP_IMAGE_URI:
g_value_set_string(value, priv->imageURI);
break;
case PROP_MEDIA_URI:
g_value_set_string(value, priv->mediaURI);
break;
case PROP_INNER_NODE:
g_value_set_object(value, priv->innerNode.get());
break;
case PROP_X:
g_value_set_int(value, priv->position.x());
break;
case PROP_Y:
g_value_set_int(value, priv->position.y());
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec);
}
}
static void webkit_hit_test_result_set_property(GObject* object, guint propertyID, const GValue* value, GParamSpec* pspec)
{
WebKitHitTestResult* web_hit_test_result = WEBKIT_HIT_TEST_RESULT(object);
WebKitHitTestResultPrivate* priv = web_hit_test_result->priv;
switch(propertyID) {
case PROP_CONTEXT:
priv->context = g_value_get_flags(value);
break;
case PROP_LINK_URI:
g_free (priv->linkURI);
priv->linkURI = g_value_dup_string(value);
break;
case PROP_IMAGE_URI:
g_free (priv->imageURI);
priv->imageURI = g_value_dup_string(value);
break;
case PROP_MEDIA_URI:
g_free (priv->mediaURI);
priv->mediaURI = g_value_dup_string(value);
break;
case PROP_INNER_NODE:
priv->innerNode = static_cast<WebKitDOMNode*>(g_value_get_object(value));
break;
case PROP_X:
priv->position.setX(g_value_get_int(value));
break;
case PROP_Y:
priv->position.setY(g_value_get_int(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec);
}
}
static void webkit_hit_test_result_class_init(WebKitHitTestResultClass* webHitTestResultClass)
{
GObjectClass* objectClass = G_OBJECT_CLASS(webHitTestResultClass);
objectClass->finalize = webkit_hit_test_result_finalize;
objectClass->dispose = webkit_hit_test_result_dispose;
objectClass->get_property = webkit_hit_test_result_get_property;
objectClass->set_property = webkit_hit_test_result_set_property;
webkitInit();
/**
* WebKitHitTestResult:context:
*
* Flags indicating the kind of target that received the event.
*
* Since: 1.1.15
*/
g_object_class_install_property(objectClass, PROP_CONTEXT,
g_param_spec_flags("context",
_("Context"),
_("Flags indicating the kind of target that received the event."),
WEBKIT_TYPE_HIT_TEST_RESULT_CONTEXT,
WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT,
static_cast<GParamFlags>((WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY))));
/**
* WebKitHitTestResult:link-uri:
*
* The URI to which the target that received the event points, if any.
*
* Since: 1.1.15
*/
g_object_class_install_property(objectClass, PROP_LINK_URI,
g_param_spec_string("link-uri",
_("Link URI"),
_("The URI to which the target that received the event points, if any."),
NULL,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)));
/**
* WebKitHitTestResult:image-uri:
*
* The URI of the image that is part of the target that received the event, if any.
*
* Since: 1.1.15
*/
g_object_class_install_property(objectClass, PROP_IMAGE_URI,
g_param_spec_string("image-uri",
_("Image URI"),
_("The URI of the image that is part of the target that received the event, if any."),
NULL,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)));
/**
* WebKitHitTestResult:media-uri:
*
* The URI of the media that is part of the target that received the event, if any.
*
* Since: 1.1.15
*/
g_object_class_install_property(objectClass, PROP_MEDIA_URI,
g_param_spec_string("media-uri",
_("Media URI"),
_("The URI of the media that is part of the target that received the event, if any."),
NULL,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)));
/**
* WebKitHitTestResult:inner-node:
*
* The DOM node at the coordinates where the hit test
* happened. Keep in mind that the node might not be
* representative of the information given in the context
* property, since WebKit uses a series of heuristics to figure
* out that information. One common example is inner-node having
* the text node inside the anchor (&lt;a&gt;) tag; WebKit knows the
* whole context and will put WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
* in the 'context' property, but the user might be confused by
* the lack of any link tag in 'inner-node'.
*
* Since: 1.3.2
*/
g_object_class_install_property(objectClass, PROP_INNER_NODE,
g_param_spec_object("inner-node",
_("Inner node"),
_("The inner DOM node associated with the hit test result."),
WEBKIT_TYPE_DOM_NODE,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
/**
* WebKitHitTestResult:x:
*
* The x coordinate of the event relative to the view's window.
*
* Since: 1.10
*/
g_object_class_install_property(objectClass, PROP_X,
g_param_spec_int("x",
_("X coordinate"),
_("The x coordinate of the event relative to the view's window."),
G_MININT, G_MAXINT, 0,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
/**
* WebKitHitTestResult:y:
*
* The x coordinate of the event relative to the view's window.
*
* Since: 1.10
*/
g_object_class_install_property(objectClass, PROP_Y,
g_param_spec_int("y",
_("Y coordinate"),
_("The y coordinate of the event relative to the view's window."),
G_MININT, G_MAXINT, 0,
static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
g_type_class_add_private(webHitTestResultClass, sizeof(WebKitHitTestResultPrivate));
}
static void webkit_hit_test_result_init(WebKitHitTestResult* web_hit_test_result)
{
web_hit_test_result->priv = G_TYPE_INSTANCE_GET_PRIVATE(web_hit_test_result, WEBKIT_TYPE_HIT_TEST_RESULT, WebKitHitTestResultPrivate);
new (web_hit_test_result->priv) WebKitHitTestResultPrivate();
}
namespace WebKit {
WebKitHitTestResult* kit(const WebCore::HitTestResult& result)
{
guint context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT;
GOwnPtr<char> linkURI(0);
GOwnPtr<char> imageURI(0);
GOwnPtr<char> mediaURI(0);
WebKitDOMNode* node = 0;
WebCore::Frame* targetFrame;
WebCore::IntPoint point;
if (!result.absoluteLinkURL().isEmpty()) {
context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK;
linkURI.set(g_strdup(result.absoluteLinkURL().string().utf8().data()));
}
if (!result.absoluteImageURL().isEmpty()) {
context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
imageURI.set(g_strdup(result.absoluteImageURL().string().utf8().data()));
}
if (!result.absoluteMediaURL().isEmpty()) {
context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;
mediaURI.set(g_strdup(result.absoluteMediaURL().string().utf8().data()));
}
if (result.isSelected())
context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
if (result.isContentEditable())
context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
if (result.innerNonSharedNode())
node = kit(result.innerNonSharedNode());
targetFrame = result.targetFrame();
if (targetFrame && targetFrame->view()) {
// Convert document coords to widget coords.
point = targetFrame->view()->contentsToWindow(result.roundedPoint());
} else
point = result.roundedPoint();
return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT,
"link-uri", linkURI.get(),
"image-uri", imageURI.get(),
"media-uri", mediaURI.get(),
"context", context,
"inner-node", node,
"x", point.x(),
"y", point.y(),
NULL));
}
}