From 4fccdf18f3956eaab6481597e38efd1939f16f81 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Fri, 12 Oct 2012 16:21:29 +0100 Subject: Move dom walker to utils/libdom.{c|h}. Add a few HTML elements to core strings. --- Makefile.sources | 6 +- render/html.c | 108 +--------------------------------- utils/corestrings.c | 6 ++ utils/corestrings.h | 2 + utils/libdom.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++ utils/libdom.h | 51 ++++++++++++++++ 6 files changed, 228 insertions(+), 109 deletions(-) create mode 100644 utils/libdom.c create mode 100644 utils/libdom.h diff --git a/Makefile.sources b/Makefile.sources index 7b0bec577..d7229badc 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -17,9 +17,9 @@ S_RENDER := box.c box_construct.c box_normalise.c \ html_forms.c imagemap.c layout.c list.c search.c table.c \ textinput.c textplain.c -S_UTILS := base64.c corestrings.c filename.c hashtable.c locale.c \ - messages.c nsurl.c talloc.c url.c utf8.c utils.c useragent.c \ - filepath.c log.c +S_UTILS := base64.c corestrings.c filename.c filepath.c hashtable.c \ + libdom.c locale.c log.c messages.c nsurl.c talloc.c url.c \ + utf8.c utils.c useragent.c S_HTTP := challenge.c generics.c primitives.c parameter.c \ content-disposition.c content-type.c www-authenticate.c diff --git a/render/html.c b/render/html.c index 02209b9e9..09256a6fa 100644 --- a/render/html.c +++ b/render/html.c @@ -45,6 +45,7 @@ #include "render/search.h" #include "utils/corestrings.h" #include "utils/http.h" +#include "utils/libdom.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/schedule.h" @@ -1626,111 +1627,6 @@ no_memory: } -/* depth-first walk the dom calling callback for each element - * - * @param root the dom node to use as the root of the tree walk - * @return true if all nodes were examined, false if the callback terminated - * the walk early. - */ -static bool -html_treewalk_dom(dom_node *root, - bool (*callback)(dom_node *node, dom_string *name, void *ctx), - void *ctx) -{ - dom_node *node; - bool result = true;; - - node = dom_node_ref(root); /* tree root */ - - while (node != NULL) { - dom_node *next = NULL; - dom_node_type type; - dom_string *name; - dom_exception exc; - - exc = dom_node_get_first_child(node, &next); - if (exc != DOM_NO_ERR) { - dom_node_unref(node); - break; - } - - if (next != NULL) { /* 1. children */ - dom_node_unref(node); - node = next; - } else { - exc = dom_node_get_next_sibling(node, &next); - if (exc != DOM_NO_ERR) { - dom_node_unref(node); - break; - } - - if (next != NULL) { /* 2. siblings */ - dom_node_unref(node); - node = next; - } else { /* 3. ancestor siblings */ - while (node != NULL) { - exc = dom_node_get_next_sibling(node, - &next); - if (exc != DOM_NO_ERR) { - dom_node_unref(node); - node = NULL; - break; - } - - if (next != NULL) { - dom_node_unref(next); - break; - } - - exc = dom_node_get_parent_node(node, - &next); - if (exc != DOM_NO_ERR) { - dom_node_unref(node); - node = NULL; - break; - } - - dom_node_unref(node); - node = next; - } - - if (node == NULL) - break; - - exc = dom_node_get_next_sibling(node, &next); - if (exc != DOM_NO_ERR) { - dom_node_unref(node); - break; - } - - dom_node_unref(node); - node = next; - } - } - - assert(node != NULL); - - exc = dom_node_get_node_type(node, &type); - if ((exc != DOM_NO_ERR) || (type != DOM_ELEMENT_NODE)) - continue; - - exc = dom_node_get_node_name(node, &name); - if (exc != DOM_NO_ERR) - continue; - - result = callback(node, name, ctx); - - dom_string_unref(name); - - if (result == false) { - break; /* callback caused early termination */ - } - - } - return result; -} - - struct find_stylesheet_ctx { unsigned int count; @@ -1957,7 +1853,7 @@ static bool html_find_stylesheets(html_content *c, dom_node *html) LOG(("%d fetches active", c->base.active)); - result = html_treewalk_dom(html, html_process_stylesheet, &ctx); + result = libdom_treewalk(html, html_process_stylesheet, &ctx); assert(c->stylesheet_count == ctx.count); diff --git a/utils/corestrings.c b/utils/corestrings.c index f2420116c..866dfd945 100644 --- a/utils/corestrings.c +++ b/utils/corestrings.c @@ -65,6 +65,7 @@ lwc_string *corestring_lwc_img; lwc_string *corestring_lwc_input; lwc_string *corestring_lwc_justify; lwc_string *corestring_lwc_left; +lwc_string *corestring_lwc_li; lwc_string *corestring_lwc_link; lwc_string *corestring_lwc_meta; lwc_string *corestring_lwc_middle; @@ -103,6 +104,7 @@ lwc_string *corestring_lwc_thead; lwc_string *corestring_lwc_title; lwc_string *corestring_lwc_top; lwc_string *corestring_lwc_tr; +lwc_string *corestring_lwc_ul; lwc_string *corestring_lwc_url; lwc_string *corestring_lwc_yes; lwc_string *corestring_lwc__blank; @@ -206,6 +208,7 @@ void corestrings_fini(void) CSS_LWC_STRING_UNREF(input); CSS_LWC_STRING_UNREF(justify); CSS_LWC_STRING_UNREF(left); + CSS_LWC_STRING_UNREF(li); CSS_LWC_STRING_UNREF(link); CSS_LWC_STRING_UNREF(meta); CSS_LWC_STRING_UNREF(middle); @@ -244,6 +247,7 @@ void corestrings_fini(void) CSS_LWC_STRING_UNREF(title); CSS_LWC_STRING_UNREF(top); CSS_LWC_STRING_UNREF(tr); + CSS_LWC_STRING_UNREF(ul); CSS_LWC_STRING_UNREF(url); CSS_LWC_STRING_UNREF(yes); CSS_LWC_STRING_UNREF(_blank); @@ -367,6 +371,7 @@ nserror corestrings_init(void) CSS_LWC_STRING_INTERN(input); CSS_LWC_STRING_INTERN(justify); CSS_LWC_STRING_INTERN(left); + CSS_LWC_STRING_INTERN(li); CSS_LWC_STRING_INTERN(link); CSS_LWC_STRING_INTERN(meta); CSS_LWC_STRING_INTERN(middle); @@ -403,6 +408,7 @@ nserror corestrings_init(void) CSS_LWC_STRING_INTERN(title); CSS_LWC_STRING_INTERN(top); CSS_LWC_STRING_INTERN(tr); + CSS_LWC_STRING_INTERN(ul); CSS_LWC_STRING_INTERN(url); CSS_LWC_STRING_INTERN(yes); CSS_LWC_STRING_INTERN(_blank); diff --git a/utils/corestrings.h b/utils/corestrings.h index 5ecc3aa63..27da3fb45 100644 --- a/utils/corestrings.h +++ b/utils/corestrings.h @@ -69,6 +69,7 @@ extern lwc_string *corestring_lwc_img; extern lwc_string *corestring_lwc_input; extern lwc_string *corestring_lwc_justify; extern lwc_string *corestring_lwc_left; +extern lwc_string *corestring_lwc_li; extern lwc_string *corestring_lwc_link; extern lwc_string *corestring_lwc_meta; extern lwc_string *corestring_lwc_middle; @@ -107,6 +108,7 @@ extern lwc_string *corestring_lwc_thead; extern lwc_string *corestring_lwc_title; extern lwc_string *corestring_lwc_top; extern lwc_string *corestring_lwc_tr; +extern lwc_string *corestring_lwc_ul; extern lwc_string *corestring_lwc_url; extern lwc_string *corestring_lwc_yes; extern lwc_string *corestring_lwc__blank; diff --git a/utils/libdom.c b/utils/libdom.c new file mode 100644 index 000000000..7caadc3d5 --- /dev/null +++ b/utils/libdom.c @@ -0,0 +1,164 @@ +/* + * Copyright 2012 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file + * libdom utilities (implementation). + */ + +#include + +#include "utils/libdom.h" + + +/* exported interface documented in libdom.h */ +bool libdom_treewalk(dom_node *root, + bool (*callback)(dom_node *node, dom_string *name, void *ctx), + void *ctx) +{ + dom_node *node; + bool result = true;; + + node = dom_node_ref(root); /* tree root */ + + while (node != NULL) { + dom_node *next = NULL; + dom_node_type type; + dom_string *name; + dom_exception exc; + + exc = dom_node_get_first_child(node, &next); + if (exc != DOM_NO_ERR) { + dom_node_unref(node); + break; + } + + if (next != NULL) { /* 1. children */ + dom_node_unref(node); + node = next; + } else { + exc = dom_node_get_next_sibling(node, &next); + if (exc != DOM_NO_ERR) { + dom_node_unref(node); + break; + } + + if (next != NULL) { /* 2. siblings */ + dom_node_unref(node); + node = next; + } else { /* 3. ancestor siblings */ + while (node != NULL) { + exc = dom_node_get_next_sibling(node, + &next); + if (exc != DOM_NO_ERR) { + dom_node_unref(node); + node = NULL; + break; + } + + if (next != NULL) { + dom_node_unref(next); + break; + } + + exc = dom_node_get_parent_node(node, + &next); + if (exc != DOM_NO_ERR) { + dom_node_unref(node); + node = NULL; + break; + } + + dom_node_unref(node); + node = next; + } + + if (node == NULL) + break; + + exc = dom_node_get_next_sibling(node, &next); + if (exc != DOM_NO_ERR) { + dom_node_unref(node); + break; + } + + dom_node_unref(node); + node = next; + } + } + + assert(node != NULL); + + exc = dom_node_get_node_type(node, &type); + if ((exc != DOM_NO_ERR) || (type != DOM_ELEMENT_NODE)) + continue; + + exc = dom_node_get_node_name(node, &name); + if (exc != DOM_NO_ERR) + continue; + + result = callback(node, name, ctx); + + dom_string_unref(name); + + if (result == false) { + break; /* callback caused early termination */ + } + + } + return result; +} + + +/* libdom_treewalk context for libdom_find_element */ +struct find_element_ctx { + lwc_string *search; + dom_node *found; +}; +/* libdom_treewalk callback for libdom_find_element */ +static bool libdom_find_element_callback(dom_node *node, dom_string *name, + void *ctx) +{ + struct find_element_ctx *data = ctx; + + if (dom_string_caseless_lwc_isequal(name, data->search)) { + /* Found element */ + data->found = node; + return false; /* Discontinue search */ + } + + return true; /* Continue search */ +} + + +/* exported interface documented in libdom.h */ +dom_node *libdom_find_element(dom_node *node, lwc_string *element_name) +{ + struct find_element_ctx data; + + assert(element_name != NULL); + + if (node == NULL) + return NULL; + + data.search = element_name; + data.found = NULL; + + libdom_treewalk(node, libdom_find_element_callback, &data); + + return data.found; +} \ No newline at end of file diff --git a/utils/libdom.h b/utils/libdom.h new file mode 100644 index 000000000..e5a7c20c1 --- /dev/null +++ b/utils/libdom.h @@ -0,0 +1,51 @@ +/* + * Copyright 2011 John-Mark Bell + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +/** \file + * libdom utilities (implementation). + */ + +#ifndef NETSURF_UTILS_LIBDOM_H_ +#define NETSURF_UTILS_LIBDOM_H_ + +#include + +#include + +/* depth-first walk the dom calling callback for each element + * + * \param root the dom node to use as the root of the tree walk + * \return true if all nodes were examined, false if the callback terminated + * the walk early. + */ +bool libdom_treewalk(dom_node *root, + bool (*callback)(dom_node *node, dom_string *name, void *ctx), + void *ctx); + +/** + * Search the descendants of a node for an element. + * + * \param node dom_node to search children of, or NULL + * \param element_name name of element to find + * \return first child of node which is an element and matches name, or + * NULL if not found or parameter node is NULL + */ +dom_node *libdom_find_element(dom_node *node, lwc_string *element_name); + +#endif -- cgit v1.2.3