summaryrefslogtreecommitdiff
path: root/webext-piper.c
diff options
context:
space:
mode:
Diffstat (limited to 'webext-piper.c')
-rw-r--r--webext-piper.c189
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 );
+
+}