diff options
Diffstat (limited to 'webext-piper.c')
| -rw-r--r-- | webext-piper.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/webext-piper.c b/webext-piper.c new file mode 100644 index 0000000..cae4da5 --- /dev/null +++ b/webext-piper.c @@ -0,0 +1,189 @@ +// +// !!! THIS IS STILL A CONCEPT/PROTOTYPE. USE AT YOUR OWN RISK !!! +// +// Author: Michal Idziorek <m.i@gmx.at> +// +// Last Update: 14th March 2018 +// +// Last Tested: with surf commit 81f0452bc6c2a110239fa303ad1e72f11c33dc94 +// from htps://git.suckless.org/surf +// +// The following simple Webkit2GTK+ extension was hacked together +// in the sleepless night between 09th and 10th March 2018 (and later +// refined). +// +// The DOM is manipulated,i.e: a <span> with a number added to every +// link encountered. +// +// Named FIFO pipes are used for communication with the ui process. +// +// TODO: g_free where appropriate !! +// TODO: allow focus on input boxes/forms +// TODO: 1024 hardcoded doc references!. make dynamic and free unused. +// TODO: more todos directly in source +// TODO: implement New window in surf on msg receive +// TODO: fix hints positions! +// + +#include <webkit2/webkit-web-extension.h> + +#include <sys/ipc.h> +#include <sys/shm.h> +#include <errno.h> +#include <string.h> +#include <pthread.h> + +#include "piper_webext.h" + +#define CSS_CLASS_NAME "webext_piper_hint" +#define MAX_DOCS 1024 + +WebKitDOMHTMLDocument *my_doc[MAX_DOCS]; +bool hints_active[MAX_DOCS]; + +void hide_hints(WebKitDOMHTMLDocument *doc,int skip) +{ + WebKitDOMNodeList *hints=webkit_dom_document_get_elements_by_class_name (doc,CSS_CLASS_NAME); + gulong c=webkit_dom_node_list_get_length (hints); + + int s=0; + for(gulong i=0;i<c;i++) + { + if(i==skip){s++;c--;} + if(i==c)continue; + WebKitDOMNode *node = webkit_dom_node_list_item (hints,s); + WebKitDOMNode *parent = webkit_dom_node_get_parent_node (node); + webkit_dom_node_remove_child (parent,node,NULL); + + } +} + +void show_hints(WebKitDOMHTMLDocument *doc) +{ + WebKitDOMElement *body = webkit_dom_document_get_body(doc); + WebKitDOMHTMLCollection *links = webkit_dom_document_get_links(doc); + gulong c = webkit_dom_html_collection_get_length (links); + + for(gulong i=0;i<c;i++) + { + char buf[1024]; + WebKitDOMHTMLAnchorElement *node = webkit_dom_html_collection_item (links,i); + WebKitDOMClientRect *rect=webkit_dom_element_get_bounding_client_rect (node); + + snprintf(buf,1024,"<span class='%s' style='"\ + + "border:1px solid black;"\ + "font-weight:bold;"\ + "font-face:Arial;"\ + "font-size:10px;"\ + "color:rgba(255,255,255,1);"\ + "padding:3px;"\ + "background-color:rgba(255,0,0,0.5);"\ + "position:absolute;"\ + "z-index:100000;"\ + "left:%ipx;"\ + "top:%ipx;"\ + + "'>%03d</span>", + CSS_CLASS_NAME,(int)webkit_dom_client_rect_get_left(rect),(int)webkit_dom_client_rect_get_top(rect),i); + webkit_dom_element_insert_adjacent_html (body,"beforeend",buf,NULL); + } +} + +void toggle_hints(int i) +{ + if(hints_active[i]) + { + hide_hints(my_doc[i],-1); + hints_active[i]=false; + return; + } + + show_hints(my_doc[i]); + hints_active[i]=true; +} + +void +document_loaded_callback (WebKitWebPage *web_page, + GPtrArray *elements, + GVariant *user_data) +{ + int id=webkit_web_page_get_id(web_page); + g_print("Document Loaded Callback Called (page id:%i)\n",id); + hints_active[id]=false; + my_doc[id] = webkit_web_page_get_dom_document(web_page); +} + +void +page_created_callback (WebKitWebExtension *extension, + WebKitWebPage *web_page, + GVariant *user_data) +{ + g_print("Page Created Callback Called\n"); + + g_signal_connect (web_page, "document-loaded", + G_CALLBACK (document_loaded_callback), + user_data); +} + +static void follow_link(int id,int link_num,bool new_win) +{ + WebKitDOMHTMLCollection *links = webkit_dom_document_get_links(my_doc[id]); + gulong c = webkit_dom_html_collection_get_length (links); + if(link_num>=c)return; + WebKitDOMHTMLAnchorElement *node = webkit_dom_html_collection_item (links,link_num); + if(!new_win) + { + hide_hints(my_doc[id],link_num); + hints_active[id]=false; + webkit_dom_html_element_click(node); + return; + } + char *href=webkit_dom_html_anchor_element_get_href (node); + char buf[1024]; + snprintf(buf,1024,"%s\n",href); + piper_send(buf); +} + +void rcv(char *msg) +{ + static int num[3]; + static int l=0; + static bool new=false; + int id; + int cmd; + sscanf(msg,"%d %d",&id,&cmd); + + if(cmd<10) + { + num[l++]=cmd; + if(l==3) + { + int link_num=100*num[0]+10*num[1]+num[2]; + g_printf("link_num: %i\n",link_num); + l=0; + follow_link(id,link_num,new); + } + } + else + { + l=0; + if(cmd==100)new=false; + if(cmd==101)new=true; + toggle_hints(id); + } + +} + +G_MODULE_EXPORT void +webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension, + GVariant *user_data) +{ + g_print("webext started [%i]\n",getpid()); + piper_init("surf-to-ext","ext-to-surf",rcv); + + g_signal_connect (extension, "page-created", + G_CALLBACK (page_created_callback), + user_data ); + +} |
