2 * Copyright (c) 2011 Marco Peereboom <marco@peereboom.us>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #if WEBKIT_CHECK_VERSION(1, 5, 0)
20 /* we got the DOM API we need */
22 focus_input_document(struct tab
*t
, WebKitDOMDocument
*doc
)
24 WebKitDOMNodeList
*input
= NULL
, *textarea
= NULL
;
27 int i
, rv
= 0 /* not found */;
29 WebKitDOMHTMLTextAreaElement
*ta
;
30 WebKitDOMHTMLInputElement
*in
;
32 /* we are deliberately ignoring tab index! */
35 input
= webkit_dom_document_get_elements_by_tag_name(doc
, "input");
36 for (i
= 0; i
< webkit_dom_node_list_get_length(input
); i
++) {
37 n
= webkit_dom_node_list_item(input
, i
);
38 in
= (WebKitDOMHTMLInputElement
*)n
;
39 g_object_get(G_OBJECT(in
), "type", &es
, (char *)NULL
);
40 if ((!g_str_equal("text", es
) && !g_str_equal("password",es
)) ||
41 webkit_dom_html_input_element_get_disabled(in
)) {
46 webkit_dom_element_focus((WebKitDOMElement
*)in
);
52 /* now try textarea */
53 textarea
= webkit_dom_document_get_elements_by_tag_name(doc
, "textarea");
54 for (i
= 0; i
< webkit_dom_node_list_get_length(textarea
); i
++) {
55 n
= webkit_dom_node_list_item(textarea
, i
);
56 ta
= (WebKitDOMHTMLTextAreaElement
*)n
;
57 if (webkit_dom_html_text_area_element_get_disabled(ta
)) {
58 /* it is hidden so skip */
61 webkit_dom_element_focus((WebKitDOMElement
*)ta
);
67 g_object_unref(input
);
69 g_object_unref(textarea
);
74 focus_input(struct tab
*t
)
76 WebKitDOMDocument
*doc
;
78 WebKitDOMNodeList
*fl
= NULL
, *ifl
= NULL
;
79 int i
, fl_count
, ifl_count
, rv
= 0;
81 WebKitDOMHTMLFrameElement
*frame
;
82 WebKitDOMHTMLIFrameElement
*iframe
;
85 * Here is what we are doing:
86 * See if we got frames or iframes
88 * if we do focus on input or textarea in frame or in iframe
90 * if we find nothing or there are no frames focus on first input or
94 doc
= webkit_web_view_get_dom_document(t
->wv
);
97 fl
= webkit_dom_document_get_elements_by_tag_name(doc
, "frame");
98 fl_count
= webkit_dom_node_list_get_length(fl
);
101 ifl
= webkit_dom_document_get_elements_by_tag_name(doc
, "iframe");
102 ifl_count
= webkit_dom_node_list_get_length(ifl
);
104 /* walk frames and look for a text input */
105 for (i
= 0; i
< fl_count
; i
++) {
106 n
= webkit_dom_node_list_item(fl
, i
);
107 frame
= (WebKitDOMHTMLFrameElement
*)n
;
108 doc
= webkit_dom_html_frame_element_get_content_document(frame
);
110 if (focus_input_document(t
, doc
)) {
116 /* walk iframes and look for a text input */
117 for (i
= 0; i
< ifl_count
; i
++) {
118 n
= webkit_dom_node_list_item(ifl
, i
);
119 iframe
= (WebKitDOMHTMLIFrameElement
*)n
;
120 doc
= webkit_dom_html_iframe_element_get_content_document(iframe
);
122 if (focus_input_document(t
, doc
)) {
128 /* if we made it here nothing got focused so use normal heuristic */
129 if (focus_input_document(t
, webkit_web_view_get_dom_document(t
->wv
))) {
143 dom_is_input(struct tab
*t
, WebKitDOMElement
**active
)
145 WebKitDOMDocument
*doc
;
147 WebKitDOMHTMLElement
*aa
;
148 WebKitDOMHTMLObjectElement
*object
;
150 WebKitDOMHTMLFrameElement
*frame
;
151 WebKitDOMHTMLIFrameElement
*iframe
;
153 /* proof positive that OO is stupid */
155 doc
= webkit_web_view_get_dom_document(t
->wv
);
157 /* unwind frames and iframes until the cows come home */
159 a
= webkit_dom_html_document_get_active_element(
160 (WebKitDOMHTMLDocument
*)doc
);
164 frame
= (WebKitDOMHTMLFrameElement
*)a
;
165 if (WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(frame
)) {
166 doc
= webkit_dom_html_frame_element_get_content_document(
171 iframe
= (WebKitDOMHTMLIFrameElement
*)a
;
172 if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT(iframe
)) {
173 doc
= webkit_dom_html_iframe_element_get_content_document(
178 object
= (WebKitDOMHTMLObjectElement
*)a
;
179 if (WEBKIT_DOM_IS_HTML_OBJECT_ELEMENT(object
)) {
180 doc
= webkit_dom_html_object_element_get_content_document(
186 * I think this is a total hack because this property isn't
187 * set for textareas or input however, it is set for jquery
188 * textareas that do rich text. Since this works around issues
189 * in RT we'll simply keep it!
191 * This might break some other stuff but for now it helps.
193 aa
= (WebKitDOMHTMLElement
*)a
;
194 if (WEBKIT_DOM_IS_HTML_ELEMENT(aa
) &&
195 webkit_dom_html_element_get_is_content_editable(aa
)) {
205 if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode
*)a
) ||
206 WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode
*)a
)) {
215 input_check_mode(struct tab
*t
)
217 WebKitDOMElement
*active
= NULL
;
219 if (dom_is_input(t
, &active
))
220 t
->mode
= XT_MODE_INSERT
;
226 input_focus_blur(struct tab
*t
, void *active
)
228 /* active is (WebKitDOMElement*) */
230 webkit_dom_element_blur(active
);
234 command_mode(struct tab
*t
, struct karg
*args
)
236 WebKitDOMElement
*active
= NULL
;
238 if (args
->i
== XT_MODE_COMMAND
) {
239 if (dom_is_input(t
, &active
))
241 webkit_dom_element_blur(active
);
242 t
->mode
= XT_MODE_COMMAND
;
245 t
->mode
= XT_MODE_INSERT
;
248 return (XT_CB_HANDLED
);
252 input_autofocus(struct tab
*t
)
254 WebKitDOMElement
*active
= NULL
;
256 if (autofocus_onload
&&
257 t
->tab_id
== gtk_notebook_get_current_page(notebook
)) {
259 t
->mode
= XT_MODE_INSERT
;
261 t
->mode
= XT_MODE_COMMAND
;
263 if (dom_is_input(t
, &active
))
265 webkit_dom_element_blur(active
);
266 t
->mode
= XT_MODE_COMMAND
;
269 #else /* WEBKIT_CHECK_VERSION */
270 /* incomplete DOM API */
274 * note that we can't check the return value of run_script so we
275 * have to assume that the command worked; this may leave you in
276 * insertmode when in fact you shouldn't be
279 input_autofocus(struct tab
*t
)
281 if (autofocus_onload
&&
282 t
->tab_id
== gtk_notebook_get_current_page(notebook
)) {
283 run_script(t
, "hints.focusInput();");
284 t
->mode
= XT_MODE_INSERT
;
286 run_script(t
, "hints.clearFocus();");
287 t
->mode
= XT_MODE_COMMAND
;
292 input_focus_blur(struct tab
*t
, void *active
)
294 run_script(t
, "hints.clearFocus();");
295 t
->mode
= XT_MODE_COMMAND
;
299 input_check_mode(struct tab
*t
)
305 command_mode(struct tab
*t
, struct karg
*args
)
307 if (args
->i
== XT_MODE_COMMAND
) {
308 run_script(t
, "hints.clearFocus();");
309 t
->mode
= XT_MODE_COMMAND
;
311 run_script(t
, "hints.focusInput();");
312 t
->mode
= XT_MODE_INSERT
;
315 return (XT_CB_HANDLED
);