/* 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); }
static void test_dom_document_get_elements_by_tag_name(DomDocumentFixture* fixture, gconstpointer data) { g_assert(fixture); WebKitWebView* view = (WebKitWebView*)fixture->webView; g_assert(view); WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); g_assert(document); WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_tag_name(document, "li"); g_assert(list); gulong length = webkit_dom_node_list_get_length(list); g_assert_cmpint(length, ==, 3); guint i; for (i = 0; i < length; i++) { WebKitDOMNode* item = webkit_dom_node_list_item(list, i); g_assert(item); WebKitDOMElement* element = (WebKitDOMElement*)item; g_assert(element); g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "LI"); WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element; char* n = g_strdup_printf("%d", i+1); g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, n); g_free(n); } g_object_unref(list); }
// frame_document_loaded watches signals emitted from the given document. static void frame_document_loaded(WebKitDOMDocument *doc, Exten *exten) { // Track document, and don't register multiple times. if(!g_hash_table_add(exten->registered_documents, doc)) { return; } WebKitDOMEventTarget *target = WEBKIT_DOM_EVENT_TARGET( webkit_dom_document_get_default_view(doc)); // listen for focus changes webkit_dom_event_target_add_event_listener( target, "blur", G_CALLBACK(active_element_change_cb), true, exten); webkit_dom_event_target_add_event_listener( target, "focus", G_CALLBACK(active_element_change_cb), true, exten); // listen for resource loads. webkit_dom_event_target_add_event_listener( target, "beforeload", G_CALLBACK(adblock_before_load_cb), true, exten); // Scan for existing iframes, and add them as new frames. WebKitDOMNodeList *nodes = webkit_dom_document_get_elements_by_tag_name( WEBKIT_DOM_DOCUMENT(doc), "IFRAME"); gulong i; gulong len; if(nodes == NULL) { len = 0; } else { len = webkit_dom_node_list_get_length(nodes); } for(i = 0; i < len; i++) { WebKitDOMDocument *subdoc = webkit_dom_html_iframe_element_get_content_document( WEBKIT_DOM_HTML_IFRAME_ELEMENT( webkit_dom_node_list_item(nodes, i))); frame_document_loaded(subdoc, exten); } // Element hider inject_adblock_css(doc, exten); }
/** * Set focus to the first found editable element and returns if a element was * found to focus. */ gboolean dom_focus_input(WebKitWebView *view) { gboolean found = false; WebKitDOMNode *html, *node; WebKitDOMDocument *doc; WebKitDOMDOMWindow *win; WebKitDOMNodeList *list; WebKitDOMXPathNSResolver *resolver; WebKitDOMXPathResult* result; doc = webkit_web_view_get_dom_document(view); win = webkit_dom_document_get_default_view(doc); list = webkit_dom_document_get_elements_by_tag_name(doc, "html"); if (!list) { return false; } html = webkit_dom_node_list_item(list, 0); resolver = webkit_dom_document_create_ns_resolver(doc, html); if (!resolver) { return false; } result = webkit_dom_document_evaluate( doc, "//input[not(@type) or @type='text' or @type='password']|//textarea", html, resolver, 0, NULL, NULL ); if (!result) { return false; } while ((node = webkit_dom_xpath_result_iterate_next(result, NULL))) { if (element_is_visible(win, WEBKIT_DOM_ELEMENT(node))) { webkit_dom_element_focus(WEBKIT_DOM_ELEMENT(node)); found = true; break; } } g_object_unref(list); return found; }
/** * Find the first editable element and set the focus on it and enter input * mode. * Returns true if there was an editable element focused. */ gboolean dom_focus_input(Document *doc) { WebKitDOMNode *html, *node; WebKitDOMDOMWindow *win; WebKitDOMNodeList *list; WebKitDOMXPathNSResolver *resolver; WebKitDOMXPathResult* result; Document *frame_doc; guint i, len; win = webkit_dom_document_get_default_view(doc); list = webkit_dom_document_get_elements_by_tag_name(doc, "html"); if (!list) { return false; } html = webkit_dom_node_list_item(list, 0); g_object_unref(list); resolver = webkit_dom_document_create_ns_resolver(doc, html); if (!resolver) { return false; } /* Use translate to match xpath expression case insensitive so that also * intput filed of type="TEXT" are matched. */ result = webkit_dom_document_evaluate( doc, "//input[not(@type) " "or translate(@type,'ETX','etx')='text' " "or translate(@type,'ADOPRSW','adoprsw')='password' " "or translate(@type,'CLOR','clor')='color' " "or translate(@type,'ADET','adet')='date' " "or translate(@type,'ADEIMT','adeimt')='datetime' " "or translate(@type,'ACDEILMOT','acdeilmot')='datetime-local' " "or translate(@type,'AEILM','aeilm')='email' " "or translate(@type,'HMNOT','hmnot')='month' " "or translate(@type,'BEMNRU','bemnru')='number' " "or translate(@type,'ACEHRS','acehrs')='search' " "or translate(@type,'ELT','elt')='tel' " "or translate(@type,'EIMT','eimt')='time' " "or translate(@type,'LRU','lru')='url' " "or translate(@type,'EKW','ekw')='week' " "]|//textarea", html, resolver, 5, NULL, NULL ); if (!result) { return false; } while ((node = webkit_dom_xpath_result_iterate_next(result, NULL))) { if (element_is_visible(win, WEBKIT_DOM_ELEMENT(node))) { vb_enter('i'); webkit_dom_element_focus(WEBKIT_DOM_ELEMENT(node)); return true; } } /* Look for editable elements in frames too. */ list = webkit_dom_document_get_elements_by_tag_name(doc, "iframe"); len = webkit_dom_node_list_get_length(list); for (i = 0; i < len; i++) { node = webkit_dom_node_list_item(list, i); frame_doc = webkit_dom_html_iframe_element_get_content_document(WEBKIT_DOM_HTML_IFRAME_ELEMENT(node)); /* Stop on first frame with focused element. */ if (dom_focus_input(frame_doc)) { g_object_unref(list); return true; } } g_object_unref(list); return false; }
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); }