diff options
| author | miguel <miguel@localhost> | 2018-03-10 19:00:32 +0100 |
|---|---|---|
| committer | miguel <miguel@localhost> | 2018-03-10 19:00:32 +0100 |
| commit | 700a87f27c4c5d63b8350d37f06410081951addb (patch) | |
| tree | 0bb7fa858936b37391fb93058056346ee4c5755d /surf-webext-dom.c | |
first commit
Diffstat (limited to 'surf-webext-dom.c')
| -rw-r--r-- | surf-webext-dom.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/surf-webext-dom.c b/surf-webext-dom.c new file mode 100644 index 0000000..31e1308 --- /dev/null +++ b/surf-webext-dom.c @@ -0,0 +1,160 @@ +// +// !!! THIS IS A BUGGY CONCEPT/PROTOTYPE. USE AT YOUR OWN RISK !!! +// +// The following simple Webkit2GTK+ extension was hacked together +// in the sleepless night between 09th and 10th March 2018 by: +// +// Michal Idziorek <m.i@gmx.at>. +// +// It regjsters a document_loaded_callback, where the DOM is manipulated, +// i.e: a <span> with a number added to every link encountered. +// +// The urls are extracted from the DOM and shared with the browsers +// process over a system V memory segment. +// +// As an example, this can be used to enable keyboardless navigation +// in surf by simply typing in the number of the link. +// +// TODO: Support multiple clients! See source for more TODOS! +// THE biggest limitation by now is the lazily hardcoded: +// key_t my_ftok = ftok("~/surf-webext-dom-shared-mem",'a'); +// +// Last Update: 10th March 2018 +// +// Last Tested: with surf commit 81f0452bc6c2a110239fa303ad1e72f11c33dc94 +// from htps://git.suckless.org/surf +// + +#include <webkit2/webkit-web-extension.h> + +#include <sys/ipc.h> +#include <sys/shm.h> +#include <errno.h> +#include <string.h> + +bool str_prefix(const char *str, const char *pre); + +void +document_loaded_callback (WebKitWebPage *web_page, + GPtrArray *elements, + GVariant *user_data) +{ + + // TODO: g_free where appropriate !! + // TODO: allow focus on input boxes/forms + // TODO: Put this somehwere else? (but I dislike #defines) + // share this info with surf itself! maybe surf can supply this along + // the ftok path via the user_data GVariant. + int MAX_LINKS=1024; + int MAX_LINK_LENGTH=1024; + int DEBUG=3; + + // get html doc + WebKitDOMHTMLDocument *doc = webkit_web_page_get_dom_document(web_page); + if(!WEBKIT_DOM_IS_HTML_DOCUMENT(doc))return; + + // get url + char *url = webkit_dom_document_get_url (doc); + if(DEBUG>1) g_print("document_loaded (callback): %s\n", url); + + // tokenize url + char *url_proto=strtok(url,"/"); + char *url_host=strtok(NULL,"/"); + if(DEBUG>2) g_print("proto: %s\n", url_proto); + if(DEBUG>2) g_print("host: %s\n", url_host); + + // get html body + WebKitDOMHTMLElement *body = webkit_dom_document_get_body(doc); + + // get links (alt) + /* altenative way, what is the difference (TODO)? + WebKitDOMNodeList *links = webkit_dom_document_query_selector_all(doc,"a",NULL); + gulong links_count = webkit_dom_node_list_get_length (links); + g_print("extracted %i links\n",links_count); + */ + + // get links + WebKitDOMHTMLCollection *links = webkit_dom_document_get_links(doc); + gulong links_count = webkit_dom_html_collection_get_length (links); + if(DEBUG>1) g_print("extracted %i links\n",links_count); + + // attach to shared memory; + key_t my_ftok = ftok("~/surf-webext-dom-shared-mem",'a'); + + // TODO: should we need the size again here? + int mem_seg=shmget(my_ftok,MAX_LINKS*MAX_LINK_LENGTH,IPC_CREAT|0660); + if(mem_seg==-1) + { + g_print("shmget failed: %s\n",strerror(errno)); + } + + char *shared_buf=shmat(mem_seg,NULL,0); + if(shared_buf==(void*)-1) + { + g_print("shmat failed: %s\n",strerror(errno)); + } + + // iterate over links + for(gulong i=0;i<links_count;i++) + { + char buf[MAX_LINK_LENGTH]; // TODO: dynamic! + + WebKitDOMHTMLLinkElement * node = webkit_dom_html_collection_item (links,i); + + // add hint for keyboard navigation + char *txt = webkit_dom_html_element_get_inner_html (node); + + // TODO: style via stylesheet + snprintf(buf,MAX_LINK_LENGTH, + "<span style='padding-right:5px;border-bottom:1px solid black;'>\ + <span style='font-size:13px;font-weight:bold;font-face:Arial;\ + border:1px solid black;display:inline;color:white;\ + background-color:#c0474c;padding:0 5px;margin:0;\ + margin-right:5px;'>%i</span>%s</span>", i,txt); + + webkit_dom_html_element_set_inner_html (node,buf,NULL); + + // alternatively add hints at the end of the body + // webkit_dom_element_insert_adjacent_html (body,"beforeend",buf,NULL); + + // TODO: this does not work for some sad reason. + // sadly, likely due to my misunderstanding. + // node seems not to be a LinkElement at all :( + // txt = webkit_dom_html_link_element_get_href (node); + // so we have to use this: + txt = webkit_dom_element_get_attribute (node,"href"); + if(str_prefix(txt,"//")) snprintf(buf,MAX_LINK_LENGTH,"%s%s",url_proto,txt); + else if(str_prefix(txt,"/")) snprintf(buf,MAX_LINK_LENGTH,"%s//%s%s",url_proto,url_host,txt); + else snprintf(buf,MAX_LINK_LENGTH,"%s",txt); + + if(i<MAX_LINKS) snprintf(&(shared_buf[MAX_LINK_LENGTH*i]),MAX_LINK_LENGTH,"%s\0",buf); + if(DEBUG>10) g_print("extracted link : %s\n",buf); + } +} + +static void +page_created_callback (WebKitWebExtension *extension, + WebKitWebPage *web_page, + GVariant *user_data) +{ + g_signal_connect (web_page, "document-loaded", + G_CALLBACK (document_loaded_callback), + user_data); +} + +G_MODULE_EXPORT void +webkit_web_extension_initialize_with_user_data (WebKitWebExtension *extension, + GVariant *user_data) +{ + g_signal_connect (extension, "page-created", + G_CALLBACK (page_created_callback), + user_data ); +} + +//https://stackoverflow.com/questions/4770985/how-to-check-if-a-string-starts-with-another-string-in-c +bool str_prefix(const char *str, const char *pre) +{ + size_t lenpre = strlen(pre), + lenstr = strlen(str); + return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0; +} |
