about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--inputfocus.c263
-rw-r--r--xxxterm.c226
-rw-r--r--xxxterm.h7
4 files changed, 277 insertions, 222 deletions
diff --git a/Makefile b/Makefile
index 169a778..cda17c2 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,8 @@ BINDIR=${PREFIX}/bin
 PROG=xxxterm
 MAN=xxxterm.1
 
-SRCS= cookie.c inspector.c marco.c about.c whitelist.c settings.c xxxterm.c
+SRCS= cookie.c inspector.c marco.c about.c whitelist.c settings.c inputfocus.c
+SRCS+= xxxterm.c
 CFLAGS+= -O2 -Wall -Wno-format-extra-args -Wunused
 CFLAGS+= -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare
 DEBUG= -ggdb3
diff --git a/inputfocus.c b/inputfocus.c
new file mode 100644
index 0000000..ae7f390
--- /dev/null
+++ b/inputfocus.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2011 Marco Peereboom <marco@peereboom.us>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xxxterm.h"
+
+#if WEBKIT_CHECK_VERSION(1, 3, 0)
+	/* we got the DOM API we need */
+int
+focus_input_document(struct tab *t, WebKitDOMDocument *doc)
+{
+	WebKitDOMNodeList	*input = NULL, *textarea = NULL;
+	WebKitDOMNode		*n;
+	char			*es;
+	int			i, rv = 0 /* not found */;
+
+	WebKitDOMHTMLTextAreaElement	*ta;
+	WebKitDOMHTMLInputElement	*in;
+
+	/* we are deliberately ignoring tab index! */
+
+	/* try input first */
+	input = webkit_dom_document_get_elements_by_tag_name(doc, "input");
+	for (i = 0; i < webkit_dom_node_list_get_length(input); i++) {
+		n = webkit_dom_node_list_item(input, i);
+		in = (WebKitDOMHTMLInputElement*)n;
+		g_object_get(G_OBJECT(in), "type", &es, (char *)NULL);
+		if ((!g_str_equal("text", es) && !g_str_equal("password",es)) ||
+		    webkit_dom_html_input_element_get_disabled(in)) {
+			/* skip not text */
+			g_free(es);
+			continue;
+		}
+		webkit_dom_element_focus((WebKitDOMElement*)in);
+		g_free(es);
+		rv = 1; /* found */
+		goto done;
+	}
+
+	/* now try textarea */
+	textarea = webkit_dom_document_get_elements_by_tag_name(doc, "textarea");
+	for (i = 0; i < webkit_dom_node_list_get_length(textarea); i++) {
+		n = webkit_dom_node_list_item(textarea, i);
+		ta = (WebKitDOMHTMLTextAreaElement*)n;
+		if (webkit_dom_html_text_area_element_get_disabled(ta)) {
+			/* it is hidden so skip */
+			continue;
+		}
+		webkit_dom_element_focus((WebKitDOMElement*)ta);
+		rv = 1; /* found */
+		goto done;
+	}
+done:
+	if (input)
+		g_object_unref(input);
+	if (textarea)
+		g_object_unref(textarea);
+
+	return (rv);
+}
+int
+focus_input(struct tab *t)
+{
+	WebKitDOMDocument	*doc;
+	WebKitDOMNode		*n;
+	WebKitDOMNodeList	*fl = NULL, *ifl = NULL;
+	int			i, fl_count, ifl_count, rv = 0;
+
+	WebKitDOMHTMLFrameElement	*frame;
+	WebKitDOMHTMLIFrameElement	*iframe;
+
+	/*
+	 * Here is what we are doing:
+	 * See if we got frames or iframes
+	 *
+	 * if we do focus on input or textarea in frame or in iframe
+	 *
+	 * if we find nothing or there are no frames focus on first input or
+	 * text area
+	 */
+
+	doc = webkit_web_view_get_dom_document(t->wv);
+
+	/* get frames */
+	fl = webkit_dom_document_get_elements_by_tag_name(doc, "frame");
+	fl_count = webkit_dom_node_list_get_length(fl);
+
+	/* get iframes */
+	ifl = webkit_dom_document_get_elements_by_tag_name(doc, "iframe");
+	ifl_count = webkit_dom_node_list_get_length(ifl);
+
+	/* walk frames and look for a text input */
+	for (i = 0; i < fl_count; i++) {
+		n = webkit_dom_node_list_item(fl, i);
+		frame = (WebKitDOMHTMLFrameElement*)n;
+		doc = webkit_dom_html_frame_element_get_content_document(frame);
+
+		if (focus_input_document(t, doc)) {
+			rv = 1;
+			goto done;
+		}
+	}
+
+	/* walk iframes and look for a text input */
+	for (i = 0; i < ifl_count; i++) {
+		n = webkit_dom_node_list_item(ifl, i);
+		iframe = (WebKitDOMHTMLIFrameElement*)n;
+		doc = webkit_dom_html_iframe_element_get_content_document(iframe);
+
+		if (focus_input_document(t, doc)) {
+			rv = 1;
+			goto done;
+		}
+	}
+
+	/* if we made it here nothing got focused so use normal heuristic */
+	if (focus_input_document(t, webkit_web_view_get_dom_document(t->wv))) {
+		rv = 1;
+		goto done;
+	}
+done:
+	if (fl)
+		g_object_unref(fl);
+	if (ifl)
+		g_object_unref(ifl);
+
+	return (rv);
+}
+
+int
+dom_is_input(struct tab *t, WebKitDOMElement **active)
+{
+	WebKitDOMDocument	*doc;
+	WebKitDOMElement	*a;
+
+	WebKitDOMHTMLFrameElement *frame;
+	WebKitDOMHTMLIFrameElement *iframe;
+
+	/* proof positive that OO is stupid */
+
+	doc = webkit_web_view_get_dom_document(t->wv);
+
+	/* unwind frames and iframes until the cows come home */
+	for (;;) {
+		a = webkit_dom_html_document_get_active_element(
+		    (WebKitDOMHTMLDocument*)doc);
+		if (a == NULL)
+			return (0);
+
+		/*
+		 * I think this is a total hack because this property isn't
+		 * set for textareas or input however, it is set for jquery
+		 * textareas that do rich text.  Since this works around issues
+		 * in RT we'll simply keep it!
+		 *
+		 * This might break some other stuff but for now it helps.
+		 */
+		if (webkit_dom_html_element_get_is_content_editable(
+		    (WebKitDOMHTMLElement*)a)) {
+			*active = a;
+			return (1);
+		}
+
+		frame = (WebKitDOMHTMLFrameElement *)a;
+		if (WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(frame)) {
+			doc = webkit_dom_html_frame_element_get_content_document(
+			    frame);
+			continue;
+		}
+
+		iframe = (WebKitDOMHTMLIFrameElement *)a;
+		if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT(iframe)) {
+			doc = webkit_dom_html_iframe_element_get_content_document(
+			    iframe);
+			continue;
+		}
+
+		break;
+	}
+
+	if (a == NULL)
+		return (0);
+
+	if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode *)a) ||
+	    WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode *)a)) {
+		*active = a;
+		return (1);
+	}
+
+	return (0);
+}
+
+void *
+input_check_mode(struct tab *t)
+{
+	WebKitDOMElement	*active = NULL;
+
+	if (dom_is_input(t, &active))
+		t->mode = XT_MODE_INSERT;
+	else
+		t->mode = XT_MODE_COMMAND;
+
+	return (active);
+}
+
+void
+input_focus_blur(struct tab *t, void *active)
+{
+	/* active is (WebKitDOMElement*) */
+	webkit_dom_element_blur(active);
+}
+
+int
+command_mode(struct tab *t, struct karg *args)
+{
+	WebKitDOMElement	*active = NULL;
+
+	if (args->i == XT_MODE_COMMAND) {
+		if (dom_is_input(t, &active))
+			if (active)
+				webkit_dom_element_blur(active);
+		t->mode = XT_MODE_COMMAND;
+	} else {
+		if (focus_input(t))
+			t->mode = XT_MODE_INSERT;
+	}
+
+	return (XT_CB_HANDLED);
+}
+
+void
+input_autofocus(struct tab *t)
+{
+	WebKitDOMElement	*active = NULL;
+
+	if (autofocus_onload &&
+	    t->tab_id == gtk_notebook_get_current_page(notebook)) {
+		if (focus_input(t))
+			t->mode = XT_MODE_INSERT;
+		else
+			t->mode = XT_MODE_COMMAND;
+	} else {
+		if (dom_is_input(t, &active))
+			if (active)
+				webkit_dom_element_blur(active);
+		t->mode = XT_MODE_COMMAND;
+	}
+}
+#elif
+	/* incomplete DOM API */
+#endif
diff --git a/xxxterm.c b/xxxterm.c
index a87994c..a6bd356 100644
--- a/xxxterm.c
+++ b/xxxterm.c
@@ -2488,207 +2488,6 @@ movetab(struct tab *t, struct karg *args)
 
 int cmd_prefix = 0;
 
-int
-focus_input_document(struct tab *t, WebKitDOMDocument *doc)
-{
-	WebKitDOMNodeList	*input = NULL, *textarea = NULL;
-	WebKitDOMNode		*n;
-	char			*es;
-	int			i, rv = 0 /* not found */;
-
-	WebKitDOMHTMLTextAreaElement	*ta;
-	WebKitDOMHTMLInputElement	*in;
-
-	/* we are deliberately ignoring tab index! */
-
-	/* try input first */
-	input = webkit_dom_document_get_elements_by_tag_name(doc, "input");
-	for (i = 0; i < webkit_dom_node_list_get_length(input); i++) {
-		n = webkit_dom_node_list_item(input, i);
-		in = (WebKitDOMHTMLInputElement*)n;
-		g_object_get(G_OBJECT(in), "type", &es, (char *)NULL);
-		if ((!g_str_equal("text", es) && !g_str_equal("password",es)) ||
-		    webkit_dom_html_input_element_get_disabled(in)) {
-			/* skip not text */
-			g_free(es);
-			continue;
-		}
-		webkit_dom_element_focus((WebKitDOMElement*)in);
-		g_free(es);
-		rv = 1; /* found */
-		goto done;
-	}
-
-	/* now try textarea */
-	textarea = webkit_dom_document_get_elements_by_tag_name(doc, "textarea");
-	for (i = 0; i < webkit_dom_node_list_get_length(textarea); i++) {
-		n = webkit_dom_node_list_item(textarea, i);
-		ta = (WebKitDOMHTMLTextAreaElement*)n;
-		if (webkit_dom_html_text_area_element_get_disabled(ta)) {
-			/* it is hidden so skip */
-			continue;
-		}
-		webkit_dom_element_focus((WebKitDOMElement*)ta);
-		rv = 1; /* found */
-		goto done;
-	}
-done:
-	if (input)
-		g_object_unref(input);
-	if (textarea)
-		g_object_unref(textarea);
-
-	return (rv);
-}
-int
-focus_input(struct tab *t)
-{
-	WebKitDOMDocument	*doc;
-	WebKitDOMNode		*n;
-	WebKitDOMNodeList	*fl = NULL, *ifl = NULL;
-	int			i, fl_count, ifl_count, rv = 0;
-
-	WebKitDOMHTMLFrameElement	*frame;
-	WebKitDOMHTMLIFrameElement	*iframe;
-
-	/*
-	 * Here is what we are doing:
-	 * See if we got frames or iframes
-	 *
-	 * if we do focus on input or textarea in frame or in iframe
-	 *
-	 * if we find nothing or there are no frames focus on first input or
-	 * text area
-	 */
-
-	doc = webkit_web_view_get_dom_document(t->wv);
-
-	/* get frames */
-	fl = webkit_dom_document_get_elements_by_tag_name(doc, "frame");
-	fl_count = webkit_dom_node_list_get_length(fl);
-
-	/* get iframes */
-	ifl = webkit_dom_document_get_elements_by_tag_name(doc, "iframe");
-	ifl_count = webkit_dom_node_list_get_length(ifl);
-
-	/* walk frames and look for a text input */
-	for (i = 0; i < fl_count; i++) {
-		n = webkit_dom_node_list_item(fl, i);
-		frame = (WebKitDOMHTMLFrameElement*)n;
-		doc = webkit_dom_html_frame_element_get_content_document(frame);
-
-		if (focus_input_document(t, doc)) {
-			rv = 1;
-			goto done;
-		}
-	}
-
-	/* walk iframes and look for a text input */
-	for (i = 0; i < ifl_count; i++) {
-		n = webkit_dom_node_list_item(ifl, i);
-		iframe = (WebKitDOMHTMLIFrameElement*)n;
-		doc = webkit_dom_html_iframe_element_get_content_document(iframe);
-
-		if (focus_input_document(t, doc)) {
-			rv = 1;
-			goto done;
-		}
-	}
-
-	/* if we made it here nothing got focused so use normal heuristic */
-	if (focus_input_document(t, webkit_web_view_get_dom_document(t->wv))) {
-		rv = 1;
-		goto done;
-	}
-done:
-	if (fl)
-		g_object_unref(fl);
-	if (ifl)
-		g_object_unref(ifl);
-
-	return (rv);
-}
-
-int
-dom_is_input(struct tab *t, WebKitDOMElement **active)
-{
-	WebKitDOMDocument	*doc;
-	WebKitDOMElement	*a;
-
-	WebKitDOMHTMLFrameElement *frame;
-	WebKitDOMHTMLIFrameElement *iframe;
-
-	/* proof positive that OO is stupid */
-
-	doc = webkit_web_view_get_dom_document(t->wv);
-
-	/* unwind frames and iframes until the cows come home */
-	for (;;) {
-		a = webkit_dom_html_document_get_active_element(
-		    (WebKitDOMHTMLDocument*)doc);
-		if (a == NULL)
-			return (0);
-
-		/*
-		 * I think this is a total hack because this property isn't
-		 * set for textareas or input however, it is set for jquery
-		 * textareas that do rich text.  Since this works around issues
-		 * in RT we'll simply keep it!
-		 *
-		 * This might break some other stuff but for now it helps.
-		 */
-		if (webkit_dom_html_element_get_is_content_editable(
-		    (WebKitDOMHTMLElement*)a)) {
-			*active = a;
-			return (1);
-		}
-
-		frame = (WebKitDOMHTMLFrameElement *)a;
-		if (WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(frame)) {
-			doc = webkit_dom_html_frame_element_get_content_document(
-			    frame);
-			continue;
-		}
-
-		iframe = (WebKitDOMHTMLIFrameElement *)a;
-		if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT(iframe)) {
-			doc = webkit_dom_html_iframe_element_get_content_document(
-			    iframe);
-			continue;
-		}
-
-		break;
-	}
-
-	if (a == NULL)
-		return (0);
-
-	if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode *)a) ||
-	    WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode *)a)) {
-		*active = a;
-		return (1);
-	}
-
-	return (0);
-}
-
-int
-command_mode(struct tab *t, struct karg *args)
-{
-	WebKitDOMElement	*active = NULL;
-
-	if (args->i == XT_MODE_COMMAND) {
-		if (dom_is_input(t, &active))
-			if (active)
-				webkit_dom_element_blur(active);
-		t->mode = XT_MODE_COMMAND;
-	} else {
-		if (focus_input(t))
-			t->mode = XT_MODE_INSERT;
-	}
-
-	return (XT_CB_HANDLED);
-}
 
 int
 command(struct tab *t, struct karg *args)
@@ -4205,23 +4004,11 @@ done:
 void
 webview_load_finished_cb(WebKitWebView *wv, WebKitWebFrame *wf, struct tab *t)
 {
-	WebKitDOMElement	*active = NULL;
-
 	/* autorun some js if enabled */
 	js_autorun(t);
 
-	if (autofocus_onload &&
-	    t->tab_id == gtk_notebook_get_current_page(notebook)) {
-		if (focus_input(t))
-			t->mode = XT_MODE_INSERT;
-		else
-			t->mode = XT_MODE_COMMAND;
-	} else {
-		if (dom_is_input(t, &active))
-			if (active)
-				webkit_dom_element_blur(active);
-		t->mode = XT_MODE_COMMAND;
-	}
+	input_autofocus(t);
+
 }
 
 void
@@ -5018,7 +4805,7 @@ int
 wv_keypress_cb(GtkEntry *w, GdkEventKey *e, struct tab *t)
 {
 	char			s[2];
-	WebKitDOMElement	*active = NULL;
+	void			*active = NULL;
 
 	/* don't use w directly; use t->whatever instead */
 
@@ -5049,10 +4836,7 @@ wv_keypress_cb(GtkEntry *w, GdkEventKey *e, struct tab *t)
 		return (XT_CB_PASSTHROUGH);
 
 	/* check if we are some sort of text input thing in the dom */
-	if (dom_is_input(t, &active))
-		t->mode = XT_MODE_INSERT;
-	else
-		t->mode = XT_MODE_COMMAND;
+	active = input_check_mode(t);
 
 	if (t->mode == XT_MODE_HINT) {
 		/* XXX make sure cmd entry is enabled */
@@ -5068,7 +4852,7 @@ wv_keypress_cb(GtkEntry *w, GdkEventKey *e, struct tab *t)
 	if (CLEAN(e->state) == 0 && e->keyval == GDK_Escape) {
 		t->mode = XT_MODE_COMMAND;
 		if (active)
-			webkit_dom_element_blur(active);
+			input_focus_blur(t, active);
 		return (XT_CB_HANDLED);
 	}
 
diff --git a/xxxterm.h b/xxxterm.h
index b9e86e0..9bc9a3a 100644
--- a/xxxterm.h
+++ b/xxxterm.h
@@ -409,6 +409,12 @@ int		toggle_cwl(struct tab *, struct karg *);
 int		toggle_js(struct tab *, struct karg *);
 int		toggle_pl(struct tab *, struct karg *);
 
+/* input autofocus */
+void		input_autofocus(struct tab *);
+void		input_focus_blur(struct tab *t, void *);
+void		*input_check_mode(struct tab *t);
+int		command_mode(struct tab *, struct karg *);
+
 /* settings */
 #define XT_BM_NORMAL		(0)
 #define XT_BM_WHITELIST		(1)
@@ -530,6 +536,7 @@ long long unsigned int	blocked_cookies;
 extern SoupCookieJar	*s_cookiejar;
 extern SoupCookieJar	*p_cookiejar;
 extern SoupSession	*session;
+extern GtkNotebook	*notebook;
 
 extern void	(*_soup_cookie_jar_add_cookie)(SoupCookieJar *, SoupCookie *);