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. --- utils/corestrings.c | 6 ++ utils/corestrings.h | 2 + utils/libdom.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++ utils/libdom.h | 51 ++++++++++++++++ 4 files changed, 223 insertions(+) create mode 100644 utils/libdom.c create mode 100644 utils/libdom.h (limited to 'utils') 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