--- /dev/null
+#include "dom.h"
+#include "main.h"
+
+static gboolean dom_auto_insert(WebKitDOMElement* element);
+static gboolean dom_editable_focus_cb(WebKitDOMElement* element, WebKitDOMEvent* event);
+static gboolean dom_is_editable(WebKitDOMElement* element);
+static WebKitDOMElement* dom_get_active_element(WebKitDOMDocument* doc);
+
+
+void dom_check_auto_insert(void)
+{
+ WebKitDOMDocument* doc = webkit_web_view_get_dom_document(vp.gui.webview);
+ WebKitDOMElement* active = dom_get_active_element(doc);
+ if (!dom_auto_insert(active)) {
+ WebKitDOMHTMLElement *element = webkit_dom_document_get_body(doc);
+ if (!element) {
+ element = WEBKIT_DOM_HTML_ELEMENT(webkit_dom_document_get_document_element(doc));
+ }
+ webkit_dom_event_target_add_event_listener(
+ WEBKIT_DOM_EVENT_TARGET(element), "focus", G_CALLBACK(dom_editable_focus_cb), true, NULL
+ );
+ }
+}
+
+static gboolean dom_auto_insert(WebKitDOMElement* element)
+{
+ if (dom_is_editable(element)) {
+ Arg a = {VP_MODE_INSERT};
+ vp_set_mode(&a);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean dom_editable_focus_cb(WebKitDOMElement* element, WebKitDOMEvent* event)
+{
+ webkit_dom_event_target_remove_event_listener(
+ WEBKIT_DOM_EVENT_TARGET(element), "focus", G_CALLBACK(dom_editable_focus_cb), true
+ );
+ if (CLEAN_MODE(vp.state.mode) != VP_MODE_INSERT) {
+ WebKitDOMEventTarget* target = webkit_dom_event_get_target(event);
+ dom_auto_insert((void*)target);
+ }
+ return FALSE;
+}
+
+/**
+ * Indicates if the given dom element is an editable element like text input,
+ * password or textarea.
+ */
+static gboolean dom_is_editable(WebKitDOMElement* element)
+{
+ if (!element) {
+ return FALSE;
+ }
+
+ gchar* tagname = webkit_dom_node_get_node_name(WEBKIT_DOM_NODE(element));
+ if (!g_strcmp0(tagname, "TEXTAREA")) {
+ return TRUE;
+ }
+ if (!g_strcmp0(tagname, "INPUT")) {
+ gchar *type = webkit_dom_element_get_attribute((void*)element, "type");
+ if (!g_strcmp0(type, "text") || !g_strcmp0(type, "password")) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static WebKitDOMElement* dom_get_active_element(WebKitDOMDocument* doc)
+{
+ WebKitDOMDocument* d = NULL;
+ WebKitDOMElement* active = webkit_dom_html_document_get_active_element((void*)doc);
+ gchar* tagname = webkit_dom_element_get_tag_name(active);
+
+ if (!g_strcmp0(tagname, "FRAME")) {
+ d = webkit_dom_html_frame_element_get_content_document(WEBKIT_DOM_HTML_FRAME_ELEMENT(active));
+ return dom_get_active_element(d);
+ }
+ if (!g_strcmp0(tagname, "IFRAME")) {
+ d = webkit_dom_html_iframe_element_get_content_document(WEBKIT_DOM_HTML_IFRAME_ELEMENT(active));
+ return dom_get_active_element(d);
+ }
+ return active;
+}
+
#include "setting.h"
#include "config.h"
#include "completion.h"
+#include "dom.h"
/* variables */
VpCore vp;
static void vp_init_gui(void);
static void vp_init_files(void);
static void vp_setup_signals(void);
+static gboolean vp_notify_event_cb(GtkWidget* widget, GdkEvent* event, gpointer data);
#ifdef FEATURE_COOKIE
static void vp_set_cookie(SoupCookie* cookie);
static const gchar* vp_get_cookies(SoupURI *uri);
break;
case WEBKIT_LOAD_FINISHED:
+ dom_check_auto_insert();
break;
case WEBKIT_LOAD_FAILED:
case VP_MODE_INSERT:
gtk_widget_grab_focus(GTK_WIDGET(vp.gui.webview));
+ vp_echo(VP_MSG_NORMAL, FALSE, "-- INPUT --");
break;
case VP_MODE_PATH_THROUGH:
* instance is closed, the program will exit */
g_signal_connect(gui->window, "destroy", G_CALLBACK(vp_destroy_window_cb), NULL);
g_signal_connect(G_OBJECT(gui->webview), "notify::load-status", G_CALLBACK(vp_webview_load_status_cb), NULL);
+ g_object_connect(
+ G_OBJECT(gui->webview),
+ "signal::event", G_CALLBACK(vp_notify_event_cb), NULL,
+ NULL
+ );
g_object_connect(
G_OBJECT(gui->inputbox),
#endif
}
+static gboolean vp_notify_event_cb(GtkWidget* widget, GdkEvent* event, gpointer data)
+{
+ WebKitHitTestResult *result = NULL;
+ WebKitHitTestResultContext context;
+ if (CLEAN_MODE(vp.state.mode) == VP_MODE_NORMAL
+ && event->type == GDK_BUTTON_RELEASE
+ ) {
+ result = webkit_web_view_get_hit_test_result(vp.gui.webview, (GdkEventButton*)event);
+ g_object_get(result, "context", &context, NULL);
+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE) {
+ Arg a = {VP_MODE_INSERT};
+ vp_set_mode(&a);
+ }
+ }
+
+ return FALSE;
+}
+
int main(int argc, char* argv[])
{
static gboolean ver = false;